From 0e9b11fd7f6e54c3f8cdde4313b8971d8535cafb Mon Sep 17 00:00:00 2001 From: mssonicbld <79238446+mssonicbld@users.noreply.github.com> Date: Thu, 24 Oct 2024 19:51:50 +0800 Subject: [PATCH 01/23] [submodule] Update submodule sonic-platform-common to the latest HEAD automatically (#20599) #### Why I did it src/sonic-platform-common ``` * 912ceb3 - (HEAD -> master, origin/master, origin/HEAD) Refactor parse_virtium_info to support new ssd model (#495) (21 hours ago) [Yuanzhe] ``` #### How I did it #### How to verify it #### Description for the changelog --- 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 f07a6aa8ef19..912ceb34c8a3 160000 --- a/src/sonic-platform-common +++ b/src/sonic-platform-common @@ -1 +1 @@ -Subproject commit f07a6aa8ef19f1ea2043e6443f476ff8fdfc0fed +Subproject commit 912ceb34c8a352b235ad77ea07778c4779a5bd4a From c83ff1b7f53a8c7608cbf6df01849cc8c480c11c Mon Sep 17 00:00:00 2001 From: mssonicbld <79238446+mssonicbld@users.noreply.github.com> Date: Thu, 24 Oct 2024 19:52:02 +0800 Subject: [PATCH 02/23] [submodule] Update submodule sonic-swss to the latest HEAD automatically (#20583) #### Why I did it src/sonic-swss ``` * bd945f67 - (HEAD -> master, origin/master, origin/HEAD) Add mgmt VRF support. (#3299) (2 hours ago) [Hua Liu] * e71eb2dc - Fix p4orch tests after SAI update (#3337) (29 hours ago) [Saikrishna Arcot] ``` #### How I did it #### How to verify it #### Description for the changelog --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index 90fceadf7565..bd945f673e0b 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 90fceadf75654501e5fb2d9726344c6e0d0d0a86 +Subproject commit bd945f673e0b2871debae5a951afd7de854d19f3 From b3e379c2a6f9551d556a50ba1456d31958a8bb4c Mon Sep 17 00:00:00 2001 From: Ze Gan Date: Fri, 25 Oct 2024 00:54:04 +0800 Subject: [PATCH 03/23] [Arista]: Update XON to 0 for TH5 (#19849) [Arista] Update XON to 0 for TH5 Signed-off-by: Ze Gan --- .../BALANCED/pg_profile_lookup.ini | 25 +++---------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-256x200G/BALANCED/pg_profile_lookup.ini b/device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-256x200G/BALANCED/pg_profile_lookup.ini index bc4b6528ea10..ecf0712e392f 100644 --- a/device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-256x200G/BALANCED/pg_profile_lookup.ini +++ b/device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-256x200G/BALANCED/pg_profile_lookup.ini @@ -1,23 +1,6 @@ # PG lossless profiles. # speed cable size xon xoff threshold xon_offset - 10000 5m 1248 2288 35776 0 2288 - 25000 5m 1248 2288 53248 0 2288 - 40000 5m 1248 2288 66560 0 2288 - 50000 5m 1248 2288 90272 0 2288 - 100000 5m 18796 3556 300990 0 3556 - 200000 5m 18796 3556 300990 0 3556 - 400000 5m 18796 3556 300990 0 3556 - 10000 40m 1248 2288 37024 0 2288 - 25000 40m 1248 2288 53248 0 2288 - 40000 40m 1248 2288 71552 0 2288 - 50000 40m 1248 2288 96096 0 2288 - 100000 40m 18796 3556 300990 0 3556 - 200000 40m 18796 3556 300990 0 3556 - 400000 40m 18796 3556 300990 0 3556 - 10000 300m 1248 2288 46176 0 2288 - 25000 300m 1248 2288 79040 0 2288 - 40000 300m 1248 2288 108160 0 2288 - 50000 300m 1248 2288 141856 0 2288 - 100000 300m 18796 3556 300990 0 3556 - 200000 300m 18796 3556 300990 0 3556 - 400000 300m 18796 3556 300990 0 3556 + 100000 5m 18796 0 300990 0 3556 + 200000 5m 18796 0 300990 0 3556 + 100000 40m 18796 0 300990 0 3556 + 200000 40m 18796 0 300990 0 3556 From 06c469e6cc0a13beae45f2bdbea8c0d0ee82946c Mon Sep 17 00:00:00 2001 From: Feng-msft Date: Fri, 25 Oct 2024 07:08:13 +0800 Subject: [PATCH 04/23] Add new redis database instance for BMP_STATE_DB. (#19016) #### Why I did it Add new redis database instance for BMP_STATE_DB. since bmp data set will be a bit large which we don't want block existing state_db operation. #### How I did it Changed database config and will use it into other bmp relevant PR. --- dockers/docker-database/database_config.json.j2 | 15 +++++++++++++-- dockers/docker-database/docker-database-init.sh | 6 +++++- files/build_templates/docker_image_ctl.j2 | 3 +++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/dockers/docker-database/database_config.json.j2 b/dockers/docker-database/database_config.json.j2 index 65db6cb72641..f37b64ee9665 100644 --- a/dockers/docker-database/database_config.json.j2 +++ b/dockers/docker-database/database_config.json.j2 @@ -23,7 +23,13 @@ "unix_socket_path": "", "persistence_for_warm_boot" : "yes" } -{% endif %} +{% endif %}, + "redis_bmp":{ + "hostname" : "{{HOST_IP}}", + "port" : {{BMP_DB_PORT}}, + "unix_socket_path" : "/var/run/redis{{DEV}}/redis_bmp.sock", + "persistence_for_warm_boot" : "yes" + } }, "DATABASES" : { "APPL_DB" : { @@ -129,7 +135,12 @@ "separator": ":", "instance" : {% if include_remote_db %} "remote_redis" {% else %} "redis" {% endif %} } -{% endif %} +{% endif %}, + "BMP_STATE_DB" : { + "id" : 20, + "separator": "|", + "instance" : "redis_bmp" + } }, "VERSION" : "1.0" } diff --git a/dockers/docker-database/docker-database-init.sh b/dockers/docker-database/docker-database-init.sh index 467f33c212d1..c50add1a7698 100755 --- a/dockers/docker-database/docker-database-init.sh +++ b/dockers/docker-database/docker-database-init.sh @@ -41,6 +41,8 @@ then fi fi +export BMP_DB_PORT=6400 + REDIS_DIR=/var/run/redis$NAMESPACE_ID mkdir -p $REDIS_DIR/sonic-db mkdir -p /etc/supervisor/conf.d/ @@ -48,7 +50,7 @@ mkdir -p /etc/supervisor/conf.d/ if [ -f /etc/sonic/database_config$NAMESPACE_ID.json ]; then cp /etc/sonic/database_config$NAMESPACE_ID.json $REDIS_DIR/sonic-db/database_config.json else - HOST_IP=$host_ip REDIS_PORT=$redis_port DATABASE_TYPE=$DATABASE_TYPE j2 /usr/share/sonic/templates/database_config.json.j2 > $REDIS_DIR/sonic-db/database_config.json + HOST_IP=$host_ip REDIS_PORT=$redis_port DATABASE_TYPE=$DATABASE_TYPE BMP_DB_PORT=$BMP_DB_PORT j2 /usr/share/sonic/templates/database_config.json.j2 > $REDIS_DIR/sonic-db/database_config.json fi # on VoQ system, we only publish redis_chassis instance and CHASSIS_APP_DB when @@ -130,5 +132,7 @@ rm -rf /etc/localtime ln -sf /usr/share/zoneinfo/$TZ /etc/localtime chown -R redis:redis $REDIS_DIR +REDIS_BMP_DIR="/var/lib/redis_bmp" +chown -R redis:redis $REDIS_BMP_DIR exec /usr/local/bin/supervisord diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 732681818824..f1757f69ba42 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -94,6 +94,7 @@ function preStartAction() # Create an emtpy file and overwrite any RDB if already there echo -n > /tmp/dump.rdb docker cp /tmp/dump.rdb database$DEV:/var/lib/redis/ + docker cp /tmp/dump.rdb database$DEV:/var/lib/redis_bmp/ fi fi {%- elif docker_container_name == "pde" %} @@ -296,7 +297,9 @@ function postStartAction() fi REDIS_SOCK="/var/run/redis-chassis/redis_chassis.sock" fi + REDIS_BMP_SOCK="/var/run/redis/redis_bmp.sock" chgrp -f redis $REDIS_SOCK && chmod -f 0760 $REDIS_SOCK + chgrp -f redis $REDIS_BMP_SOCK && chmod -f 0760 $REDIS_BMP_SOCK {%- elif docker_container_name == "swss" %} # Wait until swss container state is Running until [[ ($(docker inspect -f {{"'{{.State.Running}}'"}} swss$DEV) == "true") ]]; do From 4e9c08a605b176e22b1f20f74deecb7aada2c8c2 Mon Sep 17 00:00:00 2001 From: jingwenxie Date: Fri, 25 Oct 2024 09:19:03 +0800 Subject: [PATCH 05/23] [syslog] Add default syslog ip to interfaces.j2 (#20340) #### Why I did it This is to make interfaces iprule to align with syslog server ip if exists and goes default if not provided #### How I did it Set ip rule when interface up and down. Fix test gap on interfaces.j2 for syslog parsing #### How to verify it use j2 tempalte unit test --- files/image_config/interfaces/interfaces.j2 | 26 + .../tests/sample_output/py2/interfaces | 2 + .../tests/sample_output/py2/interfaces_syslog | 55 + .../tests/sample_output/py2/mvrf_interfaces | 2 + .../sample_output/py2/two_mgmt_interfaces | 4 + .../tests/sample_output/py3/interfaces | 2 + .../tests/sample_output/py3/interfaces_syslog | 55 + .../tests/sample_output/py3/mvrf_interfaces | 2 + .../sample_output/py3/two_mgmt_interfaces | 4 + .../tests/t0-sample-graph-syslog.xml | 943 ++++++++++++++++++ src/sonic-config-engine/tests/test_j2files.py | 6 + 11 files changed, 1101 insertions(+) create mode 100644 src/sonic-config-engine/tests/sample_output/py2/interfaces_syslog create mode 100644 src/sonic-config-engine/tests/sample_output/py3/interfaces_syslog create mode 100644 src/sonic-config-engine/tests/t0-sample-graph-syslog.xml diff --git a/files/image_config/interfaces/interfaces.j2 b/files/image_config/interfaces/interfaces.j2 index a75b617f1ec5..cfdd322c4543 100644 --- a/files/image_config/interfaces/interfaces.j2 +++ b/files/image_config/interfaces/interfaces.j2 @@ -88,6 +88,19 @@ iface {{ name }} {{ 'inet' if prefix | ipv4 else 'inet6' }} static {% for route in MGMT_INTERFACE[(name, prefix)]['forced_mgmt_routes'] %} up ip {{ '-4' if prefix | ipv4 else '-6' }} rule add pref {{ force_mgmt_route_priority }} to {{ route }} table {{ vrf_table }} {% endfor %} +{% if SYSLOG_SERVER is defined and SYSLOG_SERVER %} +{% for server in SYSLOG_SERVER %} +{% if server | ipv4 and prefix | ipv4 %} + up ip rule add pref {{ force_mgmt_route_priority }} to {{ server }}/32 table {{ vrf_table }} +{% elif server | ipv6 and prefix | ipv6 %} + up ip -6 rule add pref {{ force_mgmt_route_priority }} to {{ server }}/128 table {{ vrf_table }} +{% endif %} +{% endfor %} +{% else %} +{% if prefix | ipv4 %} + up ip rule add pref {{ force_mgmt_route_priority }} to 10.20.6.16/32 table {{ vrf_table }} +{% endif %} +{% endif %} {% if prefix | ipv6 and vrf_table == 'default'%} # IPV6 default table not add to lookup by default, management server need this to access IPV6 address when BGP shutdown up ip -6 rule add pref {{ force_mgmt_route_priority + 3 }} lookup {{ vrf_table }} @@ -99,6 +112,19 @@ iface {{ name }} {{ 'inet' if prefix | ipv4 else 'inet6' }} static {% for route in MGMT_INTERFACE[(name, prefix)]['forced_mgmt_routes'] %} pre-down ip {{ '-4' if route | ipv4 else '-6' }} rule delete pref {{ force_mgmt_route_priority }} to {{ route }} table {{ vrf_table }} {% endfor %} +{% if SYSLOG_SERVER is defined and SYSLOG_SERVER %} +{% for server in SYSLOG_SERVER %} +{% if server | ipv4 and prefix | ipv4 %} + down ip rule delete pref {{ force_mgmt_route_priority }} to {{ server }}/32 table {{ vrf_table }} +{% elif server | ipv6 and prefix | ipv6 %} + down ip -6 rule delete pref {{ force_mgmt_route_priority }} to {{ server }}/128 table {{ vrf_table }} +{% endif %} +{% endfor %} +{% else %} +{% if prefix | ipv4 %} + down ip rule delete pref {{ force_mgmt_route_priority }} to 10.20.6.16/32 table {{ vrf_table }} +{% endif %} +{% endif %} {% if prefix | ipv6 and vrf_table == 'default'%} pre-down ip -6 rule delete pref {{ force_mgmt_route_priority + 3 }} lookup {{ vrf_table }} {% endif %} diff --git a/src/sonic-config-engine/tests/sample_output/py2/interfaces b/src/sonic-config-engine/tests/sample_output/py2/interfaces index 15d5f8426247..f4a67ce37cd9 100644 --- a/src/sonic-config-engine/tests/sample_output/py2/interfaces +++ b/src/sonic-config-engine/tests/sample_output/py2/interfaces @@ -24,10 +24,12 @@ iface eth0 inet static up ip -4 route add default via 10.0.0.1 dev eth0 table default metric 201 up ip -4 route add 10.0.0.0/24 dev eth0 table default up ip -4 rule add pref 32765 from 10.0.0.100/32 table default + up ip rule add pref 32764 to 10.20.6.16/32 table default # management port down rules pre-down ip -4 route delete default via 10.0.0.1 dev eth0 table default pre-down ip -4 route delete 10.0.0.0/24 dev eth0 table default pre-down ip -4 rule delete pref 32765 from 10.0.0.100/32 table default + down ip rule delete pref 32764 to 10.20.6.16/32 table default iface eth0 inet6 static address 2603:10e2:0:2902::8 netmask 64 diff --git a/src/sonic-config-engine/tests/sample_output/py2/interfaces_syslog b/src/sonic-config-engine/tests/sample_output/py2/interfaces_syslog new file mode 100644 index 000000000000..8b58153b5b77 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py2/interfaces_syslog @@ -0,0 +1,55 @@ +# +# =============== Managed by SONiC Config Engine DO NOT EDIT! =============== +# generated from /usr/share/sonic/templates/interfaces.j2 using sonic-cfggen +# file: /etc/network/interfaces +# +# The loopback network interface +auto lo +iface lo inet loopback + address 127.0.0.1 + netmask 255.255.0.0 + scope host + post-up ip addr del 127.0.0.1/8 dev lo + pre-down ip addr add 127.0.0.1/8 dev lo + +# The management network interface +auto eth0 +iface eth0 inet static + address 10.0.0.100 + netmask 255.255.255.0 + network 10.0.0.0 + broadcast 10.0.0.255 + ########## management network policy routing rules + # management port up rules + up ip -4 route add default via 10.0.0.1 dev eth0 table default metric 201 + up ip -4 route add 10.0.0.0/24 dev eth0 table default + up ip -4 rule add pref 32765 from 10.0.0.100/32 table default + up ip rule add pref 32764 to 10.3.145.8/32 table default + up ip rule add pref 32764 to 100.127.20.21/32 table default + # management port down rules + pre-down ip -4 route delete default via 10.0.0.1 dev eth0 table default + pre-down ip -4 route delete 10.0.0.0/24 dev eth0 table default + pre-down ip -4 rule delete pref 32765 from 10.0.0.100/32 table default + down ip rule delete pref 32764 to 10.3.145.8/32 table default + down ip rule delete pref 32764 to 100.127.20.21/32 table default +iface eth0 inet6 static + address 2603:10e2:0:2902::8 + netmask 64 + network 2603:10e2:0:2902:: + broadcast 2603:10e2:0:2902:ffff:ffff:ffff:ffff + ########## management network policy routing rules + # management port up rules + up ip -6 route add default via 2603:10e2:0:2902::1 dev eth0 table default metric 201 + up ip -6 route add 2603:10e2:0:2902::/64 dev eth0 table default + up ip -6 rule add pref 32765 from 2603:10e2:0:2902::8/128 table default + # IPV6 default table not add to lookup by default, management server need this to access IPV6 address when BGP shutdown + up ip -6 rule add pref 32767 lookup default + # management port down rules + pre-down ip -6 route delete default via 2603:10e2:0:2902::1 dev eth0 table default + pre-down ip -6 route delete 2603:10e2:0:2902::/64 dev eth0 table default + pre-down ip -6 rule delete pref 32765 from 2603:10e2:0:2902::8/128 table default + pre-down ip -6 rule delete pref 32767 lookup default +# +source /etc/network/interfaces.d/* +# + diff --git a/src/sonic-config-engine/tests/sample_output/py2/mvrf_interfaces b/src/sonic-config-engine/tests/sample_output/py2/mvrf_interfaces index 518fbb0389a1..a72d754b3ca8 100644 --- a/src/sonic-config-engine/tests/sample_output/py2/mvrf_interfaces +++ b/src/sonic-config-engine/tests/sample_output/py2/mvrf_interfaces @@ -36,12 +36,14 @@ iface eth0 inet static up ip -4 rule add pref 32765 from 10.0.0.100/32 table 5000 up ip -4 rule add pref 32764 to 11.11.11.11 table 5000 up ip -4 rule add pref 32764 to 22.22.22.0/23 table 5000 + up ip rule add pref 32764 to 10.20.6.16/32 table 5000 # management port down rules pre-down ip -4 route delete default via 10.0.0.1 dev eth0 table 5000 pre-down ip -4 route delete 10.0.0.0/24 dev eth0 table 5000 pre-down ip -4 rule delete pref 32765 from 10.0.0.100/32 table 5000 pre-down ip -4 rule delete pref 32764 to 11.11.11.11 table 5000 pre-down ip -4 rule delete pref 32764 to 22.22.22.0/23 table 5000 + down ip rule delete pref 32764 to 10.20.6.16/32 table 5000 iface eth0 inet6 static address 2603:10e2:0:2902::8 netmask 64 diff --git a/src/sonic-config-engine/tests/sample_output/py2/two_mgmt_interfaces b/src/sonic-config-engine/tests/sample_output/py2/two_mgmt_interfaces index 1b46be4bc380..9e44fe93e0df 100644 --- a/src/sonic-config-engine/tests/sample_output/py2/two_mgmt_interfaces +++ b/src/sonic-config-engine/tests/sample_output/py2/two_mgmt_interfaces @@ -25,10 +25,12 @@ iface eth1 inet static up ip -4 route add default via 10.0.10.1 dev eth1 table default metric 201 up ip -4 route add 10.0.10.0/24 dev eth1 table default up ip -4 rule add pref 32765 from 10.0.10.100/32 table default + up ip rule add pref 32764 to 10.20.6.16/32 table default # management port down rules pre-down ip -4 route delete default via 10.0.10.1 dev eth1 table default pre-down ip -4 route delete 10.0.10.0/24 dev eth1 table default pre-down ip -4 rule delete pref 32765 from 10.0.10.100/32 table default + down ip rule delete pref 32764 to 10.20.6.16/32 table default iface eth0 inet static address 10.0.0.100 netmask 255.255.255.0 @@ -39,10 +41,12 @@ iface eth0 inet static up ip -4 route add default via 10.0.0.1 dev eth0 table default metric 201 up ip -4 route add 10.0.0.0/24 dev eth0 table default up ip -4 rule add pref 32765 from 10.0.0.100/32 table default + up ip rule add pref 32764 to 10.20.6.16/32 table default # management port down rules pre-down ip -4 route delete default via 10.0.0.1 dev eth0 table default pre-down ip -4 route delete 10.0.0.0/24 dev eth0 table default pre-down ip -4 rule delete pref 32765 from 10.0.0.100/32 table default + down ip rule delete pref 32764 to 10.20.6.16/32 table default iface eth1 inet6 static address 2603:10e2:0:abcd::8 netmask 64 diff --git a/src/sonic-config-engine/tests/sample_output/py3/interfaces b/src/sonic-config-engine/tests/sample_output/py3/interfaces index 15d5f8426247..f4a67ce37cd9 100644 --- a/src/sonic-config-engine/tests/sample_output/py3/interfaces +++ b/src/sonic-config-engine/tests/sample_output/py3/interfaces @@ -24,10 +24,12 @@ iface eth0 inet static up ip -4 route add default via 10.0.0.1 dev eth0 table default metric 201 up ip -4 route add 10.0.0.0/24 dev eth0 table default up ip -4 rule add pref 32765 from 10.0.0.100/32 table default + up ip rule add pref 32764 to 10.20.6.16/32 table default # management port down rules pre-down ip -4 route delete default via 10.0.0.1 dev eth0 table default pre-down ip -4 route delete 10.0.0.0/24 dev eth0 table default pre-down ip -4 rule delete pref 32765 from 10.0.0.100/32 table default + down ip rule delete pref 32764 to 10.20.6.16/32 table default iface eth0 inet6 static address 2603:10e2:0:2902::8 netmask 64 diff --git a/src/sonic-config-engine/tests/sample_output/py3/interfaces_syslog b/src/sonic-config-engine/tests/sample_output/py3/interfaces_syslog new file mode 100644 index 000000000000..8b58153b5b77 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/py3/interfaces_syslog @@ -0,0 +1,55 @@ +# +# =============== Managed by SONiC Config Engine DO NOT EDIT! =============== +# generated from /usr/share/sonic/templates/interfaces.j2 using sonic-cfggen +# file: /etc/network/interfaces +# +# The loopback network interface +auto lo +iface lo inet loopback + address 127.0.0.1 + netmask 255.255.0.0 + scope host + post-up ip addr del 127.0.0.1/8 dev lo + pre-down ip addr add 127.0.0.1/8 dev lo + +# The management network interface +auto eth0 +iface eth0 inet static + address 10.0.0.100 + netmask 255.255.255.0 + network 10.0.0.0 + broadcast 10.0.0.255 + ########## management network policy routing rules + # management port up rules + up ip -4 route add default via 10.0.0.1 dev eth0 table default metric 201 + up ip -4 route add 10.0.0.0/24 dev eth0 table default + up ip -4 rule add pref 32765 from 10.0.0.100/32 table default + up ip rule add pref 32764 to 10.3.145.8/32 table default + up ip rule add pref 32764 to 100.127.20.21/32 table default + # management port down rules + pre-down ip -4 route delete default via 10.0.0.1 dev eth0 table default + pre-down ip -4 route delete 10.0.0.0/24 dev eth0 table default + pre-down ip -4 rule delete pref 32765 from 10.0.0.100/32 table default + down ip rule delete pref 32764 to 10.3.145.8/32 table default + down ip rule delete pref 32764 to 100.127.20.21/32 table default +iface eth0 inet6 static + address 2603:10e2:0:2902::8 + netmask 64 + network 2603:10e2:0:2902:: + broadcast 2603:10e2:0:2902:ffff:ffff:ffff:ffff + ########## management network policy routing rules + # management port up rules + up ip -6 route add default via 2603:10e2:0:2902::1 dev eth0 table default metric 201 + up ip -6 route add 2603:10e2:0:2902::/64 dev eth0 table default + up ip -6 rule add pref 32765 from 2603:10e2:0:2902::8/128 table default + # IPV6 default table not add to lookup by default, management server need this to access IPV6 address when BGP shutdown + up ip -6 rule add pref 32767 lookup default + # management port down rules + pre-down ip -6 route delete default via 2603:10e2:0:2902::1 dev eth0 table default + pre-down ip -6 route delete 2603:10e2:0:2902::/64 dev eth0 table default + pre-down ip -6 rule delete pref 32765 from 2603:10e2:0:2902::8/128 table default + pre-down ip -6 rule delete pref 32767 lookup default +# +source /etc/network/interfaces.d/* +# + diff --git a/src/sonic-config-engine/tests/sample_output/py3/mvrf_interfaces b/src/sonic-config-engine/tests/sample_output/py3/mvrf_interfaces index 518fbb0389a1..a72d754b3ca8 100644 --- a/src/sonic-config-engine/tests/sample_output/py3/mvrf_interfaces +++ b/src/sonic-config-engine/tests/sample_output/py3/mvrf_interfaces @@ -36,12 +36,14 @@ iface eth0 inet static up ip -4 rule add pref 32765 from 10.0.0.100/32 table 5000 up ip -4 rule add pref 32764 to 11.11.11.11 table 5000 up ip -4 rule add pref 32764 to 22.22.22.0/23 table 5000 + up ip rule add pref 32764 to 10.20.6.16/32 table 5000 # management port down rules pre-down ip -4 route delete default via 10.0.0.1 dev eth0 table 5000 pre-down ip -4 route delete 10.0.0.0/24 dev eth0 table 5000 pre-down ip -4 rule delete pref 32765 from 10.0.0.100/32 table 5000 pre-down ip -4 rule delete pref 32764 to 11.11.11.11 table 5000 pre-down ip -4 rule delete pref 32764 to 22.22.22.0/23 table 5000 + down ip rule delete pref 32764 to 10.20.6.16/32 table 5000 iface eth0 inet6 static address 2603:10e2:0:2902::8 netmask 64 diff --git a/src/sonic-config-engine/tests/sample_output/py3/two_mgmt_interfaces b/src/sonic-config-engine/tests/sample_output/py3/two_mgmt_interfaces index 4be6dcd5d801..df2ac9ad30ad 100644 --- a/src/sonic-config-engine/tests/sample_output/py3/two_mgmt_interfaces +++ b/src/sonic-config-engine/tests/sample_output/py3/two_mgmt_interfaces @@ -25,10 +25,12 @@ iface eth0 inet static up ip -4 route add default via 10.0.0.1 dev eth0 table default metric 201 up ip -4 route add 10.0.0.0/24 dev eth0 table default up ip -4 rule add pref 32765 from 10.0.0.100/32 table default + up ip rule add pref 32764 to 10.20.6.16/32 table default # management port down rules pre-down ip -4 route delete default via 10.0.0.1 dev eth0 table default pre-down ip -4 route delete 10.0.0.0/24 dev eth0 table default pre-down ip -4 rule delete pref 32765 from 10.0.0.100/32 table default + down ip rule delete pref 32764 to 10.20.6.16/32 table default iface eth0 inet6 static address 2603:10e2:0:2902::8 netmask 64 @@ -56,10 +58,12 @@ iface eth1 inet static up ip -4 route add default via 10.0.10.1 dev eth1 table default metric 201 up ip -4 route add 10.0.10.0/24 dev eth1 table default up ip -4 rule add pref 32765 from 10.0.10.100/32 table default + up ip rule add pref 32764 to 10.20.6.16/32 table default # management port down rules pre-down ip -4 route delete default via 10.0.10.1 dev eth1 table default pre-down ip -4 route delete 10.0.10.0/24 dev eth1 table default pre-down ip -4 rule delete pref 32765 from 10.0.10.100/32 table default + down ip rule delete pref 32764 to 10.20.6.16/32 table default iface eth1 inet6 static address 2603:10e2:0:abcd::8 netmask 64 diff --git a/src/sonic-config-engine/tests/t0-sample-graph-syslog.xml b/src/sonic-config-engine/tests/t0-sample-graph-syslog.xml new file mode 100644 index 000000000000..4573e43a42f9 --- /dev/null +++ b/src/sonic-config-engine/tests/t0-sample-graph-syslog.xml @@ -0,0 +1,943 @@ + + + + + + switch-t0 + 10.1.0.32 + BGPMonitor + 10.20.30.40 + 30 + 10 + 3 + + + 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 + + + false + switch-t0 + 10.0.0.60 + ARISTA03T1 + 10.0.0.61 + 1 + 180 + 60 + + + switch-t0 + FC00::79 + ARISTA03T1 + FC00::7A + 1 + 180 + 60 + + + false + switch-t0 + 10.0.0.62 + ARISTA04T1 + 10.0.0.63 + 1 + 180 + 60 + + + switch-t0 + FC00::7D + ARISTA04T1 + FC00::7E + 1 + 180 + 60 + + + + + 1 + + BGPMonitor + + + BGPPeer +
10.1.0.32
+ + + +
+
+ +
+ + 65100 + switch-t0 + + +
10.0.0.57
+ + + +
+ +
10.0.0.59
+ + + +
+ +
10.0.0.61
+ + + +
+ +
10.0.0.63
+ + + +
+
+ +
+ + 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 + + + LoopbackIP1 + Loopback1 + + 10.10.0.99/32 + + 10.10.0.99/32 + + + LoopbackIP2 + Loopback2 + + 10.21.0.64/32 + + 10.21.0.64/32 + + + LoopbackIP3 + Loopback3 + + 10.21.64.2/32 + + 10.21.64.2/32 + + + + + HostIP + eth0 + + 10.0.0.100/24 + + 10.0.0.100/24 + + + HostIP + eth0 + + 2603:10e2:0:2902::8/64 + + 2603:10e2:0:2902::8/64 + + + + + + + switch-t0 + + + PortChannel01 + fortyGigE0/112 + + + + PortChannel02 + fortyGigE0/116 + + + + PortChannel03 + fortyGigE0/120 + + + + PortChannel04 + fortyGigE0/124 + + + + + + Vlan1000 + fortyGigE0/4;fortyGigE0/8;fortyGigE0/12;fortyGigE0/16;fortyGigE0/20;fortyGigE0/24;fortyGigE0/28;fortyGigE0/32;fortyGigE0/36;fortyGigE0/40;fortyGigE0/44;fortyGigE0/48;fortyGigE0/52;fortyGigE0/56;fortyGigE0/60;fortyGigE0/64;fortyGigE0/68;fortyGigE0/72;fortyGigE0/76;fortyGigE0/80;fortyGigE0/84;fortyGigE0/88;fortyGigE0/92;fortyGigE0/96 + False + 0.0.0.0/0 + + + 192.0.0.1;192.0.0.2 + fc02:2000::1;fc02:2000::2 + 1000 + 1000 + 192.168.0.0/27 + + + + + Vlan2000 + PortChannel01;PortChannel02;PortChannel03 + False + 0.0.0.0/0 + + + 192.0.0.3;192.0.0.4 + fc02:2000::3;fc02:2000::4 + 2000 + 2000 + 192.168.200.0/27 + + + + + Vlan99 + fortyGigE0/100 + False + 0.0.0.0/0 + + UserDefinedL2Vlan + 192.0.0.1;192.0.0.2 + 99 + 99 + + + + + + Vlan98 + fortyGigE0/100;PortChannel01;PortChannel03 + False + 0.0.0.0/0 + + UserDefinedL2Vlan + 192.0.0.1;192.0.0.2 + 98 + 98 + + + + + + + + + PortChannel01 + 10.0.0.56/31 + + + + PortChannel01 + FC00::71/126 + + + + PortChannel02 + 10.0.0.58/31 + + + + PortChannel02 + FC00::75/126 + + + + PortChannel03 + 10.0.0.60/31 + + + + PortChannel03 + FC00::79/126 + + + + PortChannel04 + 10.0.0.62/31 + + + + PortChannel04 + FC00::7D/126 + + + + Vlan1000 + 192.168.0.1/27 + + + + Vlan2000 + 192.168.200.1/27 + + + + + + ERSPAN + everflow + Everflow + + + ERSPANv6 + everflowV6 + Everflow + + + EGRESS_ERSPAN + everflow_egress + Everflow + + + PortChannel01;PortChannel02;PortChannel03;PortChannel04 + DataAclIngress + DataPlane + + + PortChannel01;PortChannel02;Vlan98 + DataAclEgress + DataPlane + + + SNMP + SNMP_ACL + SNMP + + + NTP + NTP_ACL + NTP + + + SSH + SSH_ACL + SSH + + + SSH + ROUTER-PROTECT + SSH + + + SNMP + ROUTER-PROTECT + SNMP + + + NTP + NTP_ACL + + + + + + + + + + DeviceInterfaceLink + ARISTA01T1 + Ethernet1/1 + switch-t0 + fortyGigE0/112 + + + DeviceInterfaceLink + ARISTA02T1 + Ethernet1/1 + switch-t0 + fortyGigE0/116 + + + DeviceInterfaceLink + ARISTA03T1 + Ethernet1/1 + switch-t0 + fortyGigE0/120 + + + DeviceInterfaceLink + ARISTA04T1 + Ethernet1/1 + switch-t0 + fortyGigE0/124 + 100000 + + + DeviceInterfaceLink + 100000 + switch-t0 + fortyGigE0/4 + true + ARISTA05T1 + Ethernet1/33 + true + + + DeviceInterfaceLink + Servers0 + eth0 + switch-t0 + fortyGigE0/4 + + + DeviceInterfaceLink + Servers100 + eth0 + switch-t0 + fortyGigE0/100 + + + + + switch-t0 + Force10-S6000 + + + ARISTA01T1 + Arista + + + ARISTA02T1 + Arista + + + ARISTA03T1 + Arista + + + ARISTA04T1 + Arista + + + + + + + + DeviceInterface + + true + 1 + Ethernet0 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + 1 + Ethernet8 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + 1 + Ethernet12 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + 1 + Ethernet16 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + 1 + Ethernet20 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + 1 + Ethernet24 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + 1 + Ethernet28 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + 1 + Ethernet32 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + 1 + Ethernet36 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + 1 + Ethernet40 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + 1 + Ethernet44 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + 1 + Ethernet48 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + 1 + Ethernet52 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + 1 + Ethernet56 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + 1 + Ethernet60 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + 1 + Ethernet64 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + 1 + Ethernet68 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + 1 + Ethernet72 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + 1 + Ethernet76 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + 1 + Ethernet80 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + 1 + Ethernet84 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + 1 + Ethernet88 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + 1 + Ethernet92 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + 1 + Ethernet96 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + 1 + Ethernet100 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + 1 + Ethernet104 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + 1 + Ethernet108 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + 1 + Ethernet112 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + 1 + Ethernet116 + + false + 0 + 0 + 40000 + + + DeviceInterface + + true + 1 + Ethernet120 + + false + 0 + 0 + 40000 + + + Force10-S6000 + + + + + + + switch-t0 + + + ErspanDestinationIpv4 + + 2.2.2.2 + + + + + + + + + + + + + AutoNegotiation + + True + + + FECDisabled + + True + + + ARISTA05T1:Ethernet1/33;switch-t0:fortyGigE0/4 + + + + + + AutoNegotiation + + False + + + FECDisabled + + True + + + ARISTA06T1:Ethernet1/34;switch-t0:fortyGigE0/8 + + + + + + + switch-t0 + + + DeploymentId + + 1 + + + SyslogResources + + 10.3.145.8;100.127.20.21 + + + + + + + switch-t0 + Force10-S6000 +
diff --git a/src/sonic-config-engine/tests/test_j2files.py b/src/sonic-config-engine/tests/test_j2files.py index 2f424f6c3949..3ff70d40ae83 100644 --- a/src/sonic-config-engine/tests/test_j2files.py +++ b/src/sonic-config-engine/tests/test_j2files.py @@ -20,6 +20,7 @@ def setUp(self): self.ztp_ip = os.path.join(self.test_dir, "sample-ztp-ip.json") self.ztp_inband_ip = os.path.join(self.test_dir, "sample-ztp-inband-ip.json") self.t0_minigraph = os.path.join(self.test_dir, 't0-sample-graph.xml') + self.t0_minigraph_syslog = os.path.join(self.test_dir, 't0-sample-graph-syslog.xml') self.t0_minigraph_secondary_subnets = os.path.join(self.test_dir, 't0-sample-graph-secondary-subnets.xml') self.t0_mvrf_minigraph = os.path.join(self.test_dir, 't0-sample-graph-mvrf.xml') self.t0_minigraph_nomgmt = os.path.join(self.test_dir, 't0-sample-graph-nomgmt.xml') @@ -131,6 +132,11 @@ def test_interfaces(self): argument = ['-m', self.t0_minigraph, '-p', self.t0_port_config, '-a', '{\"hwaddr\":\"e4:1d:2d:a5:f3:ad\"}', '-t', interfaces_template] self.run_script(argument, output_file=self.output_file) self.assertTrue(utils.cmp(os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'interfaces'), self.output_file)) + + # ZTP disabled, MGMT_INTERFACE defined, SYSLOG_SERVER defined + argument = ['-m', self.t0_minigraph_syslog, '-p', self.t0_port_config, '-a', '{\"hwaddr\":\"e4:1d:2d:a5:f3:ad\"}', '-t', interfaces_template] + self.run_script(argument, output_file=self.output_file) + self.assertTrue(utils.cmp(os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'interfaces_syslog'), self.output_file)) argument = ['-m', self.t0_mvrf_minigraph, '-p', self.t0_port_config, '-a', '{\"hwaddr\":\"e4:1d:2d:a5:f3:ad\"}', '-t', interfaces_template] self.run_script(argument, output_file=self.output_file) From 0e419bb5a356ba93edb86e19e055bfa6821305d2 Mon Sep 17 00:00:00 2001 From: Yaqiang Zhu Date: Fri, 25 Oct 2024 12:19:17 +0800 Subject: [PATCH 06/23] [dhcp_relay] Only check parent dhcrelay process in dhcprelayd (#20551) Why I did it In master and 202405 branch, dhcp_relay container was updated to Bookworm, hence isc-dhcp-relay was updated from 4.4.1 to 4.4.3. In this version, isc-dhcp-relay would create child process to proceed when there is network io, hence dhcprelayd would get duplicated dhcrelay process when checking How I did it Only check parent dhcp_relay process How to verify it UT Run https://github.com/sonic-net/sonic-mgmt/blob/master/tests/dhcp_relay/test_dhcp_relay_stress.py with latest dhcprelayd --- .../dhcp_utilities/common/utils.py | 18 ------------- .../dhcp_utilities/dhcprelayd/dhcprelayd.py | 20 ++++++++++++-- .../tests/common_utils.py | 6 ++++- .../tests/test_dhcprelayd.py | 26 +++++++++++++------ src/sonic-dhcp-utilities/tests/test_utils.py | 15 ----------- 5 files changed, 41 insertions(+), 44 deletions(-) diff --git a/src/sonic-dhcp-utilities/dhcp_utilities/common/utils.py b/src/sonic-dhcp-utilities/dhcp_utilities/common/utils.py index 325553f536af..ee4b1815f5a0 100644 --- a/src/sonic-dhcp-utilities/dhcp_utilities/common/utils.py +++ b/src/sonic-dhcp-utilities/dhcp_utilities/common/utils.py @@ -150,24 +150,6 @@ def _parse_table_to_dict(table): return ret -def get_target_process_cmds(process_name): - """ - Get running process cmds - Args: - process_name: name of process - Returns: - List of cmds list - """ - res = [] - for proc in psutil.process_iter(): - try: - if proc.name() == process_name: - res.append(proc.cmdline()) - except psutil.NoSuchProcess: - continue - return res - - def is_smart_switch(device_metadata): """ Check in device metadata whether subtype is smartswitch diff --git a/src/sonic-dhcp-utilities/dhcp_utilities/dhcprelayd/dhcprelayd.py b/src/sonic-dhcp-utilities/dhcp_utilities/dhcprelayd/dhcprelayd.py index d1b22a3158b4..208ab9a6c934 100644 --- a/src/sonic-dhcp-utilities/dhcp_utilities/dhcprelayd/dhcprelayd.py +++ b/src/sonic-dhcp-utilities/dhcp_utilities/dhcprelayd/dhcprelayd.py @@ -8,7 +8,7 @@ import syslog import time from swsscommon import swsscommon -from dhcp_utilities.common.utils import DhcpDbConnector, terminate_proc, get_target_process_cmds, is_smart_switch +from dhcp_utilities.common.utils import DhcpDbConnector, terminate_proc, is_smart_switch from dhcp_utilities.common.dhcp_db_monitor import DhcpRelaydDbMonitor, DhcpServerTableIntfEnablementEventChecker, \ VlanTableEventChecker, VlanIntfTableEventChecker, DhcpServerFeatureStateChecker, MidPlaneTableEventChecker @@ -226,7 +226,23 @@ def _check_dhcp_relay_processes(self): """ Check whether dhcrelay running as expected, if not, dhcprelayd will exit with code 1 """ - running_cmds = get_target_process_cmds("dhcrelay") + procs = {} + for proc in psutil.process_iter(): + try: + if proc.name() != "dhcrelay": + continue + procs[proc.pid] = [proc.ppid(), proc.cmdline()] + except psutil.NoSuchProcess: + continue + + # When there is network io, dhcrelay would create child process to proceed them, psutil has chance to get + # duplicated cmdline. Hence ignore chlid process in here + running_cmds = [] + for _, (parent_pid, cmdline) in procs.items(): + if parent_pid in procs: + continue + running_cmds.append(cmdline) + running_cmds.sort() expected_cmds = [value for key, value in self.dhcp_relay_supervisor_config.items() if "isc-dhcpv4-relay" in key] expected_cmds.sort() diff --git a/src/sonic-dhcp-utilities/tests/common_utils.py b/src/sonic-dhcp-utilities/tests/common_utils.py index f5eb4e018f86..29c579545d8e 100644 --- a/src/sonic-dhcp-utilities/tests/common_utils.py +++ b/src/sonic-dhcp-utilities/tests/common_utils.py @@ -65,10 +65,11 @@ def mock_get_config_db_table(table_name): class MockProc(object): - def __init__(self, name, pid=1, exited=False): + def __init__(self, name, pid=1, exited=False, ppid=1): self.proc_name = name self.pid = pid self.exited = exited + self.parent_id = ppid def name(self): if self.exited: @@ -96,6 +97,9 @@ def wait(self): def status(self): return self.status + def ppid(self): + return self.parent_id + class MockPopen(object): def __init__(self, pid): diff --git a/src/sonic-dhcp-utilities/tests/test_dhcprelayd.py b/src/sonic-dhcp-utilities/tests/test_dhcprelayd.py index 4914ff020d63..7b542f51359d 100644 --- a/src/sonic-dhcp-utilities/tests/test_dhcprelayd.py +++ b/src/sonic-dhcp-utilities/tests/test_dhcprelayd.py @@ -195,23 +195,33 @@ def test_execute_supervisor_dhcp_relay_process(mock_swsscommon_dbconnector_init, mock_run.assert_called_once_with(["supervisorctl", op, "dhcpmon-Vlan1000"], check=True) -@pytest.mark.parametrize("target_procs_cmds", [[["dhcrelay", "-d"]], [["dhcpmon"]]]) -def test_check_dhcp_relay_process(mock_swsscommon_dbconnector_init, mock_swsscommon_table_init, target_procs_cmds): +@pytest.mark.parametrize("iter_process", [ + [ + ["dhcrelay", 2, False, 1], ["dhcrelay", 3, False, 2], ["dhcpmon", 4, False, 1], ["dhcrelay", 5, True, 1] + ], + [ + ["dhcpmon", 4, False, 1] + ]]) +def test_check_dhcp_relay_process(mock_swsscommon_dbconnector_init, mock_swsscommon_table_init, iter_process): exp_config = { - "isc-dhcpv4-relay-Vlan1000": ["dhcrelay", "-d"] + "isc-dhcpv4-relay-Vlan1000": ["/usr/sbin/dhcrelay", "-d", "-m", "discard", "-a", "%h:%p", "%P", + "--name-alias-map-file", "/tmp/port-name-alias-map.txt", "-id", "Vlan1000", + "-iu", "docker0", "240.127.1.2"], + "dhcpmon-Vlan1000": ["/usr/sbin/dhcpmon", "-id", "Vlan1000", "-iu", "docker0", "-im", "eth0"] } - with patch("dhcp_utilities.dhcprelayd.dhcprelayd.get_target_process_cmds", return_value=target_procs_cmds), \ - patch.object(DhcpRelayd, "dhcp_relay_supervisor_config", + process_iter_ret = [MockProc(name=item[0], pid=item[1], exited=item[2], ppid=item[3]) for item in iter_process] + with patch.object(DhcpRelayd, "dhcp_relay_supervisor_config", return_value=exp_config, new_callable=PropertyMock), \ - patch.object(sys, "exit", mock_exit_func): + patch.object(sys, "exit", mock_exit_func), \ + patch.object(psutil, "process_iter", return_value=process_iter_ret): dhcp_db_connector = DhcpDbConnector() dhcprelayd = DhcpRelayd(dhcp_db_connector, None) try: dhcprelayd._check_dhcp_relay_processes() except SystemExit: - assert target_procs_cmds[0] != exp_config["isc-dhcpv4-relay-Vlan1000"] + assert all(process[0] != "dhcrelay" for process in iter_process) else: - assert target_procs_cmds[0] == exp_config["isc-dhcpv4-relay-Vlan1000"] + assert any(process[0] == "dhcrelay" for process in iter_process) def test_get_dhcp_relay_config(mock_swsscommon_dbconnector_init, mock_swsscommon_table_init): diff --git a/src/sonic-dhcp-utilities/tests/test_utils.py b/src/sonic-dhcp-utilities/tests/test_utils.py index 4a41049fe06e..88d07c648d87 100644 --- a/src/sonic-dhcp-utilities/tests/test_utils.py +++ b/src/sonic-dhcp-utilities/tests/test_utils.py @@ -141,21 +141,6 @@ def test_validate_ttr_type(test_data): assert res == test_data[2] -def test_get_target_process_cmds(): - with patch.object(psutil, "process_iter", return_value=[MockProc("dhcrelay", 1), - MockProc("dhcrelay", 1, exited=True), - MockProc("dhcpmon", 2)], - new_callable=PropertyMock): - res = utils.get_target_process_cmds("dhcrelay") - expected_res = [ - [ - "/usr/sbin/dhcrelay", "-d", "-m", "discard", "-a", "%h:%p", "%P", "--name-alias-map-file", - "/tmp/port-name-alias-map.txt", "-id", "Vlan1000", "-iu", "docker0", "240.127.1.2" - ] - ] - assert res == expected_res - - @pytest.mark.parametrize("is_smart_switch", [True, False]) def test_is_smart_switch(is_smart_switch): device_metadata = {"localhost": {"subtype": "SmartSwitch"}} if is_smart_switch else {"localhost": {}} From c03ae8dcdbf33eafe5777c2410dc476511e6c778 Mon Sep 17 00:00:00 2001 From: Sai Kiran <110003254+opcoder0@users.noreply.github.com> Date: Fri, 25 Oct 2024 21:11:41 +1100 Subject: [PATCH 07/23] [docker-ptf]: CI change to publish docker-ptf image to the docker registry (#20528) Why I did it Changes to docker-ptf Dockerfile don't get automatically published to the docker registry accessed by the community. This PR addresses the issue. Work item tracking Microsoft ADO (number only): 29869315 How I did it Modified the postSteps phase in azure-pipelines-image-template.yml to invoke the script to push docker-ptf image to the docker registry. The push is applicable to build branches (master, 202305, 202311 etc.) and not feature branches. How to verify it TBD Tested branch (Please provide the tested image version) Not applicable. Description for the changelog [docker-ptf]: CI change to publish docker-ptf image to the public/community docker registry Change pipeline YAML to publish docker-ptf image to docker registry Publish only docker-ptf image for main or release branches only and not feature branch Link to config_db schema for YANG module changes Not applicable --- .../azure-pipelines-image-template.yml | 21 ++++++++++++++++++- .azure-pipelines/official-build.yml | 1 + 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/.azure-pipelines/azure-pipelines-image-template.yml b/.azure-pipelines/azure-pipelines-image-template.yml index fde8b76c4b83..f934bf366484 100644 --- a/.azure-pipelines/azure-pipelines-image-template.yml +++ b/.azure-pipelines/azure-pipelines-image-template.yml @@ -58,9 +58,28 @@ jobs: displayName: 'Make configure' postSteps: - script: | + BUILD_REASON=$(Build.Reason) + echo "Build.Reason = $BUILD_REASON" + echo "Build.DefinitionName = $BUILD_DEFINITIONNAME" + if [[ "$BUILD_REASON" != "PullRequest" && "$BUILD_DEFINITIONNAME" == "Azure.sonic-buildimage.official.vs" ]] + then + PORT=443 + DOCKERS=$(ls target/docker-ptf.gz) + BRANCH=$(Build.SourceBranchName) + echo "Branch = $BRANCH" + LABELS="$BRANCH" + [[ "$BRANCH" == "master" ]] && LABELS="$LABELS latest" + for f in $DOCKERS; do + echo $f + echo "Labels = $LABELS" + ./push_docker.sh $f $(REGISTRY_SERVER_PUBLIC) $PORT $(REGISTRY_USERNAME) "$REGISTRY_PASSWD" "$LABELS" + done + fi mkdir -p $(Build.ArtifactStagingDirectory)/target mv target/* $(Build.ArtifactStagingDirectory)/target/ - displayName: Copy Artifacts + env: + REGISTRY_PASSWD: $(REGISTRY_PASSWD) + displayName: Publish to Docker Registry and Copy Artifacts condition: always() - publish: $(Build.ArtifactStagingDirectory) artifact: 'sonic-buildimage.$(GROUP_NAME)$(GROUP_EXTNAME)' diff --git a/.azure-pipelines/official-build.yml b/.azure-pipelines/official-build.yml index ecc9bd89c697..a228529b4abf 100644 --- a/.azure-pipelines/official-build.yml +++ b/.azure-pipelines/official-build.yml @@ -36,6 +36,7 @@ stages: - stage: Build pool: sonicbld-1es variables: + - group: Container-Registry - name: CACHE_MODE value: wcache - template: .azure-pipelines/azure-pipelines-repd-build-variables.yml@buildimage From caf8d6228125a7b655b3923ca61f966086fb4ec0 Mon Sep 17 00:00:00 2001 From: mssonicbld <79238446+mssonicbld@users.noreply.github.com> Date: Fri, 25 Oct 2024 22:19:14 +0800 Subject: [PATCH 08/23] [submodule] Update submodule sonic-linux-kernel to the latest HEAD automatically (#20598) #### Why I did it src/sonic-linux-kernel ``` * fe78170 - (HEAD -> master, origin/master, origin/HEAD) Disable AMD memory encryption (#438) (26 hours ago) [Samuel Angebault] * b8cdf9e - Add arm64 dts and xmc spi device for Wistron platform support (#433) (30 hours ago) [Owen] ``` #### How I did it #### How to verify it #### Description for the changelog --- 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 6d0f01bb20eb..fe78170347f9 160000 --- a/src/sonic-linux-kernel +++ b/src/sonic-linux-kernel @@ -1 +1 @@ -Subproject commit 6d0f01bb20eb4a7409d5c31c11a94d39a02c4d5b +Subproject commit fe78170347f947f67828f94b75d3ff8e12f7fd43 From 8e0fb3052d82d2fc5a50f3bca9fe0d88074f183b Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Fri, 25 Oct 2024 18:28:22 +0200 Subject: [PATCH 09/23] [FRR]: Fixing SRv6 SID uninstall (#20585) This PR fixes the SRv6 SID uninstall introduced in this PR: #18715 This fix has been already merged in the FRR mainline: FRRouting/frr#16835 Signed-off-by: Carmine Scarpitta --- .../dplane_fpm_sonic/dplane_fpm_sonic.c | 80 ++++--- ...e-SID-structure-in-seg6local-nexthop.patch | 207 ++++++++++++++++++ src/sonic-frr/patch/series | 1 + 3 files changed, 247 insertions(+), 41 deletions(-) create mode 100644 src/sonic-frr/patch/bgpd-lib-Include-SID-structure-in-seg6local-nexthop.patch diff --git a/src/sonic-frr/dplane_fpm_sonic/dplane_fpm_sonic.c b/src/sonic-frr/dplane_fpm_sonic/dplane_fpm_sonic.c index c87a913acb1c..f01c647d4a67 100644 --- a/src/sonic-frr/dplane_fpm_sonic/dplane_fpm_sonic.c +++ b/src/sonic-frr/dplane_fpm_sonic/dplane_fpm_sonic.c @@ -1022,6 +1022,45 @@ static ssize_t netlink_srv6_localsid_msg_encode(int cmd, (cmd == RTM_NEWSRV6LOCALSID) ? "RTM_NEWSRV6LOCALSID" : "RTM_DELSRV6LOCALSID", p, dplane_ctx_get_vrf(ctx), table_id); + seg6local_ctx = &nexthop->nh_srv6->seg6local_ctx; + + nest = + nl_attr_nest(&req->n, datalen, + FPM_SRV6_LOCALSID_FORMAT); + + if (nexthop->nh_srv6->seg6local_ctx.block_len) + if (!nl_attr_put8( + &req->n, datalen, + FPM_SRV6_LOCALSID_FORMAT_BLOCK_LEN, + nexthop->nh_srv6->seg6local_ctx.block_len)) + return -1; + + if (nexthop->nh_srv6->seg6local_ctx.node_len) + if (!nl_attr_put8( + &req->n, datalen, + FPM_SRV6_LOCALSID_FORMAT_NODE_LEN, + nexthop->nh_srv6->seg6local_ctx.node_len)) + return -1; + + if (nexthop->nh_srv6->seg6local_ctx.function_len) + if (!nl_attr_put8( + &req->n, datalen, + FPM_SRV6_LOCALSID_FORMAT_FUNC_LEN, + nexthop->nh_srv6->seg6local_ctx.function_len)) + return -1; + + if (nexthop->nh_srv6->seg6local_ctx.argument_len) + if (!nl_attr_put8( + &req->n, datalen, + FPM_SRV6_LOCALSID_FORMAT_ARG_LEN, + nexthop->nh_srv6->seg6local_ctx.argument_len)) + return -1; + + nl_attr_nest_end(&req->n, nest); + + if (cmd == RTM_DELSRV6LOCALSID) + return NLMSG_ALIGN(req->n.nlmsg_len); + for (ALL_LIST_ELEMENTS_RO(srv6->locators, node, l)) { if (prefix_match(&l->prefix, p)) { locator = l; @@ -1029,47 +1068,6 @@ static ssize_t netlink_srv6_localsid_msg_encode(int cmd, } } - if (locator) { - nest = - nl_attr_nest(&req->n, datalen, - FPM_SRV6_LOCALSID_FORMAT); - - if (locator->block_bits_length) - if (!nl_attr_put8( - &req->n, datalen, - FPM_SRV6_LOCALSID_FORMAT_BLOCK_LEN, - locator->block_bits_length)) - return -1; - - if (locator->node_bits_length) - if (!nl_attr_put8( - &req->n, datalen, - FPM_SRV6_LOCALSID_FORMAT_NODE_LEN, - locator->node_bits_length)) - return -1; - - if (locator->function_bits_length) - if (!nl_attr_put8( - &req->n, datalen, - FPM_SRV6_LOCALSID_FORMAT_FUNC_LEN, - locator->function_bits_length)) - return -1; - - if (locator->argument_bits_length) - if (!nl_attr_put8( - &req->n, datalen, - FPM_SRV6_LOCALSID_FORMAT_ARG_LEN, - locator->argument_bits_length)) - return -1; - - nl_attr_nest_end(&req->n, nest); - } - - if (cmd == RTM_DELSRV6LOCALSID) - return NLMSG_ALIGN(req->n.nlmsg_len); - - seg6local_ctx = &nexthop->nh_srv6->seg6local_ctx; - switch (nexthop->nh_srv6->seg6local_action) { case ZEBRA_SEG6_LOCAL_ACTION_END: action = (locator && CHECK_FLAG(locator->flags, SRV6_LOCATOR_USID)) ? FPM_SRV6_LOCALSID_ACTION_UN : FPM_SRV6_LOCALSID_ACTION_END; diff --git a/src/sonic-frr/patch/bgpd-lib-Include-SID-structure-in-seg6local-nexthop.patch b/src/sonic-frr/patch/bgpd-lib-Include-SID-structure-in-seg6local-nexthop.patch new file mode 100644 index 000000000000..161a0454b3c5 --- /dev/null +++ b/src/sonic-frr/patch/bgpd-lib-Include-SID-structure-in-seg6local-nexthop.patch @@ -0,0 +1,207 @@ +From 8b9b9549e6d2785d4237ddb510d285aba022bb68 Mon Sep 17 00:00:00 2001 +From: Carmine Scarpitta +Date: Sun, 15 Sep 2024 17:23:34 +0200 +Subject: [PATCH 1/5] lib: Include SID structure in seg6local nexthop + +Include SID structure information in seg6local nexthop data structure. + +Signed-off-by: Carmine Scarpitta +--- + lib/srv6.h | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/lib/srv6.h b/lib/srv6.h +index acfb0631cc..3749b01563 100644 +--- a/lib/srv6.h ++++ b/lib/srv6.h +@@ -72,6 +72,10 @@ struct seg6local_context { + struct in_addr nh4; + struct in6_addr nh6; + uint32_t table; ++ uint8_t block_len; ++ uint8_t node_len; ++ uint8_t function_len; ++ uint8_t argument_len; + }; + + struct srv6_locator { +-- +2.45.2 + + +From ebea171cadaae63d89c41fdd5e4d507cf9084e42 Mon Sep 17 00:00:00 2001 +From: Carmine Scarpitta +Date: Sun, 15 Sep 2024 18:53:35 +0200 +Subject: [PATCH 2/5] bgpd: Include structure when installing End.DT4/6 SID + +Include SID structure information when installing an SRv6 End.DT6 or End.DT4 SID +in the forwarding plane. + +Signed-off-by: Carmine Scarpitta +--- + bgpd/bgp_mplsvpn.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c +index 2af553d982..b9eef35812 100644 +--- a/bgpd/bgp_mplsvpn.c ++++ b/bgpd/bgp_mplsvpn.c +@@ -393,6 +393,18 @@ void vpn_leak_zebra_vrf_sid_update_per_af(struct bgp *bgp, afi_t afi) + if (!vrf) + return; + ++ if (bgp->vpn_policy[afi].tovpn_sid_locator) { ++ ctx.block_len = ++ bgp->vpn_policy[afi].tovpn_sid_locator->block_bits_length; ++ ctx.node_len = ++ bgp->vpn_policy[afi].tovpn_sid_locator->node_bits_length; ++ ctx.function_len = ++ bgp->vpn_policy[afi] ++ .tovpn_sid_locator->function_bits_length; ++ ctx.argument_len = ++ bgp->vpn_policy[afi] ++ .tovpn_sid_locator->argument_bits_length; ++ } + ctx.table = vrf->data.l.table_id; + act = afi == AFI_IP ? ZEBRA_SEG6_LOCAL_ACTION_END_DT4 + : ZEBRA_SEG6_LOCAL_ACTION_END_DT6; +-- +2.45.2 + + +From f5c7cf0edc25905d357effe54ece27ed5db0ae6b Mon Sep 17 00:00:00 2001 +From: Carmine Scarpitta +Date: Sun, 15 Sep 2024 18:54:55 +0200 +Subject: [PATCH 3/5] bgpd: Include structure when installing End.DT46 SID + +Include SID structure information when installing an SRv6 End.DT46 SID +in the forwarding plane. + +Signed-off-by: Carmine Scarpitta +--- + bgpd/bgp_mplsvpn.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c +index b9eef35812..005a54ec1b 100644 +--- a/bgpd/bgp_mplsvpn.c ++++ b/bgpd/bgp_mplsvpn.c +@@ -453,6 +453,12 @@ void vpn_leak_zebra_vrf_sid_update_per_vrf(struct bgp *bgp) + if (!vrf) + return; + ++ if (bgp->tovpn_sid_locator) { ++ ctx.block_len = bgp->tovpn_sid_locator->block_bits_length; ++ ctx.node_len = bgp->tovpn_sid_locator->node_bits_length; ++ ctx.function_len = bgp->tovpn_sid_locator->function_bits_length; ++ ctx.argument_len = bgp->tovpn_sid_locator->argument_bits_length; ++ } + ctx.table = vrf->data.l.table_id; + act = ZEBRA_SEG6_LOCAL_ACTION_END_DT46; + zclient_send_localsid(zclient, tovpn_sid, bgp->vrf_id, act, &ctx); +-- +2.45.2 + + +From e2428a573321cb5909a3858008df2968b655a086 Mon Sep 17 00:00:00 2001 +From: Carmine Scarpitta +Date: Sun, 15 Sep 2024 18:56:21 +0200 +Subject: [PATCH 4/5] bgpd: Include structure when removing End.DT4/6 SID + +Include SID structure information when removing an SRv6 End.DT4 or End.DT6 SID +from the forwarding plane. + +Signed-off-by: Carmine Scarpitta +--- + bgpd/bgp_mplsvpn.c | 18 ++++++++++++++++-- + 1 file changed, 16 insertions(+), 2 deletions(-) + +diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c +index 005a54ec1b..aba1b4febe 100644 +--- a/bgpd/bgp_mplsvpn.c ++++ b/bgpd/bgp_mplsvpn.c +@@ -495,6 +495,7 @@ void vpn_leak_zebra_vrf_sid_update(struct bgp *bgp, afi_t afi) + void vpn_leak_zebra_vrf_sid_withdraw_per_af(struct bgp *bgp, afi_t afi) + { + int debug = BGP_DEBUG(vpn, VPN_LEAK_LABEL); ++ struct seg6local_context seg6localctx = {}; + + if (bgp->vrf_id == VRF_UNKNOWN) { + if (debug) +@@ -507,9 +508,22 @@ void vpn_leak_zebra_vrf_sid_withdraw_per_af(struct bgp *bgp, afi_t afi) + zlog_debug("%s: deleting sid for vrf %s afi (id=%d)", __func__, + bgp->name_pretty, bgp->vrf_id); + ++ if (bgp->vpn_policy[afi].tovpn_sid_locator) { ++ seg6localctx.block_len = ++ bgp->vpn_policy[afi].tovpn_sid_locator->block_bits_length; ++ seg6localctx.node_len = ++ bgp->vpn_policy[afi].tovpn_sid_locator->node_bits_length; ++ seg6localctx.function_len = ++ bgp->vpn_policy[afi] ++ .tovpn_sid_locator->function_bits_length; ++ seg6localctx.argument_len = ++ bgp->vpn_policy[afi] ++ .tovpn_sid_locator->argument_bits_length; ++ } + zclient_send_localsid(zclient, +- bgp->vpn_policy[afi].tovpn_zebra_vrf_sid_last_sent, +- bgp->vrf_id, ZEBRA_SEG6_LOCAL_ACTION_UNSPEC, NULL); ++ bgp->vpn_policy[afi].tovpn_zebra_vrf_sid_last_sent, ++ bgp->vrf_id, ZEBRA_SEG6_LOCAL_ACTION_UNSPEC, ++ &seg6localctx); + XFREE(MTYPE_BGP_SRV6_SID, + bgp->vpn_policy[afi].tovpn_zebra_vrf_sid_last_sent); + } +-- +2.45.2 + + +From 8d148b738cdf8b987a67e13979331d91337494f3 Mon Sep 17 00:00:00 2001 +From: Carmine Scarpitta +Date: Sun, 15 Sep 2024 18:56:48 +0200 +Subject: [PATCH 5/5] bgpd: Include structure when removing End.DT46 SID + +Include SID structure information when removing an SRv6 End.DT46 SID +from the forwarding plane. + +Signed-off-by: Carmine Scarpitta +--- + bgpd/bgp_mplsvpn.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c +index aba1b4febe..6589f3e388 100644 +--- a/bgpd/bgp_mplsvpn.c ++++ b/bgpd/bgp_mplsvpn.c +@@ -535,6 +535,7 @@ void vpn_leak_zebra_vrf_sid_withdraw_per_af(struct bgp *bgp, afi_t afi) + void vpn_leak_zebra_vrf_sid_withdraw_per_vrf(struct bgp *bgp) + { + int debug = BGP_DEBUG(vpn, VPN_LEAK_LABEL); ++ struct seg6local_context seg6localctx = {}; + + if (bgp->vrf_id == VRF_UNKNOWN) { + if (debug) +@@ -548,9 +549,18 @@ void vpn_leak_zebra_vrf_sid_withdraw_per_vrf(struct bgp *bgp) + zlog_debug("%s: deleting sid for vrf %s (id=%d)", __func__, + bgp->name_pretty, bgp->vrf_id); + ++ if (bgp->tovpn_sid_locator) { ++ seg6localctx.block_len = ++ bgp->tovpn_sid_locator->block_bits_length; ++ seg6localctx.node_len = bgp->tovpn_sid_locator->node_bits_length; ++ seg6localctx.function_len = ++ bgp->tovpn_sid_locator->function_bits_length; ++ seg6localctx.argument_len = ++ bgp->tovpn_sid_locator->argument_bits_length; ++ } + zclient_send_localsid(zclient, bgp->tovpn_zebra_vrf_sid_last_sent, + bgp->vrf_id, ZEBRA_SEG6_LOCAL_ACTION_UNSPEC, +- NULL); ++ &seg6localctx); + XFREE(MTYPE_BGP_SRV6_SID, bgp->tovpn_zebra_vrf_sid_last_sent); + } + +-- +2.45.2 + diff --git a/src/sonic-frr/patch/series b/src/sonic-frr/patch/series index c14a56f5b10f..0cb3259b47d9 100644 --- a/src/sonic-frr/patch/series +++ b/src/sonic-frr/patch/series @@ -52,3 +52,4 @@ 0052-bgpd-backpressure-log-error-for-evpn-when-route-inst.patch 0053-bgpd-Set-md5-TCP-socket-option-for-outgoing-connections-on-listener.patch build-dplane-fpm-sonic-module.patch +bgpd-lib-Include-SID-structure-in-seg6local-nexthop.patch From 16c98c028ef8f4ddeffba860b2700af921d967f9 Mon Sep 17 00:00:00 2001 From: Philo <135693886+philo-micas@users.noreply.github.com> Date: Sat, 26 Oct 2024 01:33:02 +0800 Subject: [PATCH 10/23] [Micas/Platform]platform support M2-W6520-24DC8QC (#20553) * [Micas/Platform]platform support M2-W6920-32QC2X Signed-off-by: philo * update platform files Signed-off-by: philo * fix Semgrep Signed-off-by: philo * Update control --------- Signed-off-by: philo --- .../M2-W6520-24DC8QC/hwsku.json | 100 + .../M2-W6520-24DC8QC/port_config.ini | 33 + .../M2-W6520-24DC8QC/sai.profile | 1 + ...m2-w6520-24dc8qc-24x200G+8x400G-copper.yml | 4114 +++++++++++++++ .../td4-m2-w6520-24dc8qc-24x200G+8x400G.yml | 4125 +++++++++++++++ .../x86_64-micas_m2-w6520-24dc8qc-r0/cpu.cint | 85 + .../custom_led.bin | Bin 0 -> 716 bytes .../default_sku | 1 + .../x86_64-micas_m2-w6520-24dc8qc-r0/dev.xml | 371 ++ .../x86_64-micas_m2-w6520-24dc8qc-r0/fru.py | 961 ++++ .../hwsku.json | 100 + .../installer.conf | 2 + .../media_settings.json | 1476 ++++++ .../monitor.py | 402 ++ .../pcie.yaml | 581 +++ .../platform.json | 1010 ++++ .../platform_asic | 1 + .../platform_components.json | 16 + .../platform_env.conf | 2 + .../plugins/sfputil.py | 365 ++ .../plugins/ssd_util.py | 318 ++ .../pmon_daemon_control.json | 3 + .../postinit_cmd_file.soc | 7 + .../system_health_monitoring_config.json | 0 platform/broadcom/one-image.mk | 3 +- platform/broadcom/platform-modules-micas.mk | 8 + .../common/app/dev_util/dfd_debug.c | 20 + .../common/app/dev_util/dfd_utest.c | 23 +- .../common/app/dev_util/dfd_utest.h | 21 +- .../app/fw_upgrade/fw_upgrade/fw_upgrade.c | 20 + .../fw_upgrade/fw_upgrade/fw_upgrade_debug.c | 20 + .../fw_upgrade/include/fw_upgrade.h | 20 + .../fw_upgrade/include/fw_upgrade_debug.h | 20 + .../common/lib/algorithm/hysteresis.py | 16 + .../common/lib/algorithm/openloop.py | 16 + .../common/lib/algorithm/pid.py | 16 + .../common/lib/eepromutil/cust_fru.py | 17 +- .../common/lib/eepromutil/fantlv.py | 44 +- .../common/lib/eepromutil/fru.py | 55 +- .../common/lib/eepromutil/onietlv.py | 32 +- .../common/lib/eepromutil/wedge.py | 418 ++ .../common/lib/eepromutil/wedge_v5.py | 591 +++ .../common/lib/plat_hal/baseutil.py | 18 +- .../common/lib/plat_hal/chassisbase.py | 120 +- .../common/lib/plat_hal/component.py | 18 +- .../common/lib/plat_hal/cpld.py | 18 +- .../common/lib/plat_hal/cpu.py | 17 +- .../common/lib/plat_hal/dcdc.py | 25 +- .../common/lib/plat_hal/devicebase.py | 37 +- .../common/lib/plat_hal/fan.py | 126 +- .../common/lib/plat_hal/interface.py | 49 +- .../common/lib/plat_hal/led.py | 24 +- .../common/lib/plat_hal/onie_e2.py | 18 +- .../common/lib/plat_hal/osutil.py | 50 +- .../common/lib/plat_hal/psu.py | 20 +- .../common/lib/plat_hal/rotor.py | 22 +- .../common/lib/plat_hal/sensor.py | 84 +- .../common/lib/plat_hal/temp.py | 47 +- .../common/lib/restful_util/restful_api.py | 23 +- .../common/lib/wbutil/baseutil.py | 16 + .../common/lib/wbutil/smbus.py | 30 +- .../common/modules/Makefile | 7 + .../common/modules/ct7148.c | 237 + .../common/modules/dfd_tlveeprom.c | 37 +- .../common/modules/dfd_tlveeprom.h | 20 + .../common/modules/fpga_i2c.h | 20 + .../common/modules/hw_test.c | 20 +- .../common/modules/hw_test.h | 19 + .../common/modules/pinctrl/core.h | 21 +- .../common/modules/pinctrl/wb_gpio_c3000.c | 20 +- .../modules/pinctrl/wb_gpio_c3000_device.c | 20 + .../common/modules/pinctrl/wb_pinctrl_intel.c | 22 +- .../common/modules/pinctrl/wb_pinctrl_intel.h | 22 +- .../modules/plat_sysfs/dev_cfg/cfg/dfd_cfg.c | 20 + .../plat_sysfs/dev_cfg/cfg/dfd_cfg_adapter.c | 20 + .../plat_sysfs/dev_cfg/cfg/dfd_cfg_file.c | 20 + .../plat_sysfs/dev_cfg/cfg/dfd_cfg_info.c | 39 + .../plat_sysfs/dev_cfg/cfg/dfd_cfg_listnode.c | 20 + .../plat_sysfs/dev_cfg/dfd_fan_driver.c | 20 + .../modules/plat_sysfs/dev_cfg/dfd_module.c | 20 + .../plat_sysfs/dev_cfg/dfd_psu_driver.c | 20 + .../plat_sysfs/dev_cfg/dfd_sensors_driver.c | 20 + .../plat_sysfs/dev_cfg/dfd_sff_driver.c | 20 + .../plat_sysfs/dev_cfg/dfd_slot_driver.c | 20 + .../plat_sysfs/dev_cfg/include/dfd_cfg.h | 20 + .../dev_cfg/include/dfd_cfg_adapter.h | 20 + .../plat_sysfs/dev_cfg/include/dfd_cfg_file.h | 20 + .../plat_sysfs/dev_cfg/include/dfd_cfg_info.h | 23 +- .../dev_cfg/include/dfd_cfg_listnode.h | 20 + .../dev_cfg/include/dfd_fan_driver.h | 20 + .../plat_sysfs/dev_cfg/include/dfd_module.h | 20 + .../dev_cfg/include/dfd_psu_driver.h | 20 + .../dev_cfg/include/dfd_sensors_driver.h | 20 + .../dev_cfg/include/dfd_sff_driver.h | 20 + .../dev_cfg/include/dfd_slot_driver.h | 20 + .../dev_sysfs/include/plat_switch.h | 20 + .../dev_sysfs/include/sysfs_common.h | 20 + .../modules/plat_sysfs/dev_sysfs/plat_fan.c | 17 +- .../modules/plat_sysfs/dev_sysfs/plat_psu.c | 17 +- .../plat_sysfs/dev_sysfs/plat_sensor.c | 18 +- .../modules/plat_sysfs/dev_sysfs/plat_sff.c | 17 +- .../modules/plat_sysfs/dev_sysfs/plat_slot.c | 17 +- .../plat_sysfs/dev_sysfs/plat_switch.c | 20 +- .../common/modules/platform_common.h | 20 + .../common/modules/platform_common_module.c | 20 + .../common/modules/pmbus.h | 20 +- .../common/modules/s3ip_sysfs/Makefile | 19 + .../modules/s3ip_sysfs/device_driver/Makefile | 36 + .../device_driver/cpld_device_driver.c | 217 + .../device_driver/curr_sensor_device_driver.c | 220 + .../device_driver/eeprom_device_driver.c | 209 + .../device_driver/fan_device_driver.c | 542 ++ .../device_driver/fpga_device_driver.c | 216 + .../include/device_driver_common.h | 69 + .../device_driver/psu_device_driver.c | 1025 ++++ .../device_driver/slot_device_driver.c | 1100 ++++ .../device_driver/syseeprom_device_driver.c | 136 + .../device_driver/sysled_device_driver.c | 240 + .../device_driver/system_device_driver.c | 109 + .../device_driver/temp_sensor_device_driver.c | 275 + .../device_driver/transceiver_device_driver.c | 481 ++ .../device_driver/vol_sensor_device_driver.c | 267 + .../device_driver/watchdog_device_driver.c | 214 + .../modules/s3ip_sysfs/switch_driver/Makefile | 35 + .../s3ip_sysfs/switch_driver/cfg/dfd_cfg.c | 1169 +++++ .../switch_driver/cfg/dfd_cfg_adapter.c | 654 +++ .../switch_driver/cfg/dfd_cfg_file.c | 305 ++ .../switch_driver/cfg/dfd_cfg_info.c | 929 ++++ .../switch_driver/cfg/dfd_cfg_listnode.c | 133 + .../switch_driver/cfg/dfd_frueeprom.c | 534 ++ .../switch_driver/cfg/dfd_tlveeprom.c | 469 ++ .../switch_driver/include/dfd_cfg.h | 247 + .../switch_driver/include/dfd_cfg_adapter.h | 136 + .../switch_driver/include/dfd_cfg_file.h | 101 + .../switch_driver/include/dfd_cfg_info.h | 192 + .../switch_driver/include/dfd_cfg_listnode.h | 80 + .../switch_driver/include/dfd_frueeprom.h | 107 + .../switch_driver/include/dfd_sysfs_common.h | 251 + .../switch_driver/include/dfd_tlveeprom.h | 91 + .../switch_driver/include/switch_driver.h | 101 + .../switch_driver/include/wb_cpld_driver.h | 100 + .../switch_driver/include/wb_eeprom_driver.h | 59 + .../switch_driver/include/wb_fan_driver.h | 191 + .../switch_driver/include/wb_fpga_driver.h | 100 + .../switch_driver/include/wb_led_driver.h | 45 + .../switch_driver/include/wb_module.h | 360 ++ .../switch_driver/include/wb_psu_driver.h | 114 + .../switch_driver/include/wb_sensors_driver.h | 82 + .../switch_driver/include/wb_sff_driver.h | 63 + .../switch_driver/include/wb_slot_driver.h | 64 + .../switch_driver/include/wb_system_driver.h | 33 + .../include/wb_watchdog_driver.h | 37 + .../s3ip_sysfs/switch_driver/switch_driver.c | 4577 +++++++++++++++++ .../s3ip_sysfs/switch_driver/wb_cpld_driver.c | 274 + .../switch_driver/wb_eeprom_driver.c | 230 + .../s3ip_sysfs/switch_driver/wb_fan_driver.c | 1093 ++++ .../s3ip_sysfs/switch_driver/wb_fpga_driver.c | 341 ++ .../s3ip_sysfs/switch_driver/wb_led_driver.c | 133 + .../s3ip_sysfs/switch_driver/wb_module.c | 73 + .../s3ip_sysfs/switch_driver/wb_psu_driver.c | 950 ++++ .../switch_driver/wb_sensors_driver.c | 345 ++ .../s3ip_sysfs/switch_driver/wb_sff_driver.c | 143 + .../s3ip_sysfs/switch_driver/wb_slot_driver.c | 174 + .../switch_driver/wb_system_driver.c | 253 + .../switch_driver/wb_watchdog_driver.c | 217 + .../modules/s3ip_sysfs/sysfs_driver/Makefile | 34 + .../s3ip_sysfs/sysfs_driver/cpld_sysfs.c | 444 ++ .../sysfs_driver/curr_sensor_sysfs.c | 385 ++ .../s3ip_sysfs/sysfs_driver/eeprom_sysfs.c | 417 ++ .../s3ip_sysfs/sysfs_driver/fan_sysfs.c | 777 +++ .../s3ip_sysfs/sysfs_driver/fpga_sysfs.c | 345 ++ .../sysfs_driver/include/cpld_sysfs.h | 36 + .../sysfs_driver/include/curr_sensor_sysfs.h | 38 + .../sysfs_driver/include/eeprom_sysfs.h | 36 + .../sysfs_driver/include/fan_sysfs.h | 53 + .../sysfs_driver/include/fpga_sysfs.h | 36 + .../sysfs_driver/include/psu_sysfs.h | 73 + .../sysfs_driver/include/slot_sysfs.h | 80 + .../s3ip_sysfs/sysfs_driver/include/switch.h | 96 + .../sysfs_driver/include/syseeprom_sysfs.h | 32 + .../sysfs_driver/include/sysled_sysfs.h | 39 + .../sysfs_driver/include/system_sysfs.h | 54 + .../sysfs_driver/include/temp_sensor_sysfs.h | 42 + .../sysfs_driver/include/transceiver_sysfs.h | 50 + .../sysfs_driver/include/vol_sensor_sysfs.h | 40 + .../sysfs_driver/include/watchdog_sysfs.h | 36 + .../s3ip_sysfs/sysfs_driver/psu_sysfs.c | 1180 +++++ .../s3ip_sysfs/sysfs_driver/slot_sysfs.c | 1955 +++++++ .../modules/s3ip_sysfs/sysfs_driver/switch.c | 309 ++ .../s3ip_sysfs/sysfs_driver/sysled_sysfs.c | 289 ++ .../s3ip_sysfs/sysfs_driver/system_sysfs.c | 218 + .../sysfs_driver/temp_sensor_sysfs.c | 458 ++ .../sysfs_driver/transceiver_sysfs.c | 996 ++++ .../sysfs_driver/vol_sensor_sysfs.c | 416 ++ .../s3ip_sysfs/sysfs_driver/watchdog_sysfs.c | 241 + .../common/modules/wb_csu550.c | 19 +- .../common/modules/wb_fpga_i2c_bus_drv.c | 29 +- .../common/modules/wb_fpga_pca954x_drv.c | 29 +- .../common/modules/wb_fpga_pcie.c | 20 +- .../common/modules/wb_gpio_d1500.c | 22 +- .../common/modules/wb_gpio_device.c | 20 + .../common/modules/wb_i2c_dev.c | 36 +- .../common/modules/wb_i2c_dev.h | 20 + .../common/modules/wb_i2c_gpio_device.c | 20 + .../common/modules/wb_i2c_mux_pca954x.c | 35 +- .../common/modules/wb_i2c_mux_pca954x.h | 20 + .../common/modules/wb_i2c_mux_pca9641.c | 24 +- .../common/modules/wb_i2c_mux_pca9641.h | 20 + .../common/modules/wb_i2c_ocores.c | 21 +- .../common/modules/wb_i2c_ocores.h | 20 + .../common/modules/wb_indirect_dev.c | 869 ++++ .../common/modules/wb_indirect_dev.h | 54 + .../common/modules/wb_io_dev.c | 141 +- .../common/modules/wb_io_dev.h | 26 + .../common/modules/wb_lpc_drv.c | 20 +- .../common/modules/wb_lpc_drv.h | 20 + .../common/modules/wb_mac_bsc.c | 3 +- .../common/modules/wb_mdio_gpio_device.c | 20 + .../common/modules/wb_pcie_dev.c | 142 +- .../common/modules/wb_pcie_dev.h | 24 + .../common/modules/wb_platform_i2c_dev.c | 20 + .../common/modules/wb_platform_i2c_dev.h | 20 + .../common/modules/wb_spi_dev.c | 35 +- .../common/modules/wb_spi_dev.h | 20 + .../common/modules/wb_spi_gpio_device.c | 20 + .../common/modules/wb_spi_ocores.c | 56 +- .../common/modules/wb_spi_ocores.h | 21 + .../common/modules/wb_ucd9081.c | 356 ++ .../common/modules/wb_uio_irq.c | 20 + .../common/modules/wb_wdt.c | 75 +- .../common/modules/wb_wdt.h | 20 + .../common/modules/wb_xdpe132g5c.c | 21 +- .../common/modules/wb_xdpe132g5c_pmbus.c | 20 + .../common/script/auto_update.py | 15 + .../common/script/avscontrol.py | 18 +- .../common/script/cpodaemon.sh | 99 + .../common/script/dev_monitor.py | 16 + .../common/script/drv_update.py | 17 +- .../common/script/generate_airflow.py | 17 +- .../common/script/hal_fanctrl.py | 16 + .../common/script/hal_ledctrl.py | 208 +- .../common/script/hal_pltfm.py | 20 +- .../common/script/intelligent_monitor.py | 55 +- .../script/intelligent_monitor/monitor_fan.py | 16 +- .../common/script/platform_common.py | 27 +- .../common/script/platform_config.py | 27 +- .../common/script/platform_driver.py | 22 +- .../common/script/platform_e2.py | 775 ++- .../common/script/platform_intf.py | 16 + .../common/script/platform_ipmi.py | 17 +- .../common/script/platform_manufacturer.py | 36 +- .../common/script/platform_power.py | 111 + .../common/script/platform_process.py | 16 + .../common/script/platform_sensors.py | 26 + .../common/script/platform_sensors_hal.py | 280 + .../common/script/platform_test.py | 16 +- .../common/script/platform_util.py | 75 +- .../common/script/pmon_syslog.py | 20 +- .../common/script/power_ctrl.py | 333 ++ .../common/script/reboot_cause.py | 25 +- .../common/script/reboot_ctrl.py | 150 - .../common/script/sensors | 17 +- .../common/script/set_eth_mac.py | 17 +- .../common/script/sfp_highest_temperatue.py | 168 +- .../common/script/slot_monitor.py | 17 +- .../common/script/ssdmon | 16 +- .../common/script/subnetwork.py | 17 +- .../common/script/tty_console.py | 16 +- .../common/script/upgrade.py | 31 +- .../common/script/warm_upgrade.py | 20 +- .../common/sonic_platform/chassis.py | 19 +- .../common/sonic_platform/component.py | 19 +- .../common/sonic_platform/dcdc.py | 19 +- .../common/sonic_platform/eeprom.py | 23 +- .../common/sonic_platform/fan_drawer.py | 16 +- .../common/sonic_platform/pcie.py | 19 +- .../common/sonic_platform/platform.py | 18 +- .../common/sonic_platform/psu.py | 17 +- .../common/sonic_platform/sfp.py | 351 +- .../common/sonic_platform/watchdog.py | 17 +- .../debian/control | 6 +- ...orm-modules-micas-m2-w6520-24dc8qc.install | 1 + ...rm-modules-micas-m2-w6520-24dc8qc.postinst | 10 + .../debian/rule.mk | 1 + .../m2-w6520-24dc8qc/Makefile | 25 + ...x86_64_micas_m2_w6520_24dc8qc_r0_config.py | 1424 +++++ ...4_micas_m2_w6520_24dc8qc_r0_port_config.py | 7 + ...x86_64_micas_m2_w6520_24dc8qc_r0_device.py | 1190 +++++ ...86_64_micas_m2_w6520_24dc8qc_r0_monitor.py | 207 + .../m2-w6520-24dc8qc/modules/driver/Makefile | 12 + .../modules/driver/wb_fpga_i2c_bus_device.c | 874 ++++ .../modules/driver/wb_fpga_pca954x_device.c | 329 ++ .../modules/driver/wb_i2c_dev_device.c | 175 + .../modules/driver/wb_io_dev_device.c | 138 + .../modules/driver/wb_lpc_drv_device.c | 150 + .../modules/driver/wb_pcie_dev_device.c | 113 + .../plat_sysfs_cfg/WB_PLAT_CPLD.cfg | 37 + .../plat_sysfs_cfg/WB_PLAT_FAN.cfg | 437 ++ .../plat_sysfs_cfg/WB_PLAT_PSU.cfg | 64 + .../plat_sysfs_cfg/WB_PLAT_SFF.cfg | 383 ++ .../plat_sysfs_cfg/cfg_file_name | 4 + .../m2-w6520-24dc8qc/setup.py | 39 + 302 files changed, 57953 insertions(+), 851 deletions(-) create mode 100644 device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/M2-W6520-24DC8QC/hwsku.json create mode 100644 device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/M2-W6520-24DC8QC/port_config.ini create mode 100644 device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/M2-W6520-24DC8QC/sai.profile create mode 100644 device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/M2-W6520-24DC8QC/td4-m2-w6520-24dc8qc-24x200G+8x400G-copper.yml create mode 100644 device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/M2-W6520-24DC8QC/td4-m2-w6520-24dc8qc-24x200G+8x400G.yml create mode 100644 device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/cpu.cint create mode 100644 device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/custom_led.bin create mode 100644 device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/default_sku create mode 100644 device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/dev.xml create mode 100644 device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/fru.py create mode 100644 device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/hwsku.json create mode 100644 device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/installer.conf create mode 100644 device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/media_settings.json create mode 100644 device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/monitor.py create mode 100644 device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/pcie.yaml create mode 100644 device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/platform.json create mode 100644 device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/platform_asic create mode 100644 device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/platform_components.json create mode 100644 device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/platform_env.conf create mode 100644 device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/plugins/sfputil.py create mode 100644 device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/plugins/ssd_util.py create mode 100644 device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/pmon_daemon_control.json create mode 100644 device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/postinit_cmd_file.soc create mode 100644 device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/system_health_monitoring_config.json create mode 100755 platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/wedge.py create mode 100755 platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/wedge_v5.py create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/ct7148.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/cpld_device_driver.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/curr_sensor_device_driver.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/eeprom_device_driver.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/fan_device_driver.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/fpga_device_driver.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/include/device_driver_common.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/psu_device_driver.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/slot_device_driver.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/syseeprom_device_driver.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/sysled_device_driver.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/system_device_driver.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/temp_sensor_device_driver.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/transceiver_device_driver.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/vol_sensor_device_driver.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/watchdog_device_driver.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg_adapter.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg_file.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg_info.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg_listnode.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_frueeprom.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_tlveeprom.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_cfg.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_cfg_adapter.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_cfg_file.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_cfg_info.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_cfg_listnode.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_frueeprom.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_sysfs_common.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_tlveeprom.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/switch_driver.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_cpld_driver.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_eeprom_driver.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_fan_driver.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_fpga_driver.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_led_driver.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_module.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_psu_driver.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_sensors_driver.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_sff_driver.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_slot_driver.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_system_driver.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_watchdog_driver.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/switch_driver.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_cpld_driver.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_eeprom_driver.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_fan_driver.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_fpga_driver.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_led_driver.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_module.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_psu_driver.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_sensors_driver.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_sff_driver.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_slot_driver.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_system_driver.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_watchdog_driver.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/cpld_sysfs.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/curr_sensor_sysfs.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/eeprom_sysfs.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/fan_sysfs.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/fpga_sysfs.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/cpld_sysfs.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/curr_sensor_sysfs.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/eeprom_sysfs.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/fan_sysfs.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/fpga_sysfs.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/psu_sysfs.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/slot_sysfs.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/switch.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/syseeprom_sysfs.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/sysled_sysfs.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/system_sysfs.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/temp_sensor_sysfs.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/transceiver_sysfs.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/vol_sensor_sysfs.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/watchdog_sysfs.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/psu_sysfs.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/slot_sysfs.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/switch.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/sysled_sysfs.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/system_sysfs.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/temp_sensor_sysfs.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/transceiver_sysfs.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/vol_sensor_sysfs.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/watchdog_sysfs.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/wb_indirect_dev.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/wb_indirect_dev.h create mode 100644 platform/broadcom/sonic-platform-modules-micas/common/modules/wb_ucd9081.c create mode 100755 platform/broadcom/sonic-platform-modules-micas/common/script/cpodaemon.sh create mode 100755 platform/broadcom/sonic-platform-modules-micas/common/script/platform_power.py create mode 100755 platform/broadcom/sonic-platform-modules-micas/common/script/platform_sensors_hal.py create mode 100755 platform/broadcom/sonic-platform-modules-micas/common/script/power_ctrl.py delete mode 100755 platform/broadcom/sonic-platform-modules-micas/common/script/reboot_ctrl.py create mode 100644 platform/broadcom/sonic-platform-modules-micas/debian/platform-modules-micas-m2-w6520-24dc8qc.install create mode 100644 platform/broadcom/sonic-platform-modules-micas/debian/platform-modules-micas-m2-w6520-24dc8qc.postinst create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/config/x86_64_micas_m2_w6520_24dc8qc_r0_config.py create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/config/x86_64_micas_m2_w6520_24dc8qc_r0_port_config.py create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/hal-config/x86_64_micas_m2_w6520_24dc8qc_r0_device.py create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/hal-config/x86_64_micas_m2_w6520_24dc8qc_r0_monitor.py create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_fpga_i2c_bus_device.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_fpga_pca954x_device.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_i2c_dev_device.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_io_dev_device.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_lpc_drv_device.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_pcie_dev_device.c create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/plat_sysfs_cfg/WB_PLAT_CPLD.cfg create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/plat_sysfs_cfg/WB_PLAT_FAN.cfg create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/plat_sysfs_cfg/WB_PLAT_PSU.cfg create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/plat_sysfs_cfg/WB_PLAT_SFF.cfg create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/plat_sysfs_cfg/cfg_file_name create mode 100644 platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/setup.py diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/M2-W6520-24DC8QC/hwsku.json b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/M2-W6520-24DC8QC/hwsku.json new file mode 100644 index 000000000000..cadf2fb312eb --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/M2-W6520-24DC8QC/hwsku.json @@ -0,0 +1,100 @@ +{ + "interfaces": { + "Ethernet1": { + "default_brkout_mode": "1x200G" + }, + "Ethernet5": { + "default_brkout_mode": "1x200G" + }, + "Ethernet9": { + "default_brkout_mode": "1x200G" + }, + "Ethernet13": { + "default_brkout_mode": "1x200G" + }, + "Ethernet17": { + "default_brkout_mode": "1x200G" + }, + "Ethernet21": { + "default_brkout_mode": "1x200G" + }, + "Ethernet25": { + "default_brkout_mode": "1x200G" + }, + "Ethernet29": { + "default_brkout_mode": "1x200G" + }, + "Ethernet33": { + "default_brkout_mode": "1x200G" + }, + "Ethernet37": { + "default_brkout_mode": "1x200G" + }, + "Ethernet41": { + "default_brkout_mode": "1x200G" + }, + "Ethernet45": { + "default_brkout_mode": "1x200G" + }, + "Ethernet49": { + "default_brkout_mode": "1x200G" + }, + "Ethernet53": { + "default_brkout_mode": "1x200G" + }, + "Ethernet57": { + "default_brkout_mode": "1x200G" + }, + "Ethernet61": { + "default_brkout_mode": "1x200G" + }, + "Ethernet65": { + "default_brkout_mode": "1x200G" + }, + "Ethernet69": { + "default_brkout_mode": "1x200G" + }, + "Ethernet73": { + "default_brkout_mode": "1x200G" + }, + "Ethernet77": { + "default_brkout_mode": "1x200G" + }, + "Ethernet81": { + "default_brkout_mode": "1x200G" + }, + "Ethernet85": { + "default_brkout_mode": "1x200G" + }, + "Ethernet89": { + "default_brkout_mode": "1x200G" + }, + "Ethernet93": { + "default_brkout_mode": "1x200G" + }, + "Ethernet97": { + "default_brkout_mode": "1x400G" + }, + "Ethernet105": { + "default_brkout_mode": "1x400G" + }, + "Ethernet113": { + "default_brkout_mode": "1x400G" + }, + "Ethernet121": { + "default_brkout_mode": "1x400G" + }, + "Ethernet129": { + "default_brkout_mode": "1x400G" + }, + "Ethernet137": { + "default_brkout_mode": "1x400G" + }, + "Ethernet145": { + "default_brkout_mode": "1x400G" + }, + "Ethernet153": { + "default_brkout_mode": "1x400G" + } + } +} diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/M2-W6520-24DC8QC/port_config.ini b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/M2-W6520-24DC8QC/port_config.ini new file mode 100644 index 000000000000..1a166a9a8367 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/M2-W6520-24DC8QC/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias index speed +Ethernet1 25,26,27,28 twoHundredGigE0/1 0 200000 +Ethernet5 29,30,31,32 twoHundredGigE0/2 1 200000 +Ethernet9 41,42,43,44 twoHundredGigE0/3 2 200000 +Ethernet13 45,46,47,48 twoHundredGigE0/4 3 200000 +Ethernet17 49,50,51,52 twoHundredGigE0/5 4 200000 +Ethernet21 53,54,55,56 twoHundredGigE0/6 5 200000 +Ethernet25 57,58,59,60 twoHundredGigE0/7 6 200000 +Ethernet29 61,62,63,64 twoHundredGigE0/8 7 200000 +Ethernet33 9,10,11,12 twoHundredGigE0/9 8 200000 +Ethernet37 13,14,15,16 twoHundredGigE0/10 9 200000 +Ethernet41 17,18,19,20 twoHundredGigE0/11 10 200000 +Ethernet45 21,22,23,24 twoHundredGigE0/12 11 200000 +Ethernet49 81,82,83,84 twoHundredGigE0/13 12 200000 +Ethernet53 85,86,87,88 twoHundredGigE0/14 13 200000 +Ethernet57 89,90,91,92 twoHundredGigE0/15 14 200000 +Ethernet61 93,94,95,96 twoHundredGigE0/16 15 200000 +Ethernet65 97,98,99,100 twoHundredGigE0/17 16 200000 +Ethernet69 101,102,103,104 twoHundredGigE0/18 17 200000 +Ethernet73 137,138,139,140 twoHundredGigE0/19 18 200000 +Ethernet77 141,142,143,144 twoHundredGigE0/20 19 200000 +Ethernet81 145,146,147,148 twoHundredGigE0/21 20 200000 +Ethernet85 149,150,151,152 twoHundredGigE0/22 21 200000 +Ethernet89 153,154,155,156 twoHundredGigE0/23 22 200000 +Ethernet93 157,158,159,160 twoHundredGigE0/24 23 200000 +Ethernet97 1,2,3,4,5,6,7,8 fourHundredGigE0/1 24 400000 +Ethernet105 33,34,35,36,37,38,39,40 fourHundredGigE0/2 25 400000 +Ethernet113 65,66,67,68,69,70,71,72 fourHundredGigE0/3 26 400000 +Ethernet121 73,74,75,76,77,78,79,80 fourHundredGigE0/4 27 400000 +Ethernet129 105,106,107,108,109,110,111,112 fourHundredGigE0/5 28 400000 +Ethernet137 113,114,115,116,117,118,119,120 fourHundredGigE0/6 29 400000 +Ethernet145 121,122,123,124,125,126,127,128 fourHundredGigE0/7 30 400000 +Ethernet153 129,130,131,132,133,134,135,136 fourHundredGigE0/8 31 400000 diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/M2-W6520-24DC8QC/sai.profile b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/M2-W6520-24DC8QC/sai.profile new file mode 100644 index 000000000000..4b3cbf7154af --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/M2-W6520-24DC8QC/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td4-m2-w6520-24dc8qc-24x200G+8x400G.yml diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/M2-W6520-24DC8QC/td4-m2-w6520-24dc8qc-24x200G+8x400G-copper.yml b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/M2-W6520-24DC8QC/td4-m2-w6520-24dc8qc-24x200G+8x400G-copper.yml new file mode 100644 index 000000000000..8a7c7a7e9fbc --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/M2-W6520-24DC8QC/td4-m2-w6520-24dc8qc-24x200G+8x400G-copper.yml @@ -0,0 +1,4114 @@ +--- +bcm_device: + 0: + global: + bcm_tunnel_term_compatible_mode: 1 + vlan_flooding_l2mc_num_reserved: 2048 + l3_alpm_template: 2 + l3_alpm2_bnk_threshold: 100 + uft_mode: 1 + l3_enable: 1 + l2_hitbit_enable: 0 + pktio_mode: 1 + warmboot_knet_shutdown_mode: 1 + sai_optimized_mmu: 1 + sai_pfc_defaults_disable: 1 + sai_postinit_cmd_file: /usr/share/sonic/platform/postinit_cmd_file.soc +... + +--- +bcm_device: + 0: + port: + 11: + dport_map_port: 1 + 12: + dport_map_port: 2 + 13: + dport_map_port: 3 + 14: + dport_map_port: 4 + 20: + dport_map_port: 5 + 21: + dport_map_port: 6 + 22: + dport_map_port: 7 + 23: + dport_map_port: 8 + 24: + dport_map_port: 9 + 25: + dport_map_port: 10 + 26: + dport_map_port: 11 + 27: + dport_map_port: 12 + 28: + dport_map_port: 13 + 29: + dport_map_port: 14 + 30: + dport_map_port: 15 + 31: + dport_map_port: 16 + 3: + dport_map_port: 17 + 4: + dport_map_port: 18 + 5: + dport_map_port: 19 + 6: + dport_map_port: 20 + 7: + dport_map_port: 21 + 8: + dport_map_port: 22 + 9: + dport_map_port: 23 + 10: + dport_map_port: 24 + 40: + dport_map_port: 25 + 41: + dport_map_port: 26 + 42: + dport_map_port: 27 + 43: + dport_map_port: 28 + 44: + dport_map_port: 29 + 45: + dport_map_port: 30 + 46: + dport_map_port: 31 + 47: + dport_map_port: 32 + 48: + dport_map_port: 33 + 49: + dport_map_port: 34 + 50: + dport_map_port: 35 + 51: + dport_map_port: 36 + 64: + dport_map_port: 37 + 65: + dport_map_port: 38 + 66: + dport_map_port: 39 + 67: + dport_map_port: 40 + 68: + dport_map_port: 41 + 69: + dport_map_port: 42 + 70: + dport_map_port: 43 + 71: + dport_map_port: 44 + 72: + dport_map_port: 45 + 73: + dport_map_port: 46 + 74: + dport_map_port: 47 + 75: + dport_map_port: 48 + 1: + dport_map_port: 49 + 2: + dport_map_port: 50 + 15: + dport_map_port: 51 + 16: + dport_map_port: 52 + 32: + dport_map_port: 53 + 33: + dport_map_port: 54 + 34: + dport_map_port: 55 + 35: + dport_map_port: 56 + 52: + dport_map_port: 57 + 53: + dport_map_port: 58 + 54: + dport_map_port: 59 + 55: + dport_map_port: 60 + 60: + dport_map_port: 61 + 61: + dport_map_port: 62 + 62: + dport_map_port: 63 + 63: + dport_map_port: 64 +... + +--- +device: + 0: + DEVICE_CONFIG: + # CORE CLOCK FREQUENCY + CORE_CLK_FREQ: CLK_1350MHZ + # PP CLOCK FREQUENCY + PP_CLK_FREQ: CLK_1350MHZ +... + +--- +device: + 0: + PC_PM_CORE: + ? + PC_PM_ID: 1 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x73510624 + RX_LANE_MAP: 0x46270513 + TX_POLARITY_FLIP: 0xa + RX_POLARITY_FLIP: 0x17 + ? + PC_PM_ID: 2 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x52317046 + RX_LANE_MAP: 0x31247056 + TX_POLARITY_FLIP: 0x90 + RX_POLARITY_FLIP: 0x47 + ? + PC_PM_ID: 3 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23104567 + RX_LANE_MAP: 0x64752310 + TX_POLARITY_FLIP: 0x29 + RX_POLARITY_FLIP: 0x5a + ? + PC_PM_ID: 4 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23104567 + RX_LANE_MAP: 0x64752310 + TX_POLARITY_FLIP: 0x29 + RX_POLARITY_FLIP: 0x5a + ? + PC_PM_ID: 5 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x25047361 + RX_LANE_MAP: 0x10452736 + TX_POLARITY_FLIP: 0xf5 + RX_POLARITY_FLIP: 0xc0 + ? + PC_PM_ID: 6 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45763210 + RX_LANE_MAP: 0x13026457 + TX_POLARITY_FLIP: 0xa + RX_POLARITY_FLIP: 0xf9 + ? + PC_PM_ID: 7 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45763210 + RX_LANE_MAP: 0x13026457 + TX_POLARITY_FLIP: 0xa + RX_POLARITY_FLIP: 0xf9 + ? + PC_PM_ID: 8 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45673210 + RX_LANE_MAP: 0x13026457 + TX_POLARITY_FLIP: 0x4a + RX_POLARITY_FLIP: 0xf3 + ? + PC_PM_ID: 9 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02476531 + RX_LANE_MAP: 0x05261734 + TX_POLARITY_FLIP: 0xdf + RX_POLARITY_FLIP: 0x84 + ? + PC_PM_ID: 10 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x37065241 + RX_LANE_MAP: 0x04175263 + TX_POLARITY_FLIP: 0x36 + RX_POLARITY_FLIP: 0x39 + ? + PC_PM_ID: 11 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x54762301 + RX_LANE_MAP: 0x13025467 + TX_POLARITY_FLIP: 0x70 + RX_POLARITY_FLIP: 0x6f + ? + PC_PM_ID: 12 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x73125046 + RX_LANE_MAP: 0x21437056 + TX_POLARITY_FLIP: 0x78 + RX_POLARITY_FLIP: 0x5c + ? + PC_PM_ID: 13 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x32104567 + RX_LANE_MAP: 0x64572310 + TX_POLARITY_FLIP: 0xd6 + RX_POLARITY_FLIP: 0xad + ? + PC_PM_ID: 14 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x03172465 + RX_LANE_MAP: 0x45173620 + TX_POLARITY_FLIP: 0xed + RX_POLARITY_FLIP: 0x36 + ? + PC_PM_ID: 15 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x36175042 + RX_LANE_MAP: 0x04176253 + TX_POLARITY_FLIP: 0x10 + RX_POLARITY_FLIP: 0xfa + ? + PC_PM_ID: 16 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x74615203 + RX_LANE_MAP: 0x51704236 + TX_POLARITY_FLIP: 0x5f + RX_POLARITY_FLIP: 0x56 + ? + PC_PM_ID: 17 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x26374051 + RX_LANE_MAP: 0x37046251 + TX_POLARITY_FLIP: 0xaa + RX_POLARITY_FLIP: 0x21 + ? + PC_PM_ID: 18 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45672310 + RX_LANE_MAP: 0x32105476 + TX_POLARITY_FLIP: 0x15 + RX_POLARITY_FLIP: 0x92 + ? + PC_PM_ID: 19 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x70465321 + RX_LANE_MAP: 0x63107542 + TX_POLARITY_FLIP: 0xe6 + RX_POLARITY_FLIP: 0xf2 + ? + PC_PM_ID: 20 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23015476 + RX_LANE_MAP: 0x64752301 + TX_POLARITY_FLIP: 0x50 + RX_POLARITY_FLIP: 0x6c +... + +--- +device: + 0: + PC_PORT_PHYS_MAP: + ? + # CPU port + PORT_ID: 0 + : + PC_PHYS_PORT_ID: 0 + ? + PORT_ID: 1 + : + PC_PHYS_PORT_ID: 1 + ? + PORT_ID: 3 + : + PC_PHYS_PORT_ID: 9 + ? + PORT_ID: 5 + : + PC_PHYS_PORT_ID: 13 + ? + PORT_ID: 7 + : + PC_PHYS_PORT_ID: 17 + ? + PORT_ID: 9 + : + PC_PHYS_PORT_ID: 21 + ? + PORT_ID: 11 + : + PC_PHYS_PORT_ID: 25 + ? + PORT_ID: 13 + : + PC_PHYS_PORT_ID: 29 + ? + PORT_ID: 15 + : + PC_PHYS_PORT_ID: 33 + ? + PORT_ID: 20 + : + PC_PHYS_PORT_ID: 41 + ? + PORT_ID: 22 + : + PC_PHYS_PORT_ID: 45 + ? + PORT_ID: 24 + : + PC_PHYS_PORT_ID: 49 + ? + PORT_ID: 26 + : + PC_PHYS_PORT_ID: 53 + ? + PORT_ID: 28 + : + PC_PHYS_PORT_ID: 57 + ? + PORT_ID: 30 + : + PC_PHYS_PORT_ID: 61 + ? + PORT_ID: 32 + : + PC_PHYS_PORT_ID: 65 + ? + PORT_ID: 34 + : + PC_PHYS_PORT_ID: 73 + ? + PORT_ID: 40 + : + PC_PHYS_PORT_ID: 81 + ? + PORT_ID: 42 + : + PC_PHYS_PORT_ID: 85 + ? + PORT_ID: 44 + : + PC_PHYS_PORT_ID: 89 + ? + PORT_ID: 46 + : + PC_PHYS_PORT_ID: 93 + ? + PORT_ID: 48 + : + PC_PHYS_PORT_ID: 97 + ? + PORT_ID: 50 + : + PC_PHYS_PORT_ID: 101 + ? + PORT_ID: 52 + : + PC_PHYS_PORT_ID: 105 + ? + PORT_ID: 54 + : + PC_PHYS_PORT_ID: 113 + ? + PORT_ID: 60 + : + PC_PHYS_PORT_ID: 121 + ? + PORT_ID: 62 + : + PC_PHYS_PORT_ID: 129 + ? + PORT_ID: 64 + : + PC_PHYS_PORT_ID: 137 + ? + PORT_ID: 66 + : + PC_PHYS_PORT_ID: 141 + ? + PORT_ID: 68 + : + PC_PHYS_PORT_ID: 145 + ? + PORT_ID: 70 + : + PC_PHYS_PORT_ID: 149 + ? + PORT_ID: 72 + : + PC_PHYS_PORT_ID: 153 + ? + PORT_ID: 74 + : + PC_PHYS_PORT_ID: 157 + +... + +--- +device: + 0: + PC_PORT: + ? + PORT_ID: 0 + : + ENABLE: 1 + SPEED: 10000 + NUM_LANES: 1 + ? + PORT_ID: [3, 5, 7, 9, 11, 13, + 20, 22, 24, 26, 28, 30, + 40, 42, 44, 46, 48, 50, + 64, 66, 68, 70, 72, 74] + : + ENABLE: 0 + SPEED: 200000 + FEC_MODE: PC_FEC_RS544_2XN + NUM_LANES: 4 + LINK_TRAINING: 0 + MAX_FRAME_SIZE: 9416 + ? + PORT_ID: [1, 15, 32, 34, 52, 54, 60, 62] + : + ENABLE: 0 + SPEED: 400000 + FEC_MODE: PC_FEC_RS544_2XN + NUM_LANES: 8 + LINK_TRAINING: 0 + MAX_FRAME_SIZE: 9416 + +... + +--- +device: + 0: + TM_SCHEDULER_CONFIG: + NUM_MC_Q: NUM_MC_Q_4 +... + +--- +device: + 0: + PC_TX_TAPS: + ? + PORT_ID: 11 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 11 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 11 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 11 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 13 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 13 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 13 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 13 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 20 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 20 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 20 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 20 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 22 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 22 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 22 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 22 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 24 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 24 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 24 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 24 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 26 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 26 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 26 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 26 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 28 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 28 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 28 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 28 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 30 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 30 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 30 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 30 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 3 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 3 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 3 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 3 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 5 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 5 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 5 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 5 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 7 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 7 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 7 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 7 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 9 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 9 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 9 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 9 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 40 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 40 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 40 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 40 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 42 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 42 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 42 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 42 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 44 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 44 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 44 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 44 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 46 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 46 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 46 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 46 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 48 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 48 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 48 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 48 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 50 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 50 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 140 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 24 + TX_PRE_SIGN: 1 + TX_PRE2: 2 + ? + PORT_ID: 50 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 50 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 64 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 64 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 64 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 64 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 66 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 66 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 66 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 66 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 68 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 68 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 68 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 68 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 70 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 70 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 70 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 70 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 72 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 72 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 72 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 72 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 74 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 74 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 74 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 74 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 1 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 1 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 1 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 1 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 1 + LANE_INDEX: [4] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 1 + LANE_INDEX: [5] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 1 + LANE_INDEX: [6] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 1 + LANE_INDEX: [7] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 15 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 15 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 15 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 15 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 15 + LANE_INDEX: [4] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 15 + LANE_INDEX: [5] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 15 + LANE_INDEX: [6] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 15 + LANE_INDEX: [7] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 32 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 32 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 32 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 32 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 32 + LANE_INDEX: [4] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 32 + LANE_INDEX: [5] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 32 + LANE_INDEX: [6] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 32 + LANE_INDEX: [7] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 34 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 34 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 34 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 34 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 34 + LANE_INDEX: [4] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 34 + LANE_INDEX: [5] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 34 + LANE_INDEX: [6] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 34 + LANE_INDEX: [7] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 52 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 52 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 52 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 52 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 52 + LANE_INDEX: [4] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 52 + LANE_INDEX: [5] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 52 + LANE_INDEX: [6] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 52 + LANE_INDEX: [7] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 54 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 54 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 54 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 54 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 54 + LANE_INDEX: [4] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 54 + LANE_INDEX: [5] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 54 + LANE_INDEX: [6] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 54 + LANE_INDEX: [7] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 60 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 60 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 60 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 60 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 60 + LANE_INDEX: [4] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 60 + LANE_INDEX: [5] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 60 + LANE_INDEX: [6] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 60 + LANE_INDEX: [7] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 62 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 62 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 62 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 62 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 62 + LANE_INDEX: [4] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 62 + LANE_INDEX: [5] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 62 + LANE_INDEX: [6] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 + ? + PORT_ID: 62 + LANE_INDEX: [7] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 28 + TX_PRE_SIGN: 1 + TX_PRE2: 6 +... diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/M2-W6520-24DC8QC/td4-m2-w6520-24dc8qc-24x200G+8x400G.yml b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/M2-W6520-24DC8QC/td4-m2-w6520-24dc8qc-24x200G+8x400G.yml new file mode 100644 index 000000000000..779f4b79d1b9 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/M2-W6520-24DC8QC/td4-m2-w6520-24dc8qc-24x200G+8x400G.yml @@ -0,0 +1,4125 @@ +--- +bcm_device: + 0: + global: + bcm_tunnel_term_compatible_mode: 1 + vlan_flooding_l2mc_num_reserved: 0 + shared_block_mask_section: uc_bc + l3_alpm_template: 2 + l3_alpm2_bnk_threshold: 100 + svi_my_station_optimization: 1 + sai_nbr_bcast_ifp_optimized: 2 + uft_mode: 1 + l3_enable: 1 + l2_hitbit_enable: 0 + pktio_mode: 1 + sai_optimized_mmu: 1 + sai_pfc_defaults_disable: 1 + warmboot_knet_shutdown_mode: 1 + sai_postinit_cmd_file: /usr/share/sonic/platform/postinit_cmd_file.soc +... + +--- +device: + 0: + FP_CONFIG: + #FP_ING_OPERMODE: PIPE_UNIQUE + FP_ING_OPERMODE: GLOBAL_PIPE_AWARE +... + +--- +bcm_device: + 0: + port: + 11: + dport_map_port: 1 + 12: + dport_map_port: 2 + 13: + dport_map_port: 3 + 14: + dport_map_port: 4 + 20: + dport_map_port: 5 + 21: + dport_map_port: 6 + 22: + dport_map_port: 7 + 23: + dport_map_port: 8 + 24: + dport_map_port: 9 + 25: + dport_map_port: 10 + 26: + dport_map_port: 11 + 27: + dport_map_port: 12 + 28: + dport_map_port: 13 + 29: + dport_map_port: 14 + 30: + dport_map_port: 15 + 31: + dport_map_port: 16 + 3: + dport_map_port: 17 + 4: + dport_map_port: 18 + 5: + dport_map_port: 19 + 6: + dport_map_port: 20 + 7: + dport_map_port: 21 + 8: + dport_map_port: 22 + 9: + dport_map_port: 23 + 10: + dport_map_port: 24 + 40: + dport_map_port: 25 + 41: + dport_map_port: 26 + 42: + dport_map_port: 27 + 43: + dport_map_port: 28 + 44: + dport_map_port: 29 + 45: + dport_map_port: 30 + 46: + dport_map_port: 31 + 47: + dport_map_port: 32 + 48: + dport_map_port: 33 + 49: + dport_map_port: 34 + 50: + dport_map_port: 35 + 51: + dport_map_port: 36 + 64: + dport_map_port: 37 + 65: + dport_map_port: 38 + 66: + dport_map_port: 39 + 67: + dport_map_port: 40 + 68: + dport_map_port: 41 + 69: + dport_map_port: 42 + 70: + dport_map_port: 43 + 71: + dport_map_port: 44 + 72: + dport_map_port: 45 + 73: + dport_map_port: 46 + 74: + dport_map_port: 47 + 75: + dport_map_port: 48 + 1: + dport_map_port: 49 + 2: + dport_map_port: 50 + 15: + dport_map_port: 51 + 16: + dport_map_port: 52 + 32: + dport_map_port: 53 + 33: + dport_map_port: 54 + 34: + dport_map_port: 55 + 35: + dport_map_port: 56 + 52: + dport_map_port: 57 + 53: + dport_map_port: 58 + 54: + dport_map_port: 59 + 55: + dport_map_port: 60 + 60: + dport_map_port: 61 + 61: + dport_map_port: 62 + 62: + dport_map_port: 63 + 63: + dport_map_port: 64 +... + +--- +device: + 0: + DEVICE_CONFIG: + # CORE CLOCK FREQUENCY + CORE_CLK_FREQ: CLK_1350MHZ + # PP CLOCK FREQUENCY + PP_CLK_FREQ: CLK_1350MHZ +... + +--- +device: + 0: + PC_PM_CORE: + ? + PC_PM_ID: 1 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x73510624 + RX_LANE_MAP: 0x46270513 + TX_POLARITY_FLIP: 0xa + RX_POLARITY_FLIP: 0x17 + ? + PC_PM_ID: 2 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x52317046 + RX_LANE_MAP: 0x31247056 + TX_POLARITY_FLIP: 0x90 + RX_POLARITY_FLIP: 0x47 + ? + PC_PM_ID: 3 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23104567 + RX_LANE_MAP: 0x64752310 + TX_POLARITY_FLIP: 0x29 + RX_POLARITY_FLIP: 0x5a + ? + PC_PM_ID: 4 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23104567 + RX_LANE_MAP: 0x64752310 + TX_POLARITY_FLIP: 0x29 + RX_POLARITY_FLIP: 0x5a + ? + PC_PM_ID: 5 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x25047361 + RX_LANE_MAP: 0x10452736 + TX_POLARITY_FLIP: 0xf5 + RX_POLARITY_FLIP: 0xc0 + ? + PC_PM_ID: 6 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45763210 + RX_LANE_MAP: 0x13026457 + TX_POLARITY_FLIP: 0xa + RX_POLARITY_FLIP: 0xf9 + ? + PC_PM_ID: 7 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45763210 + RX_LANE_MAP: 0x13026457 + TX_POLARITY_FLIP: 0xa + RX_POLARITY_FLIP: 0xf9 + ? + PC_PM_ID: 8 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45673210 + RX_LANE_MAP: 0x13026457 + TX_POLARITY_FLIP: 0x4a + RX_POLARITY_FLIP: 0xf3 + ? + PC_PM_ID: 9 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x02476531 + RX_LANE_MAP: 0x05261734 + TX_POLARITY_FLIP: 0xdf + RX_POLARITY_FLIP: 0x84 + ? + PC_PM_ID: 10 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x37065241 + RX_LANE_MAP: 0x04175263 + TX_POLARITY_FLIP: 0x36 + RX_POLARITY_FLIP: 0x39 + ? + PC_PM_ID: 11 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x54762301 + RX_LANE_MAP: 0x13025467 + TX_POLARITY_FLIP: 0x70 + RX_POLARITY_FLIP: 0x6f + ? + PC_PM_ID: 12 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x73125046 + RX_LANE_MAP: 0x21437056 + TX_POLARITY_FLIP: 0x78 + RX_POLARITY_FLIP: 0x5c + ? + PC_PM_ID: 13 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x32104567 + RX_LANE_MAP: 0x64572310 + TX_POLARITY_FLIP: 0xd6 + RX_POLARITY_FLIP: 0xad + ? + PC_PM_ID: 14 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x03172465 + RX_LANE_MAP: 0x45173620 + TX_POLARITY_FLIP: 0xed + RX_POLARITY_FLIP: 0x36 + ? + PC_PM_ID: 15 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x36175042 + RX_LANE_MAP: 0x04176253 + TX_POLARITY_FLIP: 0x10 + RX_POLARITY_FLIP: 0xfa + ? + PC_PM_ID: 16 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x74615203 + RX_LANE_MAP: 0x51704236 + TX_POLARITY_FLIP: 0x5f + RX_POLARITY_FLIP: 0x56 + ? + PC_PM_ID: 17 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x26374051 + RX_LANE_MAP: 0x37046251 + TX_POLARITY_FLIP: 0xaa + RX_POLARITY_FLIP: 0x21 + ? + PC_PM_ID: 18 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x45672310 + RX_LANE_MAP: 0x32105476 + TX_POLARITY_FLIP: 0x15 + RX_POLARITY_FLIP: 0x92 + ? + PC_PM_ID: 19 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x70465321 + RX_LANE_MAP: 0x63107542 + TX_POLARITY_FLIP: 0xe6 + RX_POLARITY_FLIP: 0xf2 + ? + PC_PM_ID: 20 + CORE_INDEX: 0 + : + TX_LANE_MAP_AUTO: 0 + RX_LANE_MAP_AUTO: 0 + TX_POLARITY_FLIP_AUTO: 0 + RX_POLARITY_FLIP_AUTO: 0 + TX_LANE_MAP: 0x23015476 + RX_LANE_MAP: 0x64752301 + TX_POLARITY_FLIP: 0x50 + RX_POLARITY_FLIP: 0x6c +... + +--- +device: + 0: + PC_PORT_PHYS_MAP: + ? + # CPU port + PORT_ID: 0 + : + PC_PHYS_PORT_ID: 0 + ? + PORT_ID: 1 + : + PC_PHYS_PORT_ID: 1 + ? + PORT_ID: 3 + : + PC_PHYS_PORT_ID: 9 + ? + PORT_ID: 5 + : + PC_PHYS_PORT_ID: 13 + ? + PORT_ID: 7 + : + PC_PHYS_PORT_ID: 17 + ? + PORT_ID: 9 + : + PC_PHYS_PORT_ID: 21 + ? + PORT_ID: 11 + : + PC_PHYS_PORT_ID: 25 + ? + PORT_ID: 13 + : + PC_PHYS_PORT_ID: 29 + ? + PORT_ID: 15 + : + PC_PHYS_PORT_ID: 33 + ? + PORT_ID: 20 + : + PC_PHYS_PORT_ID: 41 + ? + PORT_ID: 22 + : + PC_PHYS_PORT_ID: 45 + ? + PORT_ID: 24 + : + PC_PHYS_PORT_ID: 49 + ? + PORT_ID: 26 + : + PC_PHYS_PORT_ID: 53 + ? + PORT_ID: 28 + : + PC_PHYS_PORT_ID: 57 + ? + PORT_ID: 30 + : + PC_PHYS_PORT_ID: 61 + ? + PORT_ID: 32 + : + PC_PHYS_PORT_ID: 65 + ? + PORT_ID: 34 + : + PC_PHYS_PORT_ID: 73 + ? + PORT_ID: 40 + : + PC_PHYS_PORT_ID: 81 + ? + PORT_ID: 42 + : + PC_PHYS_PORT_ID: 85 + ? + PORT_ID: 44 + : + PC_PHYS_PORT_ID: 89 + ? + PORT_ID: 46 + : + PC_PHYS_PORT_ID: 93 + ? + PORT_ID: 48 + : + PC_PHYS_PORT_ID: 97 + ? + PORT_ID: 50 + : + PC_PHYS_PORT_ID: 101 + ? + PORT_ID: 52 + : + PC_PHYS_PORT_ID: 105 + ? + PORT_ID: 54 + : + PC_PHYS_PORT_ID: 113 + ? + PORT_ID: 60 + : + PC_PHYS_PORT_ID: 121 + ? + PORT_ID: 62 + : + PC_PHYS_PORT_ID: 129 + ? + PORT_ID: 64 + : + PC_PHYS_PORT_ID: 137 + ? + PORT_ID: 66 + : + PC_PHYS_PORT_ID: 141 + ? + PORT_ID: 68 + : + PC_PHYS_PORT_ID: 145 + ? + PORT_ID: 70 + : + PC_PHYS_PORT_ID: 149 + ? + PORT_ID: 72 + : + PC_PHYS_PORT_ID: 153 + ? + PORT_ID: 74 + : + PC_PHYS_PORT_ID: 157 + +... + +--- +device: + 0: + PC_PORT: + ? + PORT_ID: 0 + : + ENABLE: 1 + SPEED: 10000 + NUM_LANES: 1 + ? + PORT_ID: [3, 5, 7, 9, 11, 13, + 20, 22, 24, 26, 28, 30, + 40, 42, 44, 46, 48, 50, + 64, 66, 68, 70, 72, 74] + : + ENABLE: 0 + SPEED: 200000 + FEC_MODE: PC_FEC_RS544_2XN + NUM_LANES: 4 + LINK_TRAINING: 0 + MAX_FRAME_SIZE: 9416 + ? + PORT_ID: [1, 15, 32, 34, 52, 54, 60, 62] + : + ENABLE: 0 + SPEED: 400000 + FEC_MODE: PC_FEC_RS544_2XN + NUM_LANES: 8 + LINK_TRAINING: 0 + MAX_FRAME_SIZE: 9416 + +... + +--- +device: + 0: + TM_SCHEDULER_CONFIG: + NUM_MC_Q: NUM_MC_Q_4 +... + +--- +device: + 0: + PC_TX_TAPS: + ? + PORT_ID: 11 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 14 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 11 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 11 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 11 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 13 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 13 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 13 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 13 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 20 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 20 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 20 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 20 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 22 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 22 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 22 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 22 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 24 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 24 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 24 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 24 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 26 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 26 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 26 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 26 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 28 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 28 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 28 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 28 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 30 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 30 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 30 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 30 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 3 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 3 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 3 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 3 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 5 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 5 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 5 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 5 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 7 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 7 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 7 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 7 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 9 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 9 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 9 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 9 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 40 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 40 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 40 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 40 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 42 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 42 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 42 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 42 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 44 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 44 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 44 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 44 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 46 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 46 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 46 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 46 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 48 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 48 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 48 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 48 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 50 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 50 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 50 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 50 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 64 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 64 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 64 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 4 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 64 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 66 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 66 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 66 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 66 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 68 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 68 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 16 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 68 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 68 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 16 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 70 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 70 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 70 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 70 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 72 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 72 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 72 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 72 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 74 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 74 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 74 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 74 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 1 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 1 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 148 + TX_POST: 0 + TX_POST_SIGN: 0 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 1 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 1 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 1 + LANE_INDEX: [4] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 1 + LANE_INDEX: [5] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 1 + LANE_INDEX: [6] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 124 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 1 + LANE_INDEX: [7] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 15 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 15 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 15 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 15 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 15 + LANE_INDEX: [4] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 15 + LANE_INDEX: [5] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 15 + LANE_INDEX: [6] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 15 + LANE_INDEX: [7] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 32 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 32 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 32 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 32 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 32 + LANE_INDEX: [4] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 32 + LANE_INDEX: [5] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 32 + LANE_INDEX: [6] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 32 + LANE_INDEX: [7] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 34 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 34 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 34 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 34 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 34 + LANE_INDEX: [4] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 34 + LANE_INDEX: [5] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 34 + LANE_INDEX: [6] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 34 + LANE_INDEX: [7] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 52 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 52 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 52 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 52 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 52 + LANE_INDEX: [4] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 52 + LANE_INDEX: [5] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 52 + LANE_INDEX: [6] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 52 + LANE_INDEX: [7] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 54 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 54 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 54 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 54 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 54 + LANE_INDEX: [4] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 54 + LANE_INDEX: [5] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 54 + LANE_INDEX: [6] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 54 + LANE_INDEX: [7] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 60 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 60 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 60 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 60 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 60 + LANE_INDEX: [4] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 132 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 60 + LANE_INDEX: [5] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 60 + LANE_INDEX: [6] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 60 + LANE_INDEX: [7] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 62 + LANE_INDEX: [0] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 62 + LANE_INDEX: [1] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 62 + LANE_INDEX: [2] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 62 + LANE_INDEX: [3] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 62 + LANE_INDEX: [4] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 62 + LANE_INDEX: [5] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 144 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 62 + LANE_INDEX: [6] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 124 + TX_POST: 8 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 8 + TX_PRE_SIGN: 1 + TX_PRE2: 0 + ? + PORT_ID: 62 + LANE_INDEX: [7] + : + TX_SIG_MODE: PC_SIG_MODE_PAM4 + TX_POST_AUTO: 0 + TX_MAIN_AUTO: 0 + TX_PRE_AUTO: 0 + TX_PRE2_AUTO: 0 + TX_POST2_AUTO: 0 + TX_POST3_AUTO: 0 + TX_AMP_AUTO: 0 + TX_MAIN: 136 + TX_POST: 12 + TX_POST_SIGN: 1 + TX_POST2: 0 + TX_POST2_SIGN: 0 + TX_POST3: 0 + TX_POST3_SIGN: 0 + TX_PRE: 12 + TX_PRE_SIGN: 1 + TX_PRE2: 0 +... diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/cpu.cint b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/cpu.cint new file mode 100644 index 000000000000..e286d3cf42a6 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/cpu.cint @@ -0,0 +1,85 @@ +cint_reset(); + +int cint_field_group_create(int unit, bcm_field_group_t grp) +{ + int rv; + + bcm_field_qset_t qset; + bcm_field_aset_t aset; + + BCM_FIELD_QSET_INIT(qset); + BCM_FIELD_QSET_ADD(qset,bcmFieldQualifyDstMac); + BCM_FIELD_QSET_ADD(qset, bcmFieldQualifyStageIngress); + + BCM_FIELD_ASET_INIT(aset); + BCM_FIELD_ASET_ADD(aset, bcmFieldActionCopyToCpu); + + rv = bcm_field_group_create_mode_id(unit, qset, 103, bcmFieldGroupModeAuto, grp); + if (rv != BCM_E_NONE) { + printf("bcm_field_group_create_mode_id failed, rv = %d\r\n", rv); + return -1; + } + printf("cint_field_group_create success!!!, rv = %d\r\n", rv); + + bcm_field_group_dump(unit,grp); + return 0; +} + +int cint_field_entry_create1(int unit, bcm_field_group_t grp,bcm_field_entry_t entry) +{ + int rv; + bcm_mac_t dst_mac = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + bcm_mac_t mac_mask = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + + rv = bcm_field_entry_create_id(unit, grp, entry); + if (rv != BCM_E_NONE) { + printf("bcm_field_entry_create_id failed, rv = %d\r\n", rv); + return -1; + } + + + rv =bcm_field_qualify_DstMac(unit, entry, dst_mac, mac_mask); + if (rv != BCM_E_NONE) { + printf("bcm_field_qualify_DstMac failed,ret = %d\r\n", rv); + bcm_field_entry_destroy(unit, entry); + return -1; + } + + rv = bcm_field_action_add(unit, entry, bcmFieldActionCopyToCpu, 1, 0); + if (rv != BCM_E_NONE) { + printf("bcm_field_action_add failed, rv = %d \r\n", rv); + bcm_field_entry_destroy(unit, entry); + return -1; + } + + rv = bcm_field_action_add(unit, entry, bcmFieldActionDrop, 1, 0); + if (rv != BCM_E_NONE) { + printf("bcm_field_action_add failed, rv = %d \r\n", rv); + bcm_field_entry_destroy(unit, entry); + return -1; + } + + rv = bcm_field_entry_install(unit, entry); + if (rv != BCM_E_NONE) { + printf("bcm_field_entry_install failed,ret = %d\r\n", rv); + bcm_field_entry_destroy(unit, entry); + return -1; + } + + printf("********************* BEGIN ****************************\r\n"); + bcm_field_entry_dump(unit, entry); + printf("*********************** END ****************************\r\n"); + + return 0; +} + +cint_field_group_create(0,5); +cint_field_entry_create1(0,5,2048); + +//bcm_field_entry_destroy(0, 2048); +//bcm_field_group_destroy(0, 5); + + + + + diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/custom_led.bin b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/custom_led.bin new file mode 100644 index 0000000000000000000000000000000000000000..b3185be90620437bade87ac81750977221683aea GIT binary patch literal 716 zcma)%PiPZi5XIlOo1`0Ksck82Y$9nkk*2Ff1%+s}Uy?G!mO^V$YPM=(5#rH{G@ks2 zQWK>$6?WZ<=+#SI?LoAl-l`y*dWqz+;2|fW=tc12RuDZ|55o-a%`m^WzI=vG&?pVj z`tzGhEhrOqUL4Vh#RVn6#h5|g+RUJ~O+%W@96MxM$)b*QZh`dBWw+z*i{iVf_p&*2 zpH$wJM(vF=F6Al0uM^Z(TX3K(5_%>`lUC(b3wnf$m>z0ai!|+Sh&Gfgp|`EJC9%~O z>Ow-Oi%v(vXZsYdGeMmhm1}?_C{J;zSU$!M?CD>wvAC${q>&KqR}3D4Z5; zP2wbQ<{%1X(xvm;dE(MF(p+xWF&H0{-&$j?BiYQzO5Jk967>{GyhC1dGorV}&i_(9 zf7CuVYt(BX(O!$GV%mFr + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/fru.py b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/fru.py new file mode 100644 index 000000000000..f95164e03601 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/fru.py @@ -0,0 +1,961 @@ +#!/usr/bin/python3 +import collections +from datetime import datetime, timedelta +from bitarray import bitarray + + +__DEBUG__ = "N" + + +class FruException(Exception): + def __init__(self, message='fruerror', code=-100): + err = 'errcode: {0} message:{1}'.format(code, message) + Exception.__init__(self, err) + self.code = code + self.message = message + + +def e_print(err): + print("ERROR: " + err) + + +def d_print(debug_info): + if __DEBUG__ == "Y": + print(debug_info) + + +class FruUtil(): + @staticmethod + def decodeLength(value): + a = bitarray(8) + a.setall(True) + a[0:1] = 0 + a[1:2] = 0 + x = ord(a.tobytes()) + return x & ord(value) + + @staticmethod + def minToData(): + starttime = datetime(1996, 1, 1, 0, 0, 0) + endtime = datetime.now() + seconds = (endtime - starttime).total_seconds() + mins = seconds // 60 + m = int(round(mins)) + return m + + @staticmethod + def getTimeFormat(): + return datetime.now().strftime('%Y-%m-%d') + + @staticmethod + def getTypeLength(value): + if value is None or len(value) == 0: + return 0 + a = bitarray(8) + a.setall(False) + a[0:1] = 1 + a[1:2] = 1 + x = ord(a.tobytes()) + return x | len(value) + + @staticmethod + def checksum(b): + result = 0 + for item in b: + result += ord(item) + return (0x100 - (result & 0xff)) & 0xff + + +class BaseArea(object): + SUGGESTED_SIZE_COMMON_HEADER = 8 + SUGGESTED_SIZE_INTERNAL_USE_AREA = 72 + SUGGESTED_SIZE_CHASSIS_INFO_AREA = 32 + SUGGESTED_SIZE_BOARD_INFO_AREA = 80 + SUGGESTED_SIZE_PRODUCT_INFO_AREA = 80 + + INITVALUE = b'\x00' + resultvalue = INITVALUE * 256 + COMMON_HEAD_VERSION = b'\x01' + __childList = None + + def __init__(self, name="", size=0, offset=0): + self.__childList = [] + self._offset = offset + self.name = name + self._size = size + self._isPresent = False + self._data = b'\x00' * size + + @property + def childList(self): + return self.__childList + + @childList.setter + def childList(self, value): + self.__childList = value + + @property + def offset(self): + return self._offset + + @offset.setter + def offset(self, value): + self._offset = value + + @property + def size(self): + return self._size + + @size.setter + def size(self, value): + self._size = value + + @property + def data(self): + return self._data + + @data.setter + def data(self, value): + self._data = value + + @property + def isPresent(self): + return self._isPresent + + @isPresent.setter + def isPresent(self, value): + self._isPresent = value + + +class InternalUseArea(BaseArea): + pass + + +class ChassisInfoArea(BaseArea): + pass + + +class BoardInfoArea(BaseArea): + _boardTime = None + _fields = None + _mfg_date = None + areaversion = None + _boardversion = None + _language = None + + def __str__(self): + formatstr = "version : %x\n" \ + "length : %d \n" \ + "language : %x \n" \ + "mfg_date : %s \n" \ + "boardManufacturer : %s \n" \ + "boardProductName : %s \n" \ + "boardSerialNumber : %s \n" \ + "boardPartNumber : %s \n" \ + "fruFileId : %s \n" + + tmpstr = formatstr % (ord(self.boardversion), self.size, + self.language, self.getMfgRealData(), + self.boardManufacturer, self.boardProductName, + self.boardSerialNumber, self.boardPartNumber, + self.fruFileId) + for i in range(1, 11): + valtmp = "boardextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + tmpstr += "boardextra%d : %s \n" % (i, valtmpval) + else: + break + + return tmpstr + + def todict(self): + dic = collections.OrderedDict() + dic["boardversion"] = ord(self.boardversion) + dic["boardlength"] = self.size + dic["boardlanguage"] = self.language + dic["boardmfg_date"] = self.getMfgRealData() + dic["boardManufacturer"] = self.boardManufacturer + dic["boardProductName"] = self.boardProductName + dic["boardSerialNumber"] = self.boardSerialNumber + dic["boardPartNumber"] = self.boardPartNumber + dic["boardfruFileId"] = self.fruFileId + for i in range(1, 11): + valtmp = "boardextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + dic[valtmp] = valtmpval + else: + break + return dic + + def decodedata(self): + index = 0 + self.areaversion = self.data[index] + index += 1 + d_print("decode length :%d class size:%d" % + ((ord(self.data[index]) * 8), self.size)) + index += 2 + + timetmp = self.data[index: index + 3] + self.mfg_date = ord(timetmp[0]) | ( + ord(timetmp[1]) << 8) | (ord(timetmp[2]) << 16) + d_print("decode getMfgRealData :%s" % self.getMfgRealData()) + index += 3 + + templen = FruUtil.decodeLength(self.data[index]) + self.boardManufacturer = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode boardManufacturer:%s" % self.boardManufacturer) + + templen = FruUtil.decodeLength(self.data[index]) + self.boardProductName = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode boardProductName:%s" % self.boardProductName) + + templen = FruUtil.decodeLength(self.data[index]) + self.boardSerialNumber = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode boardSerialNumber:%s" % self.boardSerialNumber) + + templen = FruUtil.decodeLength(self.data[index]) + self.boardPartNumber = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode boardPartNumber:%s" % self.boardPartNumber) + + templen = FruUtil.decodeLength(self.data[index]) + self.fruFileId = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode fruFileId:%s" % self.fruFileId) + + for i in range(1, 11): + valtmp = "boardextra%d" % i + if self.data[index] != chr(0xc1): + templen = FruUtil.decodeLength(self.data[index]) + tmpval = self.data[index + 1: index + templen + 1] + setattr(self, valtmp, tmpval) + index += templen + 1 + d_print("decode boardextra%d:%s" % (i, tmpval)) + else: + break + + def fruSetValue(self, field, value): + tmp_field = getattr(self, field, None) + if tmp_field is not None: + setattr(self, field, value) + + def recalcute(self): + d_print("boardInfoArea version:%x" % ord(self.boardversion)) + d_print("boardInfoArea length:%d" % self.size) + d_print("boardInfoArea language:%x" % self.language) + self.mfg_date = FruUtil.minToData() + d_print("boardInfoArea mfg_date:%x" % self.mfg_date) + + self.data = chr(ord(self.boardversion)) + \ + chr(self.size // 8) + chr(self.language) + + self.data += chr(self.mfg_date & 0xFF) + self.data += chr((self.mfg_date >> 8) & 0xFF) + self.data += chr((self.mfg_date >> 16) & 0xFF) + + d_print("boardInfoArea boardManufacturer:%s" % self.boardManufacturer) + typelength = FruUtil.getTypeLength(self.boardManufacturer) + self.data += chr(typelength) + self.data += self.boardManufacturer + + d_print("boardInfoArea boardProductName:%s" % self.boardProductName) + self.data += chr(FruUtil.getTypeLength(self.boardProductName)) + self.data += self.boardProductName + + d_print("boardInfoArea boardSerialNumber:%s" % self.boardSerialNumber) + self.data += chr(FruUtil.getTypeLength(self.boardSerialNumber)) + self.data += self.boardSerialNumber + + d_print("boardInfoArea boardPartNumber:%s" % self.boardPartNumber) + self.data += chr(FruUtil.getTypeLength(self.boardPartNumber)) + self.data += self.boardPartNumber + + d_print("boardInfoArea fruFileId:%s" % self.fruFileId) + self.data += chr(FruUtil.getTypeLength(self.fruFileId)) + self.data += self.fruFileId + + for i in range(1, 11): + valtmp = "boardextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + d_print("boardInfoArea boardextra%d:%s" % (i, valtmpval)) + self.data += chr(FruUtil.getTypeLength(valtmpval)) + if valtmpval is not None: + self.data += valtmpval + else: + break + + self.data += chr(0xc1) + + if len(self.data) > (self.size - 1): + incr = (len(self.data) - self.size) // 8 + 1 + self.size += incr * 8 + + self.data = self.data[0:1] + chr(self.size // 8) + self.data[2:] + d_print("self data:%d" % len(self.data)) + d_print("self size:%d" % self.size) + d_print("adjust size:%d" % (self.size - len(self.data) - 1)) + self.data = self.data.ljust((self.size - 1), chr(self.INITVALUE[0])) + + # checksum + checksum = FruUtil.checksum(self.data) + d_print("board info checksum:%x" % checksum) + self.data += chr(checksum) + + def getMfgRealData(self): + starttime = datetime(1996, 1, 1, 0, 0, 0) + mactime = starttime + timedelta(minutes=self.mfg_date) + return mactime + + @property + def language(self): + self._language = 25 + return self._language + + @property + def mfg_date(self): + return self._mfg_date + + @mfg_date.setter + def mfg_date(self, val): + self._mfg_date = val + + @property + def boardversion(self): + self._boardversion = self.COMMON_HEAD_VERSION + return self._boardversion + + @property + def fruFileId(self): + return self._FRUFileID + + @fruFileId.setter + def fruFileId(self, val): + self._FRUFileID = val + + @property + def boardPartNumber(self): + return self._boardPartNumber + + @boardPartNumber.setter + def boardPartNumber(self, val): + self._boardPartNumber = val + + @property + def boardSerialNumber(self): + return self._boardSerialNumber + + @boardSerialNumber.setter + def boardSerialNumber(self, val): + self._boardSerialNumber = val + + @property + def boardProductName(self): + return self._boradProductName + + @boardProductName.setter + def boardProductName(self, val): + self._boradProductName = val + + @property + def boardManufacturer(self): + return self._boardManufacturer + + @boardManufacturer.setter + def boardManufacturer(self, val): + self._boardManufacturer = val + + @property + def boardTime(self): + return self._boardTime + + @boardTime.setter + def boardTime(self, val): + self._boardTime = val + + @property + def fields(self): + return self._fields + + @fields.setter + def fields(self, val): + self._fields = val + + +class ProductInfoArea(BaseArea): + _productManufacturer = None + _productAssetTag = None + _FRUFileID = None + _language = None + + def __str__(self): + formatstr = "version : %x\n" \ + "length : %d \n" \ + "language : %x \n" \ + "productManufacturer : %s \n" \ + "productName : %s \n" \ + "productPartModelName: %s \n" \ + "productVersion : %s \n" \ + "productSerialNumber : %s \n" \ + "productAssetTag : %s \n" \ + "fruFileId : %s \n" + + tmpstr = formatstr % (ord(self.areaversion), self.size, + self.language, self.productManufacturer, + self.productName, self.productPartModelName, + self.productVersion, self.productSerialNumber, + self.productAssetTag, self.fruFileId) + + for i in range(1, 11): + valtmp = "productextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + tmpstr += "productextra%d : %s \n" % (i, valtmpval) + else: + break + + return tmpstr + + def todict(self): + dic = collections.OrderedDict() + dic["productversion"] = ord(self.areaversion) + dic["productlength"] = self.size + dic["productlanguage"] = self.language + dic["productManufacturer"] = self.productManufacturer + dic["productName"] = self.productName + dic["productPartModelName"] = self.productPartModelName + dic["productVersion"] = int(self.productVersion, 16) + dic["productSerialNumber"] = self.productSerialNumber + dic["productAssetTag"] = self.productAssetTag + dic["productfruFileId"] = self.fruFileId + for i in range(1, 11): + valtmp = "productextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + dic[valtmp] = valtmpval + else: + break + return dic + + def decodedata(self): + index = 0 + self.areaversion = self.data[index] # 0 + index += 1 + d_print("decode length %d" % (ord(self.data[index]) * 8)) + d_print("class size %d" % self.size) + index += 2 + + templen = FruUtil.decodeLength(self.data[index]) + self.productManufacturer = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productManufacturer:%s" % self.productManufacturer) + + templen = FruUtil.decodeLength(self.data[index]) + self.productName = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productName:%s" % self.productName) + + templen = FruUtil.decodeLength(self.data[index]) + self.productPartModelName = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productPartModelName:%s" % self.productPartModelName) + + templen = FruUtil.decodeLength(self.data[index]) + self.productVersion = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productVersion:%s" % self.productVersion) + + templen = FruUtil.decodeLength(self.data[index]) + self.productSerialNumber = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productSerialNumber:%s" % self.productSerialNumber) + + templen = FruUtil.decodeLength(self.data[index]) + self.productAssetTag = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode productAssetTag:%s" % self.productAssetTag) + + templen = FruUtil.decodeLength(self.data[index]) + self.fruFileId = self.data[index + 1: index + templen + 1] + index += templen + 1 + d_print("decode fruFileId:%s" % self.fruFileId) + + for i in range(1, 11): + valtmp = "productextra%d" % i + if self.data[index] != chr(0xc1) and index < self.size - 1: + templen = FruUtil.decodeLength(self.data[index]) + if templen == 0: + break + tmpval = self.data[index + 1: index + templen + 1] + d_print("decode boardextra%d:%s" % (i, tmpval)) + setattr(self, valtmp, tmpval) + index += templen + 1 + else: + break + + @property + def productVersion(self): + return self._productVersion + + @productVersion.setter + def productVersion(self, name): + self._productVersion = name + + @property + def areaversion(self): + self._areaversion = self.COMMON_HEAD_VERSION + return self._areaversion + + @areaversion.setter + def areaversion(self, name): + self._areaversion = name + + @property + def language(self): + self._language = 25 + return self._language + + @property + def productManufacturer(self): + return self._productManufacturer + + @productManufacturer.setter + def productManufacturer(self, name): + self._productManufacturer = name + + @property + def productName(self): + return self._productName + + @productName.setter + def productName(self, name): + self._productName = name + + @property + def productPartModelName(self): + return self._productPartModelName + + @productPartModelName.setter + def productPartModelName(self, name): + self._productPartModelName = name + + @property + def productSerialNumber(self): + return self._productSerialNumber + + @productSerialNumber.setter + def productSerialNumber(self, name): + self._productSerialNumber = name + + @property + def productAssetTag(self): + return self._productAssetTag + + @productAssetTag.setter + def productAssetTag(self, name): + self._productAssetTag = name + + @property + def fruFileId(self): + return self._FRUFileID + + @fruFileId.setter + def fruFileId(self, name): + self._FRUFileID = name + + def fruSetValue(self, field, value): + tmp_field = getattr(self, field, None) + if tmp_field is not None: + setattr(self, field, value) + + def recalcute(self): + d_print("product version:%x" % ord(self.areaversion)) + d_print("product length:%d" % self.size) + d_print("product language:%x" % self.language) + self.data = chr(ord(self.areaversion)) + \ + chr(self.size // 8) + chr(self.language) + + typelength = FruUtil.getTypeLength(self.productManufacturer) + self.data += chr(typelength) + self.data += self.productManufacturer + + self.data += chr(FruUtil.getTypeLength(self.productName)) + self.data += self.productName + + self.data += chr(FruUtil.getTypeLength(self.productPartModelName)) + self.data += self.productPartModelName + + self.data += chr(FruUtil.getTypeLength(self.productVersion)) + self.data += self.productVersion + + self.data += chr(FruUtil.getTypeLength(self.productSerialNumber)) + self.data += self.productSerialNumber + + self.data += chr(FruUtil.getTypeLength(self.productAssetTag)) + if self.productAssetTag is not None: + self.data += self.productAssetTag + + self.data += chr(FruUtil.getTypeLength(self.fruFileId)) + self.data += self.fruFileId + + for i in range(1, 11): + valtmp = "productextra%d" % i + if hasattr(self, valtmp): + valtmpval = getattr(self, valtmp) + d_print("boardInfoArea productextra%d:%s" % (i, valtmpval)) + self.data += chr(FruUtil.getTypeLength(valtmpval)) + if valtmpval is not None: + self.data += valtmpval + else: + break + + self.data += chr(0xc1) + if len(self.data) > (self.size - 1): + incr = (len(self.data) - self.size) // 8 + 1 + self.size += incr * 8 + d_print("self.data:%d" % len(self.data)) + d_print("self.size:%d" % self.size) + + self.data = self.data[0:1] + chr(self.size // 8) + self.data[2:] + self.data = self.data.ljust((self.size - 1), chr(self.INITVALUE[0])) + checksum = FruUtil.checksum(self.data) + d_print("board info checksum:%x" % checksum) + self.data += chr(checksum) + + +class MultiRecordArea(BaseArea): + pass + + +class Field(object): + + def __init__(self, fieldType="ASCII", fieldData=""): + self.fieldData = fieldData + self.fieldType = fieldType + + @property + def fieldType(self): + return self.fieldType + + @property + def fieldData(self): + return self.fieldData + + +class ipmifru(BaseArea): + _BoardInfoArea = None + _ProductInfoArea = None + _InternalUseArea = None + _ChassisInfoArea = None + _multiRecordArea = None + _productinfoAreaOffset = BaseArea.INITVALUE + _boardInfoAreaOffset = BaseArea.INITVALUE + _internalUserAreaOffset = BaseArea.INITVALUE + _chassicInfoAreaOffset = BaseArea.INITVALUE + _multiRecordAreaOffset = BaseArea.INITVALUE + _bindata = None + _bodybin = None + _version = BaseArea.COMMON_HEAD_VERSION + _zeroCheckSum = None + _frusize = 256 + + def __str__(self): + tmpstr = "" + if self.boardInfoArea.isPresent: + tmpstr += "\nboardinfoarea: \n" + tmpstr += self.boardInfoArea.__str__() + if self.productInfoArea.isPresent: + tmpstr += "\nproductinfoarea: \n" + tmpstr += self.productInfoArea.__str__() + return tmpstr + + def decodeBin(self, eeprom): + commonHead = eeprom[0:8] + d_print("decode version %x" % ord(commonHead[0])) + if ord(self.COMMON_HEAD_VERSION) != ord(commonHead[0]): + raise FruException("HEAD VERSION error,not Fru format!", -10) + if FruUtil.checksum(commonHead[0:7]) != ord(commonHead[7]): + strtemp = "check header checksum error [cal:%02x data:%02x]" % ( + FruUtil.checksum(commonHead[0:7]), ord(commonHead[7])) + raise FruException(strtemp, -3) + if ord(commonHead[1]) != ord(self.INITVALUE): + d_print("Internal Use Area is present") + self.internalUseArea = InternalUseArea( + name="Internal Use Area", size=self.SUGGESTED_SIZE_INTERNAL_USE_AREA) + self.internalUseArea.isPresent = True + self.internalUserAreaOffset = ord(commonHead[1]) + self.internalUseArea.data = eeprom[self.internalUserAreaOffset * 8: ( + self.internalUserAreaOffset * 8 + self.internalUseArea.size)] + if ord(commonHead[2]) != ord(self.INITVALUE): + d_print("Chassis Info Area is present") + self.chassisInfoArea = ChassisInfoArea( + name="Chassis Info Area", size=self.SUGGESTED_SIZE_CHASSIS_INFO_AREA) + self.chassisInfoArea.isPresent = True + self.chassicInfoAreaOffset = ord(commonHead[2]) + self.chassisInfoArea.data = eeprom[self.chassicInfoAreaOffset * 8: ( + self.chassicInfoAreaOffset * 8 + self.chassisInfoArea.size)] + if ord(commonHead[3]) != ord(self.INITVALUE): + self.boardInfoArea = BoardInfoArea( + name="Board Info Area", size=self.SUGGESTED_SIZE_BOARD_INFO_AREA) + self.boardInfoArea.isPresent = True + self.boardInfoAreaOffset = ord(commonHead[3]) + self.boardInfoArea.size = ord( + eeprom[self.boardInfoAreaOffset * 8 + 1]) * 8 + d_print("Board Info Area is present size:%d" % + (self.boardInfoArea.size)) + self.boardInfoArea.data = eeprom[self.boardInfoAreaOffset * 8: ( + self.boardInfoAreaOffset * 8 + self.boardInfoArea.size)] + if FruUtil.checksum(self.boardInfoArea.data[:-1]) != ord(self.boardInfoArea.data[-1:]): + strtmp = "check boardInfoArea checksum error[cal:%02x data:%02x]" % \ + (FruUtil.checksum( + self.boardInfoArea.data[:-1]), ord(self.boardInfoArea.data[-1:])) + raise FruException(strtmp, -3) + self.boardInfoArea.decodedata() + if ord(commonHead[4]) != ord(self.INITVALUE): + d_print("Product Info Area is present") + self.productInfoArea = ProductInfoArea( + name="Product Info Area ", size=self.SUGGESTED_SIZE_PRODUCT_INFO_AREA) + self.productInfoArea.isPresent = True + self.productinfoAreaOffset = ord(commonHead[4]) + d_print("length offset value: %02x" % + ord(eeprom[self.productinfoAreaOffset * 8 + 1])) + self.productInfoArea.size = ord( + eeprom[self.productinfoAreaOffset * 8 + 1]) * 8 + d_print("Product Info Area is present size:%d" % + (self.productInfoArea.size)) + + self.productInfoArea.data = eeprom[self.productinfoAreaOffset * 8: ( + self.productinfoAreaOffset * 8 + self.productInfoArea.size)] + if FruUtil.checksum(self.productInfoArea.data[:-1]) != ord(self.productInfoArea.data[-1:]): + strtmp = "check productInfoArea checksum error [cal:%02x data:%02x]" % ( + FruUtil.checksum(self.productInfoArea.data[:-1]), ord(self.productInfoArea.data[-1:])) + raise FruException(strtmp, -3) + self.productInfoArea.decodedata() + if ord(commonHead[5]) != ord(self.INITVALUE): + self.multiRecordArea = MultiRecordArea( + name="MultiRecord record Area ") + d_print("MultiRecord record present") + self.multiRecordArea.isPresent = True + self.multiRecordAreaOffset = ord(commonHead[5]) + self.multiRecordArea.data = eeprom[self.multiRecordAreaOffset * 8: ( + self.multiRecordAreaOffset * 8 + self.multiRecordArea.size)] + + def initDefault(self): + self.version = self.COMMON_HEAD_VERSION + self.internalUserAreaOffset = self.INITVALUE + self.chassicInfoAreaOffset = self.INITVALUE + self.boardInfoAreaOffset = self.INITVALUE + self.productinfoAreaOffset = self.INITVALUE + self.multiRecordAreaOffset = self.INITVALUE + self.zeroCheckSum = self.INITVALUE + self.offset = self.SUGGESTED_SIZE_COMMON_HEADER + self.productInfoArea = None + self.internalUseArea = None + self.boardInfoArea = None + self.chassisInfoArea = None + self.multiRecordArea = None + # self.recalcute() + + @property + def version(self): + return self._version + + @version.setter + def version(self, name): + self._version = name + + @property + def internalUserAreaOffset(self): + return self._internalUserAreaOffset + + @internalUserAreaOffset.setter + def internalUserAreaOffset(self, obj): + self._internalUserAreaOffset = obj + + @property + def chassicInfoAreaOffset(self): + return self._chassicInfoAreaOffset + + @chassicInfoAreaOffset.setter + def chassicInfoAreaOffset(self, obj): + self._chassicInfoAreaOffset = obj + + @property + def productinfoAreaOffset(self): + return self._productinfoAreaOffset + + @productinfoAreaOffset.setter + def productinfoAreaOffset(self, obj): + self._productinfoAreaOffset = obj + + @property + def boardInfoAreaOffset(self): + return self._boardInfoAreaOffset + + @boardInfoAreaOffset.setter + def boardInfoAreaOffset(self, obj): + self._boardInfoAreaOffset = obj + + @property + def multiRecordAreaOffset(self): + return self._multiRecordAreaOffset + + @multiRecordAreaOffset.setter + def multiRecordAreaOffset(self, obj): + self._multiRecordAreaOffset = obj + + @property + def zeroCheckSum(self): + return self._zeroCheckSum + + @zeroCheckSum.setter + def zeroCheckSum(self, obj): + self._zeroCheckSum = obj + + @property + def productInfoArea(self): + return self._ProductInfoArea + + @productInfoArea.setter + def productInfoArea(self, obj): + self._ProductInfoArea = obj + + @property + def internalUseArea(self): + return self._InternalUseArea + + @internalUseArea.setter + def internalUseArea(self, obj): + self.internalUseArea = obj + + @property + def boardInfoArea(self): + return self._BoardInfoArea + + @boardInfoArea.setter + def boardInfoArea(self, obj): + self._BoardInfoArea = obj + + @property + def chassisInfoArea(self): + return self._ChassisInfoArea + + @chassisInfoArea.setter + def chassisInfoArea(self, obj): + self._ChassisInfoArea = obj + + @property + def multiRecordArea(self): + return self._multiRecordArea + + @multiRecordArea.setter + def multiRecordArea(self, obj): + self._multiRecordArea = obj + + @property + def bindata(self): + return self._bindata + + @bindata.setter + def bindata(self, obj): + self._bindata = obj + + @property + def bodybin(self): + return self._bodybin + + @bodybin.setter + def bodybin(self, obj): + self._bodybin = obj + + def recalcuteCommonHead(self): + self.bindata = "" + self.offset = self.SUGGESTED_SIZE_COMMON_HEADER + d_print("common Header %d" % self.offset) + d_print("fru eeprom size %d" % self._frusize) + if self.internalUseArea is not None and self.internalUseArea.isPresent: + self.internalUserAreaOffset = self.offset // 8 + self.offset += self.internalUseArea.size + d_print("internalUseArea is present offset:%d" % self.offset) + + if self.chassisInfoArea is not None and self.chassisInfoArea.isPresent: + self.chassicInfoAreaOffset = self.offset // 8 + self.offset += self.chassisInfoArea.size + d_print("chassisInfoArea is present offset:%d" % self.offset) + + if self.boardInfoArea is not None and self.boardInfoArea.isPresent: + self.boardInfoAreaOffset = self.offset // 8 + self.offset += self.boardInfoArea.size + d_print("boardInfoArea is present offset:%d" % self.offset) + d_print("boardInfoArea is present size:%d" % + self.boardInfoArea.size) + + if self.productInfoArea is not None and self.productInfoArea.isPresent: + self.productinfoAreaOffset = self.offset // 8 + self.offset += self.productInfoArea.size + d_print("productInfoArea is present offset:%d" % self.offset) + + if self.multiRecordArea is not None and self.multiRecordArea.isPresent: + self.multiRecordAreaOffset = self.offset // 8 + d_print("multiRecordArea is present offset:%d" % self.offset) + + if self.internalUserAreaOffset == self.INITVALUE: + self.internalUserAreaOffset = 0 + if self.productinfoAreaOffset == self.INITVALUE: + self.productinfoAreaOffset = 0 + if self.chassicInfoAreaOffset == self.INITVALUE: + self.chassicInfoAreaOffset = 0 + if self.boardInfoAreaOffset == self.INITVALUE: + self.boardInfoAreaOffset = 0 + if self.multiRecordAreaOffset == self.INITVALUE: + self.multiRecordAreaOffset = 0 + + self.zeroCheckSum = (0x100 - ord(self.version) - self.internalUserAreaOffset - self.chassicInfoAreaOffset - self.productinfoAreaOffset + - self.boardInfoAreaOffset - self.multiRecordAreaOffset) & 0xff + d_print("zerochecksum:%x" % self.zeroCheckSum) + self.data = "" + self.data += chr(self.version[0]) + chr(self.internalUserAreaOffset) + chr(self.chassicInfoAreaOffset) + chr( + self.boardInfoAreaOffset) + chr(self.productinfoAreaOffset) + chr(self.multiRecordAreaOffset) + chr(self.INITVALUE[0]) + chr(self.zeroCheckSum) + + self.bindata = self.data + self.bodybin + totallen = len(self.bindata) + d_print("totallen %d" % totallen) + if totallen < self._frusize: + self.bindata = self.bindata.ljust(self._frusize, chr(self.INITVALUE[0])) + else: + raise FruException('bin data more than %d' % self._frusize, -2) + + def recalcutebin(self): + self.bodybin = "" + if self.internalUseArea is not None and self.internalUseArea.isPresent: + d_print("internalUseArea present") + self.bodybin += self.internalUseArea.data + if self.chassisInfoArea is not None and self.chassisInfoArea.isPresent: + d_print("chassisInfoArea present") + self.bodybin += self.chassisInfoArea.data + if self.boardInfoArea is not None and self.boardInfoArea.isPresent: + d_print("boardInfoArea present") + self.boardInfoArea.recalcute() + self.bodybin += self.boardInfoArea.data + if self.productInfoArea is not None and self.productInfoArea.isPresent: + d_print("productInfoAreapresent") + self.productInfoArea.recalcute() + self.bodybin += self.productInfoArea.data + if self.multiRecordArea is not None and self.multiRecordArea.isPresent: + d_print("multiRecordArea present") + self.bodybin += self.productInfoArea.data + + def recalcute(self, fru_eeprom_size=256): + self._frusize = fru_eeprom_size + self.recalcutebin() + self.recalcuteCommonHead() + + def setValue(self, area, field, value): + tmp_area = getattr(self, area, None) + if tmp_area is not None: + tmp_area.fruSetValue(field, value) diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/hwsku.json b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/hwsku.json new file mode 100644 index 000000000000..cadf2fb312eb --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/hwsku.json @@ -0,0 +1,100 @@ +{ + "interfaces": { + "Ethernet1": { + "default_brkout_mode": "1x200G" + }, + "Ethernet5": { + "default_brkout_mode": "1x200G" + }, + "Ethernet9": { + "default_brkout_mode": "1x200G" + }, + "Ethernet13": { + "default_brkout_mode": "1x200G" + }, + "Ethernet17": { + "default_brkout_mode": "1x200G" + }, + "Ethernet21": { + "default_brkout_mode": "1x200G" + }, + "Ethernet25": { + "default_brkout_mode": "1x200G" + }, + "Ethernet29": { + "default_brkout_mode": "1x200G" + }, + "Ethernet33": { + "default_brkout_mode": "1x200G" + }, + "Ethernet37": { + "default_brkout_mode": "1x200G" + }, + "Ethernet41": { + "default_brkout_mode": "1x200G" + }, + "Ethernet45": { + "default_brkout_mode": "1x200G" + }, + "Ethernet49": { + "default_brkout_mode": "1x200G" + }, + "Ethernet53": { + "default_brkout_mode": "1x200G" + }, + "Ethernet57": { + "default_brkout_mode": "1x200G" + }, + "Ethernet61": { + "default_brkout_mode": "1x200G" + }, + "Ethernet65": { + "default_brkout_mode": "1x200G" + }, + "Ethernet69": { + "default_brkout_mode": "1x200G" + }, + "Ethernet73": { + "default_brkout_mode": "1x200G" + }, + "Ethernet77": { + "default_brkout_mode": "1x200G" + }, + "Ethernet81": { + "default_brkout_mode": "1x200G" + }, + "Ethernet85": { + "default_brkout_mode": "1x200G" + }, + "Ethernet89": { + "default_brkout_mode": "1x200G" + }, + "Ethernet93": { + "default_brkout_mode": "1x200G" + }, + "Ethernet97": { + "default_brkout_mode": "1x400G" + }, + "Ethernet105": { + "default_brkout_mode": "1x400G" + }, + "Ethernet113": { + "default_brkout_mode": "1x400G" + }, + "Ethernet121": { + "default_brkout_mode": "1x400G" + }, + "Ethernet129": { + "default_brkout_mode": "1x400G" + }, + "Ethernet137": { + "default_brkout_mode": "1x400G" + }, + "Ethernet145": { + "default_brkout_mode": "1x400G" + }, + "Ethernet153": { + "default_brkout_mode": "1x400G" + } + } +} diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/installer.conf b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/installer.conf new file mode 100644 index 000000000000..7a9fec8cc99c --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/installer.conf @@ -0,0 +1,2 @@ +CONSOLE_SPEED=115200 +ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="intel_idle.max_cstate=0 idle=poll" \ No newline at end of file diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/media_settings.json b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/media_settings.json new file mode 100644 index 000000000000..1d7f598d2fe8 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/media_settings.json @@ -0,0 +1,1476 @@ +{ + "PORT_MEDIA_SETTINGS": { + "0": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090" + }, + "post1": { + "lane0": "0xfffffff2", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "1": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "2": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "3": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000088", + "lane2": "0x00000088", + "lane3": "0x00000090" + }, + "post1": { + "lane0": "0xfffffff8", + "lane1": "0xfffffff8", + "lane2": "0xfffffff8", + "lane3": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "4": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "5": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "6": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "7": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000088", + "lane2": "0x00000088", + "lane3": "0x00000088" + }, + "post1": { + "lane0": "0xfffffff8", + "lane1": "0xfffffff8", + "lane2": "0xfffffff8", + "lane3": "0xfffffff8" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "8": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000088" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "9": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000088", + "lane2": "0x00000090", + "lane3": "0x00000090" + }, + "post1": { + "lane0": "0xfffffff8", + "lane1": "0xfffffff8", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "10": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000088", + "lane2": "0x00000088", + "lane3": "0x00000088" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "11": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff8", + "lane1": "0xfffffff8", + "lane2": "0xfffffff8", + "lane3": "0xfffffff8" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084" + }, + "post1": { + "lane0": "0xfffffff8", + "lane1": "0xfffffff8", + "lane2": "0xfffffff8", + "lane3": "0xfffffff8" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "12": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff8", + "lane1": "0xfffffff8", + "lane2": "0xfffffff8", + "lane3": "0xfffffff8" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084" + }, + "post1": { + "lane0": "0xfffffff8", + "lane1": "0xfffffff8", + "lane2": "0xfffffff8", + "lane3": "0xfffffff8" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "13": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff8", + "lane1": "0xfffffff8", + "lane2": "0xfffffff8", + "lane3": "0xfffffff8" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000088", + "lane2": "0x00000088", + "lane3": "0x00000088" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0xfffffffc", + "lane2": "0xfffffffc", + "lane3": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "14": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff8", + "lane1": "0xfffffff8", + "lane2": "0xfffffff8", + "lane3": "0xfffffff8" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000088", + "lane2": "0x00000088", + "lane3": "0x00000088" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0xfffffffc", + "lane2": "0xfffffffc", + "lane3": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "15": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff8", + "lane1": "0xfffffff8", + "lane2": "0xfffffff8", + "lane3": "0xfffffff8" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000088", + "lane2": "0x00000088", + "lane3": "0x00000088" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0xfffffffc", + "lane2": "0xfffffffc", + "lane3": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "16": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff8", + "lane1": "0xfffffff8", + "lane2": "0xfffffff8", + "lane3": "0xfffffff8" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000088", + "lane2": "0x00000088", + "lane3": "0x00000088" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0xfffffffc", + "lane2": "0xfffffffc", + "lane3": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "17": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff8", + "lane1": "0xfffffff8", + "lane2": "0xfffffff8", + "lane3": "0xfffffff8" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000088", + "lane2": "0x00000088", + "lane3": "0x00000088" + }, + "post1": { + "lane0": "0xfffffffc", + "lane1": "0xfffffffc", + "lane2": "0xfffffffc", + "lane3": "0xfffffffc" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "18": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff8", + "lane2": "0xfffffff8", + "lane3": "0xfffffff4" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000088", + "lane2": "0x00000088", + "lane3": "0x00000088" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffffc", + "lane2": "0xfffffffc", + "lane3": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "19": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "20": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff8", + "lane2": "0xfffffff8", + "lane3": "0xfffffff8" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000088", + "lane3": "0x00000090" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff0", + "lane2": "0xfffffff8", + "lane3": "0xfffffff0" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "21": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000088", + "lane2": "0x00000088", + "lane3": "0x00000090" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff8", + "lane2": "0xfffffff8", + "lane3": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "22": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4" + }, + "main": { + "lane0": "0x00000088", + "lane1": "0x00000088", + "lane2": "0x00000088", + "lane3": "0x00000088" + }, + "post1": { + "lane0": "0xfffffff8", + "lane1": "0xfffffff8", + "lane2": "0xfffffff8", + "lane3": "0xfffffff8" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "23": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff8", + "lane3": "0xfffffff8" + }, + "main": { + "lane0": "0x00000084", + "lane1": "0x00000084", + "lane2": "0x00000084", + "lane3": "0x00000084" + }, + "post1": { + "lane0": "0xfffffff8", + "lane1": "0xfffffff8", + "lane2": "0xfffffff8", + "lane3": "0xfffffff8" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000" + } + } + }, + "24": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff8", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff8", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000094", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000088", + "lane5": "0x00000090", + "lane6": "0x0000007C", + "lane7": "0x00000088" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0x00000000", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff8", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "25": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "26": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff8", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000088", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "27": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "28": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "29": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000090" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "30": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff8", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000090", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000084", + "lane5": "0x00000090", + "lane6": "0x00000090", + "lane7": "0x00000088" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff4", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff8", + "lane5": "0xfffffff4", + "lane6": "0xfffffff4", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + }, + "31": { + "Default": { + "pre2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "pre1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff8", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff8", + "lane7": "0xfffffff4" + }, + "main": { + "lane0": "0x00000090", + "lane1": "0x00000088", + "lane2": "0x00000090", + "lane3": "0x00000090", + "lane4": "0x00000090", + "lane5": "0x00000090", + "lane6": "0x0000007C", + "lane7": "0x00000088" + }, + "post1": { + "lane0": "0xfffffff4", + "lane1": "0xfffffff8", + "lane2": "0xfffffff4", + "lane3": "0xfffffff4", + "lane4": "0xfffffff4", + "lane5": "0xfffffff4", + "lane6": "0xfffffff8", + "lane7": "0xfffffff4" + }, + "post2": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + }, + "post3": { + "lane0": "0x00000000", + "lane1": "0x00000000", + "lane2": "0x00000000", + "lane3": "0x00000000", + "lane4": "0x00000000", + "lane5": "0x00000000", + "lane6": "0x00000000", + "lane7": "0x00000000" + } + } + } + } +} diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/monitor.py b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/monitor.py new file mode 100644 index 000000000000..5fc287892e50 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/monitor.py @@ -0,0 +1,402 @@ +#!/usr/bin/python3 +# * onboard temperature sensors +# * FAN trays +# * PSU +# +import os +from lxml import etree as ET +import glob +import json +from decimal import Decimal +from fru import ipmifru + + +MAILBOX_DIR = "/sys/bus/i2c/devices/" +BOARD_ID_PATH = "/sys/module/platform_common/parameters/dfd_my_type" +BOARD_AIRFLOW_PATH = "/etc/sonic/.airflow" + + +CONFIG_NAME = "dev.xml" + + +def byteTostr(val): + strtmp = '' + for value in val: + strtmp += chr(value) + return strtmp + + +def typeTostr(val): + if isinstance(val, bytes): + strtmp = byteTostr(val) + return strtmp + return val + + +def get_board_id(): + if not os.path.exists(BOARD_ID_PATH): + return "NA" + with open(BOARD_ID_PATH) as fd: + id_str = fd.read().strip() + return "0x%x" % (int(id_str, 10)) + + +def getboardairflow(): + if not os.path.exists(BOARD_AIRFLOW_PATH): + return "NA" + with open(BOARD_AIRFLOW_PATH) as fd: + airflow_str = fd.read().strip() + data = json.loads(airflow_str) + airflow = data.get("board", "NA") + return airflow + + +boardid = get_board_id() +boardairflow = getboardairflow() + + +DEV_XML_FILE_LIST = [ + "dev_" + boardid + "_" + boardairflow + ".xml", + "dev_" + boardid + ".xml", + "dev_" + boardairflow + ".xml", +] + + +def dev_file_read(path, offset, read_len): + retval = "ERR" + val_list = [] + msg = "" + ret = "" + fd = -1 + + if not os.path.exists(path): + return False, "%s %s not found" % (retval, path) + + try: + fd = os.open(path, os.O_RDONLY) + os.lseek(fd, offset, os.SEEK_SET) + ret = os.read(fd, read_len) + for item in ret: + val_list.append(item) + except Exception as e: + msg = str(e) + return False, "%s %s" % (retval, msg) + finally: + if fd > 0: + os.close(fd) + return True, val_list + + +def getPMCreg(location): + retval = 'ERR' + if not os.path.isfile(location): + return "%s %s notfound" % (retval, location) + try: + with open(location, 'r') as fd: + retval = fd.read() + except Exception as error: + return "ERR %s" % str(error) + + retval = retval.rstrip('\r\n') + retval = retval.lstrip(" ") + return retval + + +# Get a mailbox register +def get_pmc_register(reg_name): + retval = 'ERR' + mb_reg_file = reg_name + filepath = glob.glob(mb_reg_file) + if len(filepath) == 0: + return "%s %s notfound" % (retval, mb_reg_file) + mb_reg_file = filepath[0] + if not os.path.isfile(mb_reg_file): + # print mb_reg_file, 'not found !' + return "%s %s notfound" % (retval, mb_reg_file) + try: + with open(mb_reg_file, 'rb') as fd: + retval = fd.read() + retval = typeTostr(retval) + except Exception as error: + retval = "%s %s read failed, msg: %s" % (retval, mb_reg_file, str(error)) + + retval = retval.rstrip('\r\n') + retval = retval.lstrip(" ") + return retval + + +class checktype(): + def __init__(self, test1): + self.test1 = test1 + + @staticmethod + def getValue(location, bit, data_type, coefficient=1, addend=0): + try: + value_t = get_pmc_register(location) + if value_t.startswith("ERR") or value_t.startswith("NA"): + return value_t + if data_type == 1: + return float('%.1f' % ((float(value_t) / 1000) + addend)) + if data_type == 2: + return float('%.1f' % (float(value_t) / 100)) + if data_type == 3: + psu_status = int(value_t, 16) + return (psu_status & (1 << bit)) >> bit + if data_type == 4: + return int(value_t, 10) + if data_type == 5: + return float('%.1f' % (float(value_t) / 1000 / 1000)) + if data_type == 6: + return Decimal(float(value_t) * coefficient / 1000).quantize(Decimal('0.000')) + return value_t + except Exception as e: + value_t = "ERR %s" % str(e) + return value_t + + # fanFRU + @staticmethod + def decodeBinByValue(retval): + fru = ipmifru() + fru.decodeBin(retval) + return fru + + @staticmethod + def getfruValue(prob_t, root, val): + try: + ret, binval_bytes = dev_file_read(val, 0, 256) + if ret is False: + return binval_bytes + binval = byteTostr(binval_bytes) + fanpro = {} + ret = checktype.decodeBinByValue(binval) + fanpro['fan_type'] = ret.productInfoArea.productName + fanpro['hw_version'] = ret.productInfoArea.productVersion + fanpro['sn'] = ret.productInfoArea.productSerialNumber + fan_display_name_dict = status.getDecodValue(root, "fan_display_name") + fan_name = fanpro['fan_type'].strip() + if len(fan_display_name_dict) == 0: + return fanpro + if fan_name not in fan_display_name_dict: + prob_t['errcode'] = -1 + prob_t['errmsg'] = '%s' % ("ERR fan name: %s not support" % fan_name) + else: + fanpro['fan_type'] = fan_display_name_dict[fan_name] + return fanpro + except Exception as error: + return "ERR " + str(error) + + @staticmethod + def getslotfruValue(val): + try: + binval = checktype.getValue(val, 0, 0) + if binval.startswith("ERR"): + return binval + slotpro = {} + ret = checktype.decodeBinByValue(binval) + slotpro['slot_type'] = ret.boardInfoArea.boardProductName + slotpro['hw_version'] = ret.boardInfoArea.boardextra1 + slotpro['sn'] = ret.boardInfoArea.boardSerialNumber + return slotpro + except Exception as error: + return "ERR " + str(error) + + @staticmethod + def getpsufruValue(prob_t, root, val): + try: + psu_match = False + binval = checktype.getValue(val, 0, 0) + if binval.startswith("ERR"): + return binval + psupro = {} + ret = checktype.decodeBinByValue(binval) + psupro['type1'] = ret.productInfoArea.productPartModelName + psupro['sn'] = ret.productInfoArea.productSerialNumber + psupro['hw_version'] = ret.productInfoArea.productVersion + psu_dict = status.getDecodValue(root, "psutype") + psupro['type1'] = psupro['type1'].strip() + if len(psu_dict) == 0: + return psupro + for psu_name, display_name in psu_dict.items(): + if psu_name.strip() == psupro['type1']: + psupro['type1'] = display_name + psu_match = True + break + if psu_match is not True: + prob_t['errcode'] = -1 + prob_t['errmsg'] = '%s' % ("ERR psu name: %s not support" % psupro['type1']) + return psupro + except Exception as error: + return "ERR " + str(error) + + +class status(): + def __init__(self, productname): + self.productname = productname + + @staticmethod + def getETroot(filename): + tree = ET.parse(filename) + root = tree.getroot() + return root + + @staticmethod + def getDecodValue(collection, decode): + decodes = collection.find('decode') + testdecode = decodes.find(decode) + test = {} + if testdecode is None: + return test + for neighbor in testdecode.iter('code'): + test[neighbor.attrib["key"]] = neighbor.attrib["value"] + return test + + @staticmethod + def getfileValue(location): + return checktype.getValue(location, " ", " ") + + @staticmethod + def getETValue(a, filename, tagname): + root = status.getETroot(filename) + for neighbor in root.iter(tagname): + prob_t = {} + prob_t.update(neighbor.attrib) + prob_t['errcode'] = 0 + prob_t['errmsg'] = '' + for pros in neighbor.iter("property"): + ret = dict(list(neighbor.attrib.items()) + list(pros.attrib.items())) + if ret.get('e2type') == 'fru' and ret.get("name") == "fru": + fruval = checktype.getfruValue(prob_t, root, ret["location"]) + if isinstance(fruval, str) and fruval.startswith("ERR"): + prob_t['errcode'] = -1 + prob_t['errmsg'] = fruval + break + prob_t.update(fruval) + continue + + if ret.get("name") == "psu" and ret.get('e2type') == 'fru': + psuval = checktype.getpsufruValue(prob_t, root, ret["location"]) + if isinstance(psuval, str) and psuval.startswith("ERR"): + prob_t['errcode'] = -1 + prob_t['errmsg'] = psuval + break + prob_t.update(psuval) + continue + + if ret.get("gettype") == "config": + prob_t[ret["name"]] = ret["value"] + continue + + if 'type' not in ret.keys(): + val = "0" + else: + val = ret["type"] + if 'bit' not in ret.keys(): + bit = "0" + else: + bit = ret["bit"] + if 'coefficient' not in ret.keys(): + coefficient = 1 + else: + coefficient = float(ret["coefficient"]) + if 'addend' not in ret.keys(): + addend = 0 + else: + addend = float(ret["addend"]) + + s = checktype.getValue(ret["location"], int(bit), int(val), coefficient, addend) + if isinstance(s, str) and s.startswith("ERR"): + prob_t['errcode'] = -1 + prob_t['errmsg'] = s + break + if 'default' in ret.keys(): + rt = status.getDecodValue(root, ret['decode']) + prob_t['errmsg'] = rt[str(s)] + if str(s) != ret["default"]: + prob_t['errcode'] = -1 + break + else: + if 'decode' in ret.keys(): + rt = status.getDecodValue(root, ret['decode']) + if (ret['decode'] == "psutype" and s.replace("\x00", "").rstrip() not in rt): + prob_t['errcode'] = -1 + prob_t['errmsg'] = '%s' % ("ERR psu name: %s not support" % + (s.replace("\x00", "").rstrip())) + else: + s = rt[str(s).replace("\x00", "").rstrip()] + name = ret["name"] + prob_t[name] = str(s) + a.append(prob_t) + + @staticmethod + def getCPUValue(a, filename, tagname): + root = status.getETroot(filename) + for neighbor in root.iter(tagname): + location = neighbor.attrib["location"] + L = [] + for dirpath, dirnames, filenames in os.walk(location): + for file in filenames: + if file.endswith("input"): + L.append(os.path.join(dirpath, file)) + L = sorted(L, reverse=False) + for i in range(len(L)): + prob_t = {} + prob_t["name"] = getPMCreg("%s/temp%d_label" % (location, i + 1)) + prob_t["temp"] = float(getPMCreg("%s/temp%d_input" % (location, i + 1))) / 1000 + prob_t["alarm"] = float(getPMCreg("%s/temp%d_crit_alarm" % (location, i + 1))) / 1000 + prob_t["crit"] = float(getPMCreg("%s/temp%d_crit" % (location, i + 1))) / 1000 + prob_t["max"] = float(getPMCreg("%s/temp%d_max" % (location, i + 1))) / 1000 + a.append(prob_t) + + @staticmethod + def getFileName(): + fpath = os.path.dirname(os.path.realpath(__file__)) + for file in DEV_XML_FILE_LIST: + xml = fpath + "/" + file + if os.path.exists(xml): + return xml + return fpath + "/" + CONFIG_NAME + + @staticmethod + def checkFan(ret): + _filename = status.getFileName() + # _filename = "/usr/local/bin/" + status.getFileName() + _tagname = "fan" + status.getETValue(ret, _filename, _tagname) + + @staticmethod + def getTemp(ret): + _filename = status.getFileName() + # _filename = "/usr/local/bin/" + status.getFileName() + _tagname = "temp" + status.getETValue(ret, _filename, _tagname) + + @staticmethod + def getPsu(ret): + _filename = status.getFileName() + # _filename = "/usr/local/bin/" + status.getFileName() + _tagname = "psu" + status.getETValue(ret, _filename, _tagname) + + @staticmethod + def getcputemp(ret): + _filename = status.getFileName() + _tagname = "cpus" + status.getCPUValue(ret, _filename, _tagname) + + @staticmethod + def getDcdc(ret): + _filename = status.getFileName() + _tagname = "dcdc" + status.getETValue(ret, _filename, _tagname) + + @staticmethod + def getmactemp(ret): + _filename = status.getFileName() + _tagname = "mactemp" + status.getETValue(ret, _filename, _tagname) + + @staticmethod + def getmacpower(ret): + _filename = status.getFileName() + _tagname = "macpower" + status.getETValue(ret, _filename, _tagname) diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/pcie.yaml b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/pcie.yaml new file mode 100644 index 000000000000..ee025879f7f8 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/pcie.yaml @@ -0,0 +1,581 @@ +- bus: '00' + dev: '00' + fn: '0' + id: 6f00 + name: 'Host bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D DMI2 + (rev 05)' +- bus: '00' + dev: '01' + fn: '0' + id: 6f02 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 1 (rev 05)' +- bus: '00' + dev: '01' + fn: '1' + id: 6f03 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 1 (rev 05)' +- bus: '00' + dev: '02' + fn: '0' + id: 6f04 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 2 (rev 05)' +- bus: '00' + dev: '02' + fn: '2' + id: 6f06 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 2 (rev 05)' +- bus: '00' + dev: '02' + fn: '3' + id: 6f07 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 2 (rev 05)' +- bus: '00' + dev: '03' + fn: '0' + id: 6f08 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 3 (rev 05)' +- bus: '00' + dev: '03' + fn: '1' + id: 6f09 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 3 (rev 05)' +- bus: '00' + dev: '03' + fn: '2' + id: 6f0a + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 3 (rev 05)' +- bus: '00' + dev: '03' + fn: '3' + id: 6f0b + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 3 (rev 05)' +- bus: '00' + dev: '04' + fn: '0' + id: 6f20 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Crystal Beach DMA Channel 0 (rev 05)' +- bus: '00' + dev: '04' + fn: '1' + id: 6f21 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Crystal Beach DMA Channel 1 (rev 05)' +- bus: '00' + dev: '04' + fn: '2' + id: 6f22 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Crystal Beach DMA Channel 2 (rev 05)' +- bus: '00' + dev: '04' + fn: '3' + id: 6f23 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Crystal Beach DMA Channel 3 (rev 05)' +- bus: '00' + dev: '04' + fn: '4' + id: 6f24 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Crystal Beach DMA Channel 4 (rev 05)' +- bus: '00' + dev: '04' + fn: '5' + id: 6f25 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Crystal Beach DMA Channel 5 (rev 05)' +- bus: '00' + dev: '04' + fn: '6' + id: 6f26 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Crystal Beach DMA Channel 6 (rev 05)' +- bus: '00' + dev: '04' + fn: '7' + id: 6f27 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Crystal Beach DMA Channel 7 (rev 05)' +- bus: '00' + dev: '05' + fn: '0' + id: 6f28 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Map/VTd_Misc/System Management (rev 05)' +- bus: '00' + dev: '05' + fn: '1' + id: 6f29 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO Hot Plug (rev 05)' +- bus: '00' + dev: '05' + fn: '2' + id: 6f2a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO RAS/Control Status/Global Errors (rev 05)' +- bus: '00' + dev: '05' + fn: '4' + id: 6f2c + name: 'PIC: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D I/O APIC (rev + 05)' +- bus: '00' + dev: '05' + fn: '6' + id: 6f39 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IO Performance Monitoring (rev 05)' +- bus: '00' + dev: '06' + fn: '0' + id: 6f10 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO Debug (rev 05)' +- bus: '00' + dev: '06' + fn: '1' + id: 6f11 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO Debug (rev 05)' +- bus: '00' + dev: '06' + fn: '2' + id: 6f12 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO Debug (rev 05)' +- bus: '00' + dev: '06' + fn: '3' + id: 6f13 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO Debug (rev 05)' +- bus: '00' + dev: '06' + fn: '4' + id: 6f14 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO Debug (rev 05)' +- bus: '00' + dev: '06' + fn: '5' + id: 6f15 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO Debug (rev 05)' +- bus: '00' + dev: '06' + fn: '6' + id: 6f16 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO Debug (rev 05)' +- bus: '00' + dev: '06' + fn: '7' + id: 6f17 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO Debug (rev 05)' +- bus: '00' + dev: '07' + fn: '0' + id: 6f18 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO Debug (rev 05)' +- bus: '00' + dev: '07' + fn: '1' + id: 6f19 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO Debug (rev 05)' +- bus: '00' + dev: '07' + fn: '2' + id: 6f1a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO Debug (rev 05)' +- bus: '00' + dev: '07' + fn: '3' + id: 6f1b + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO Debug (rev 05)' +- bus: '00' + dev: '07' + fn: '4' + id: 6f1c + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO Debug (rev 05)' +- bus: '00' + dev: '14' + fn: '0' + id: 8c31 + name: 'USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB + xHCI (rev 05)' +- bus: '00' + dev: '16' + fn: '0' + id: 8c3a + name: 'Communication controller: Intel Corporation 8 Series/C220 Series Chipset + Family MEI Controller #1 (rev 04)' +- bus: '00' + dev: '16' + fn: '1' + id: 8c3b + name: 'Communication controller: Intel Corporation 8 Series/C220 Series Chipset + Family MEI Controller #2 (rev 04)' +- bus: '00' + dev: 1d + fn: '0' + id: 8c26 + name: 'USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB + EHCI #1 (rev 05)' +- bus: '00' + dev: 1f + fn: '0' + id: 8c54 + name: 'ISA bridge: Intel Corporation C224 Series Chipset Family Server Standard + SKU LPC Controller (rev 05)' +- bus: '00' + dev: 1f + fn: '2' + id: 8c02 + name: 'SATA controller: Intel Corporation 8 Series/C220 Series Chipset Family 6-port + SATA Controller 1 [AHCI mode] (rev 05)' +- bus: '00' + dev: 1f + fn: '3' + id: 8c22 + name: 'SMBus: Intel Corporation 8 Series/C220 Series Chipset Family SMBus Controller + (rev 05)' +- bus: '04' + dev: '00' + fn: '0' + id: 15ab + name: 'Ethernet controller: Intel Corporation Ethernet Connection X552 10 GbE Backplane' +- bus: '04' + dev: '00' + fn: '1' + id: 15ab + name: 'Ethernet controller: Intel Corporation Ethernet Connection X552 10 GbE Backplane' +- bus: '05' + dev: '00' + fn: '0' + id: 15ab + name: 'Ethernet controller: Intel Corporation Ethernet Connection X552 10 GbE Backplane' +- bus: '05' + dev: '00' + fn: '1' + id: 15ab + name: 'Ethernet controller: Intel Corporation Ethernet Connection X552 10 GbE Backplane' +- bus: '06' + dev: '00' + fn: '0' + id: b780 + name: 'Ethernet controller: Broadcom Inc. and subsidiaries Device b780 (rev 01)' +- bus: '07' + dev: '00' + fn: '0' + id: '1537' + name: 'Ethernet controller: Intel Corporation I210 Gigabit Backplane Connection + (rev 03)' +- bus: 08 + dev: '00' + fn: '0' + id: '7011' + name: 'Memory controller: Xilinx Corporation Device 7011' +- bus: ff + dev: 0b + fn: '0' + id: 6f81 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 05)' +- bus: ff + dev: 0b + fn: '1' + id: 6f36 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 05)' +- bus: ff + dev: 0b + fn: '2' + id: 6f37 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 05)' +- bus: ff + dev: 0b + fn: '3' + id: 6f76 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link Debug (rev 05)' +- bus: ff + dev: 0c + fn: '0' + id: 6fe0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 05)' +- bus: ff + dev: 0c + fn: '1' + id: 6fe1 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 05)' +- bus: ff + dev: 0c + fn: '2' + id: 6fe2 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 05)' +- bus: ff + dev: 0c + fn: '3' + id: 6fe3 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 05)' +- bus: ff + dev: 0f + fn: '0' + id: 6ff8 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 05)' +- bus: ff + dev: 0f + fn: '4' + id: 6ffc + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 05)' +- bus: ff + dev: 0f + fn: '5' + id: 6ffd + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 05)' +- bus: ff + dev: 0f + fn: '6' + id: 6ffe + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 05)' +- bus: ff + dev: '10' + fn: '0' + id: 6f1d + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R2PCIe Agent (rev 05)' +- bus: ff + dev: '10' + fn: '1' + id: 6f34 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R2PCIe Agent (rev 05)' +- bus: ff + dev: '10' + fn: '5' + id: 6f1e + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 05)' +- bus: ff + dev: '10' + fn: '6' + id: 6f7d + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 05)' +- bus: ff + dev: '10' + fn: '7' + id: 6f1f + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 05)' +- bus: ff + dev: '12' + fn: '0' + id: 6fa0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Home Agent 0 (rev 05)' +- bus: ff + dev: '12' + fn: '1' + id: 6f30 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Home Agent 0 (rev 05)' +- bus: ff + dev: '12' + fn: '2' + id: 6f70 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Home Agent 0 Debug (rev 05)' +- bus: ff + dev: '13' + fn: '0' + id: 6fa8 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Target Address/Thermal/RAS (rev 05)' +- bus: ff + dev: '13' + fn: '1' + id: 6f71 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Target Address/Thermal/RAS (rev 05)' +- bus: ff + dev: '13' + fn: '2' + id: 6faa + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 05)' +- bus: ff + dev: '13' + fn: '3' + id: 6fab + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 05)' +- bus: ff + dev: '13' + fn: '4' + id: 6fac + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 05)' +- bus: ff + dev: '13' + fn: '5' + id: 6fad + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 05)' +- bus: ff + dev: '13' + fn: '6' + id: 6fae + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Broadcast (rev 05)' +- bus: ff + dev: '13' + fn: '7' + id: 6faf + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Global Broadcast (rev 05)' +- bus: ff + dev: '14' + fn: '0' + id: 6fb0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 0 Thermal Control (rev 05)' +- bus: ff + dev: '14' + fn: '1' + id: 6fb1 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 1 Thermal Control (rev 05)' +- bus: ff + dev: '14' + fn: '2' + id: 6fb2 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 0 Error (rev 05)' +- bus: ff + dev: '14' + fn: '3' + id: 6fb3 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 1 Error (rev 05)' +- bus: ff + dev: '14' + fn: '4' + id: 6fbc + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 05)' +- bus: ff + dev: '14' + fn: '5' + id: 6fbd + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 05)' +- bus: ff + dev: '14' + fn: '6' + id: 6fbe + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 05)' +- bus: ff + dev: '14' + fn: '7' + id: 6fbf + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 05)' +- bus: ff + dev: '15' + fn: '0' + id: 6fb4 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 2 Thermal Control (rev 05)' +- bus: ff + dev: '15' + fn: '1' + id: 6fb5 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 3 Thermal Control (rev 05)' +- bus: ff + dev: '15' + fn: '2' + id: 6fb6 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 2 Error (rev 05)' +- bus: ff + dev: '15' + fn: '3' + id: 6fb7 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 3 Error (rev 05)' +- bus: ff + dev: 1e + fn: '0' + id: 6f98 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 05)' +- bus: ff + dev: 1e + fn: '1' + id: 6f99 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 05)' +- bus: ff + dev: 1e + fn: '2' + id: 6f9a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 05)' +- bus: ff + dev: 1e + fn: '3' + id: 6fc0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 05)' +- bus: ff + dev: 1e + fn: '4' + id: 6f9c + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 05)' +- bus: ff + dev: 1e + fn: '7' + id: 6f9f + name: 'System peripheral: Intel Corporation Device 6f9f (rev 05)' +- bus: ff + dev: 1f + fn: '0' + id: 6f88 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 05)' +- bus: ff + dev: 1f + fn: '2' + id: 6f8a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 05)' diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/platform.json b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/platform.json new file mode 100644 index 000000000000..d22eee94c31b --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/platform.json @@ -0,0 +1,1010 @@ +{ + "chassis": { + "name": "M2-W6520-24DC8QC", + "thermal_manager": false, + "status_led": { + "controllable": false, + "colors": [ + "green", + "blinking_green", + "amber", + "blinking_amber" + ] + }, + "components": [ + { + "name": "CPU_CPLD" + }, + { + "name": "CONNECT_CPLD" + }, + { + "name": "MAC_CPLDA" + }, + { + "name": "MAC_CPLDB" + }, + { + "name": "FAN_CPLD" + }, + { + "name": "FPGA" + }, + { + "name": "BIOS" + } + ], + "fans": [ + { + "name": "Fantray1_1", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false, + "colors": [ + "off", + "red", + "amber", + "green" + ] + } + }, + { + "name": "Fantray1_2", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false, + "colors": [ + "off", + "red", + "amber", + "green" + ] + } + }, + { + "name": "Fantray2_1", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false, + "colors": [ + "off", + "red", + "amber", + "green" + ] + } + }, + { + "name": "Fantray2_2", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false, + "colors": [ + "off", + "red", + "amber", + "green" + ] + } + }, + { + "name": "Fantray3_1", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false, + "colors": [ + "off", + "red", + "amber", + "green" + ] + } + }, + { + "name": "Fantray3_2", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false, + "colors": [ + "off", + "red", + "amber", + "green" + ] + } + }, + { + "name": "Fantray4_1", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false, + "colors": [ + "off", + "red", + "amber", + "green" + ] + } + }, + { + "name": "Fantray4_2", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false, + "colors": [ + "off", + "red", + "amber", + "green" + ] + } + }, + { + "name": "Fantray5_1", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false, + "colors": [ + "off", + "red", + "amber", + "green" + ] + } + }, + { + "name": "Fantray5_2", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false, + "colors": [ + "off", + "red", + "amber", + "green" + ] + } + }, + { + "name": "Fantray6_1", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false, + "colors": [ + "off", + "red", + "amber", + "green" + ] + } + }, + { + "name": "Fantray6_2", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false, + "colors": [ + "off", + "red", + "amber", + "green" + ] + } + } + ], + "fan_drawers": [ + { + "name": "Fantray1", + "num_fans": 2, + "status_led": { + "controllable": false, + "colors": [ + "amber", + "green", + "off" + ] + }, + "fans": [ + { + "name": "Fantray1_1", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false + } + }, + { + "name": "Fantray1_2", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false + } + } + ] + }, + { + "name": "Fantray2", + "num_fans": 2, + "status_led": { + "controllable": false, + "colors": [ + "amber", + "green", + "off" + ] + }, + "fans": [ + { + "name": "Fantray2_1", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false + } + }, + { + "name": "Fantray2_2", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false + } + } + ] + }, + { + "name": "Fantray3", + "num_fans": 2, + "status_led": { + "controllable": false, + "colors": [ + "amber", + "green", + "off" + ] + }, + "fans": [ + { + "name": "Fantray3_1", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false + } + }, + { + "name": "Fantray3_2", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false + } + } + ] + }, + { + "name": "Fantray4", + "num_fans": 2, + "status_led": { + "controllable": false, + "colors": [ + "amber", + "green", + "off" + ] + }, + "fans": [ + { + "name": "Fantray4_1", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false + } + }, + { + "name": "Fantray4_2", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false + } + } + ] + }, + { + "name": "Fantray5", + "num_fans": 2, + "status_led": { + "controllable": false, + "colors": [ + "amber", + "green", + "off" + ] + }, + "fans": [ + { + "name": "Fantray5_1", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false + } + }, + { + "name": "Fantray5_2", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false + } + } + ] + }, + { + "name": "Fantray6", + "num_fans": 2, + "status_led": { + "controllable": false, + "colors": [ + "amber", + "green", + "off" + ] + }, + "fans": [ + { + "name": "Fantray6_1", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false + } + }, + { + "name": "Fantray6_2", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false + } + } + ] + } + ], + "psus": [ + { + "name": "Psu1", + "voltage": true, + "current": true, + "power": true, + "max_power": false, + "voltage_high_threshold": true, + "voltage_low_threshold": true, + "temperature": true, + "fans_target_speed": true, + "status_led": { + "controllable": false + }, + "fans": [ + { + "name": "PSU1_FAN1", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false + } + } + ] + }, + { + "name": "Psu2", + "voltage": true, + "current": true, + "power": true, + "max_power": false, + "voltage_high_threshold": true, + "voltage_low_threshold": true, + "temperature": true, + "fans_target_speed": true, + "status_led": { + "controllable": false + }, + "fans": [ + { + "name": "PSU2_FAN1", + "speed": { + "controllable": true, + "minimum": 50, + "maximum": 100 + }, + "status_led": { + "available": false + } + } + ] + } + ], + "thermals": [ + { + "name": "BOARD_TEMP", + "controllable": false, + "low-crit-threshold": true, + "high-crit-threshold": true, + "low-threshold": true, + "high-threshold": true, + "minimum-recorded": true, + "maximum-recorded": true + }, + { + "name": "CPU_TEMP", + "controllable": false, + "low-crit-threshold": true, + "high-crit-threshold": true, + "low-threshold": true, + "high-threshold": true, + "minimum-recorded": true, + "maximum-recorded": true + }, + { + "name": "INLET_TEMP", + "controllable": false, + "low-crit-threshold": true, + "high-crit-threshold": true, + "low-threshold": true, + "high-threshold": true, + "minimum-recorded": true, + "maximum-recorded": true + }, + { + "name": "OUTLET_TEMP", + "controllable": false, + "low-crit-threshold": true, + "high-crit-threshold": true, + "low-threshold": true, + "high-threshold": true, + "minimum-recorded": true, + "maximum-recorded": true + }, + { + "name": "ASIC_TEMP", + "controllable": false, + "low-crit-threshold": true, + "high-crit-threshold": true, + "low-threshold": true, + "high-threshold": true, + "minimum-recorded": true, + "maximum-recorded": true + }, + { + "name": "PSU1_TEMP", + "controllable": false, + "low-crit-threshold": true, + "high-crit-threshold": true, + "low-threshold": true, + "high-threshold": true, + "minimum-recorded": true, + "maximum-recorded": true + }, + { + "name": "PSU2_TEMP", + "controllable": false, + "low-crit-threshold": true, + "high-crit-threshold": true, + "low-threshold": true, + "high-threshold": true, + "minimum-recorded": true, + "maximum-recorded": true + } + ], + "modules": [], + "sfps": [] + }, + "interfaces": { + "Ethernet1": { + "index": "0,0,0,0", + "lanes": "25,26,27,28", + "breakout_modes": { + "1x200G": [ + "Eth1" + ], + "2x100G": [ + "Eth1/1", + "Eth1/2" + ] + } + }, + "Ethernet5": { + "index": "1,1,1,1", + "lanes": "29,30,31,32", + "breakout_modes": { + "1x200G": [ + "Eth2" + ], + "2x100G": [ + "Eth2/1", + "Eth2/2" + ] + } + }, + "Ethernet9": { + "index": "2,2,2,2", + "lanes": "41,42,43,44", + "breakout_modes": { + "1x200G": [ + "Eth3" + ], + "2x100G": [ + "Eth3/1", + "Eth3/2" + ] + } + }, + "Ethernet13": { + "index": "3,3,3,3", + "lanes": "45,46,47,48", + "breakout_modes": { + "1x200G": [ + "Eth4" + ], + "2x100G": [ + "Eth4/1", + "Eth4/2" + ] + } + }, + "Ethernet17": { + "index": "4,4,4,4", + "lanes": "49,50,51,52", + "breakout_modes": { + "1x200G": [ + "Eth5" + ], + "2x100G": [ + "Eth5/1", + "Eth5/2" + ] + } + }, + "Ethernet21": { + "index": "5,5,5,5", + "lanes": "53,54,55,56", + "breakout_modes": { + "1x200G": [ + "Eth6" + ], + "2x100G": [ + "Eth6/1", + "Eth6/2" + ] + } + }, + "Ethernet25": { + "index": "6,6,6,6", + "lanes": "57,58,59,60", + "breakout_modes": { + "1x200G": [ + "Eth7" + ], + "2x100G": [ + "Eth7/1", + "Eth7/2" + ] + } + }, + "Ethernet29": { + "index": "7,7,7,7", + "lanes": "61,62,63,64", + "breakout_modes": { + "1x200G": [ + "Eth8" + ], + "2x100G": [ + "Eth8/1", + "Eth8/2" + ] + } + }, + "Ethernet33": { + "index": "8,8,8,8", + "lanes": "9,10,11,12", + "breakout_modes": { + "1x200G": [ + "Eth9" + ], + "2x100G": [ + "Eth9/1", + "Eth9/2" + ] + } + }, + "Ethernet37": { + "index": "9,9,9,9", + "lanes": "13,14,15,16", + "breakout_modes": { + "1x200G": [ + "Eth10" + ], + "2x100G": [ + "Eth10/1", + "Eth10/2" + ] + } + }, + "Ethernet41": { + "index": "10,10,10,10", + "lanes": "17,18,19,20", + "breakout_modes": { + "1x200G": [ + "Eth11" + ], + "2x100G": [ + "Eth11/1", + "Eth11/2" + ] + } + }, + "Ethernet45": { + "index": "11,11,11,11", + "lanes": "21,22,23,24", + "breakout_modes": { + "1x200G": [ + "Eth12" + ], + "2x100G": [ + "Eth12/1", + "Eth12/2" + ] + } + }, + "Ethernet49": { + "index": "12,12,12,12", + "lanes": "81,82,83,84", + "breakout_modes": { + "1x200G": [ + "Eth13" + ], + "2x100G": [ + "Eth13/1", + "Eth13/2" + ] + } + }, + "Ethernet53": { + "index": "13,13,13,13", + "lanes": "85,86,87,88", + "breakout_modes": { + "1x200G": [ + "Eth14" + ], + "2x100G": [ + "Eth14/1", + "Eth14/2" + ] + } + }, + "Ethernet57": { + "index": "14,14,14,14", + "lanes": "89,90,91,92", + "breakout_modes": { + "1x200G": [ + "Eth15" + ], + "2x100G": [ + "Eth15/1", + "Eth15/2" + ] + } + }, + "Ethernet61": { + "index": "15,15,15,15", + "lanes": "93,94,95,96", + "breakout_modes": { + "1x200G": [ + "Eth16" + ], + "2x100G": [ + "Eth16/1", + "Eth16/2" + ] + } + }, + "Ethernet65": { + "index": "16,16,16,16", + "lanes": "97,98,99,100", + "breakout_modes": { + "1x200G": [ + "Eth17" + ], + "2x100G": [ + "Eth17/1", + "Eth17/2" + ] + } + }, + "Ethernet69": { + "index": "17,17,17,17", + "lanes": "101,102,103,104", + "breakout_modes": { + "1x200G": [ + "Eth18" + ], + "2x100G": [ + "Eth18/1", + "Eth18/2" + ] + } + }, + "Ethernet73": { + "index": "18,18,18,18", + "lanes": "137,138,139,140", + "breakout_modes": { + "1x200G": [ + "Eth19" + ], + "2x100G": [ + "Eth19/1", + "Eth19/2" + ] + } + }, + "Ethernet77": { + "index": "19,19,19,19", + "lanes": "141,142,143,144", + "breakout_modes": { + "1x200G": [ + "Eth20" + ], + "2x100G": [ + "Eth20/1", + "Eth20/2" + ] + } + }, + "Ethernet81": { + "index": "20,20,20,20", + "lanes": "145,146,147,148", + "breakout_modes": { + "1x200G": [ + "Eth21" + ], + "2x100G": [ + "Eth21/1", + "Eth21/2" + ] + } + }, + "Ethernet85": { + "index": "21,21,21,21", + "lanes": "149,150,151,152", + "breakout_modes": { + "1x200G": [ + "Eth22" + ], + "2x100G": [ + "Eth22/1", + "Eth22/2" + ] + } + }, + "Ethernet89": { + "index": "22,22,22,22", + "lanes": "153,154,155,156", + "breakout_modes": { + "1x200G": [ + "Eth23" + ], + "2x100G": [ + "Eth23/1", + "Eth23/2" + ] + } + }, + "Ethernet93": { + "index": "23,23,23,23", + "lanes": "157,158,159,160", + "breakout_modes": { + "1x200G": [ + "Eth24" + ], + "2x100G": [ + "Eth24/1", + "Eth24/2" + ] + } + }, + "Ethernet97": { + "index": "24,24,24,24,24,24,24,24", + "lanes": "1,2,3,4,5,6,7,8", + "breakout_modes": { + "1x400G": [ + "Eth25" + ], + "2x200G[100G]": [ + "Eth25/1", + "Eth25/2" + ] + } + }, + "Ethernet105": { + "index": "25,25,25,25,25,25,25,25", + "lanes": "33,34,35,36,37,38,39,40", + "breakout_modes": { + "1x400G": [ + "Eth26" + ], + "2x200G[100G]": [ + "Eth26/1", + "Eth26/2" + ] + } + }, + "Ethernet113": { + "index": "26,26,26,26,26,26,26,26", + "lanes": "65,66,67,68,69,70,71,72", + "breakout_modes": { + "1x400G": [ + "Eth27" + ], + "2x200G[100G]": [ + "Eth27/1", + "Eth27/2" + ] + } + }, + "Ethernet121": { + "index": "27,27,27,27,27,27,27,27", + "lanes": "73,74,75,76,77,78,79,80", + "breakout_modes": { + "1x400G": [ + "Eth28" + ], + "2x200G[100G]": [ + "Eth28/1", + "Eth28/2" + ] + } + }, + "Ethernet129": { + "index": "28,28,28,28,28,28,28,28", + "lanes": "105,106,107,108,109,110,111,112", + "breakout_modes": { + "1x400G": [ + "Eth29" + ], + "2x200G[100G]": [ + "Eth29/1", + "Eth29/2" + ] + } + }, + "Ethernet137": { + "index": "29,29,29,29,29,29,29,29", + "lanes": "113,114,115,116,117,118,119,120", + "breakout_modes": { + "1x400G": [ + "Eth30" + ], + "2x200G[100G]": [ + "Eth30/1", + "Eth30/2" + ] + } + }, + "Ethernet145": { + "index": "30,30,30,30,30,30,30,30", + "lanes": "121,122,123,124,125,126,127,128", + "breakout_modes": { + "1x400G": [ + "Eth31" + ], + "2x200G[100G]": [ + "Eth31/1", + "Eth31/2" + ] + } + }, + "Ethernet153": { + "index": "31,31,31,31,31,31,31,31", + "lanes": "129,130,131,132,133,134,135,136", + "breakout_modes": { + "1x400G": [ + "Eth32" + ], + "2x200G[100G]": [ + "Eth32/1", + "Eth32/2" + ] + } + } + } +} diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/platform_asic b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/platform_asic new file mode 100644 index 000000000000..960467652765 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/platform_asic @@ -0,0 +1 @@ +broadcom diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/platform_components.json b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/platform_components.json new file mode 100644 index 000000000000..8fc136f7b9b1 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/platform_components.json @@ -0,0 +1,16 @@ +{ + "chassis": { + "M2-W6520-24DC8QC": { + "component": { + "CPU_CPLD": { }, + "CONNECT_CPLD": { }, + "FAN_CPLD": { }, + "MAC_CPLDA": { }, + "MAC_CPLDB": { }, + "FPGA": { }, + "BIOS": { } + } + } + } +} + diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/platform_env.conf b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/platform_env.conf new file mode 100644 index 000000000000..fc119184d5c1 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/platform_env.conf @@ -0,0 +1,2 @@ +is_ltsw_chip=1 +SYNCD_SHM_SIZE=1g diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/plugins/sfputil.py b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/plugins/sfputil.py new file mode 100644 index 000000000000..f6c4e0477c57 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/plugins/sfputil.py @@ -0,0 +1,365 @@ +# sfputil.py +# +# Platform-specific SFP transceiver interface for SONiC +# + +try: + import time + import re + import os + import threading + import traceback + import subprocess + from ctypes import create_string_buffer + from sonic_sfp.sfputilbase import SfpUtilBase + from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom +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 = 46 + SFP_DEVICE_TYPE = "optoe2" + QSFP_DEVICE_TYPE = "optoe1" + QSFP_DD_DEVICE_TYPE = "optoe3" + I2C_MAX_ATTEMPT = 3 + + OPTOE_TYPE1 = 1 + OPTOE_TYPE2 = 2 + OPTOE_TYPE3 = 3 + + SFP_STATUS_INSERTED = '1' + SFP_STATUS_REMOVED = '0' + + _port_to_eeprom_mapping = {} + port_to_i2cbus_mapping ={} + port_dict = {} + + qsfp_ports_list = [] + qsfp_dd_ports_list = [] + + @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_list + + @property + def qsfp_dd_ports(self): + return self.qsfp_dd_ports_list + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + def __init__(self): + self.qsfp_ports_list = [] + self.qsfp_dd_ports_list = [] + for x in range(self.PORT_START, self.PORTS_IN_BLOCK): + self.port_to_i2cbus_mapping[x] = (x + self.EEPROM_OFFSET) + + if self.get_presence(x): + self.port_dict[x] = self.SFP_STATUS_INSERTED + else: + self.port_dict[x] = self.SFP_STATUS_REMOVED + + if (self.check_is_qsfpdd(x)): + self.qsfp_dd_ports_list.append(x) + self.check_optoe_type(x, self.OPTOE_TYPE3) + else: + self.qsfp_ports_list.append(x) + self.check_optoe_type(x, self.OPTOE_TYPE1) + SfpUtilBase.__init__(self) + + def _sfp_read_file_path(self, file_path, offset, num_bytes): + attempts = 0 + while attempts < self.I2C_MAX_ATTEMPT: + try: + file_path.seek(offset) + read_buf = file_path.read(num_bytes) + except: + attempts += 1 + time.sleep(0.05) + else: + return True, read_buf + return False, None + + def _sfp_eeprom_present(self, sysfs_sfp_i2c_client_eeprompath, offset): + """Tries to read the eeprom file to determine if the + device/sfp is present or not. If sfp present, the read returns + valid bytes. If not, read returns error 'Connection timed out""" + + if not os.path.exists(sysfs_sfp_i2c_client_eeprompath): + return False + else: + with open(sysfs_sfp_i2c_client_eeprompath, "rb", buffering=0) as sysfsfile: + rv, buf = self._sfp_read_file_path(sysfsfile, offset, 1) + return rv + + def _add_new_sfp_device(self, sysfs_sfp_i2c_adapter_path, devaddr, devtype): + try: + sysfs_nd_path = "%s/new_device" % sysfs_sfp_i2c_adapter_path + + # Write device address to new_device file + nd_file = open(sysfs_nd_path, "w") + nd_str = "%s %s" % (devtype, hex(devaddr)) + nd_file.write(nd_str) + nd_file.close() + + except Exception as err: + print("Error writing to new device file: %s" % str(err)) + return 1 + else: + return 0 + + def _get_port_eeprom_path(self, port_num, devid): + sysfs_i2c_adapter_base_path = "/sys/class/i2c-adapter" + + if port_num in self.port_to_eeprom_mapping.keys(): + sysfs_sfp_i2c_client_eeprom_path = self.port_to_eeprom_mapping[port_num] + else: + sysfs_i2c_adapter_base_path = "/sys/class/i2c-adapter" + + i2c_adapter_id = self._get_port_i2c_adapter_id(port_num) + if i2c_adapter_id is None: + print("Error getting i2c bus num") + return None + + # Get i2c virtual bus path for the sfp + sysfs_sfp_i2c_adapter_path = "%s/i2c-%s" % (sysfs_i2c_adapter_base_path, + str(i2c_adapter_id)) + + # If i2c bus for port does not exist + if not os.path.exists(sysfs_sfp_i2c_adapter_path): + print("Could not find i2c bus %s. Driver not loaded?" % sysfs_sfp_i2c_adapter_path) + return None + + sysfs_sfp_i2c_client_path = "%s/%s-00%s" % (sysfs_sfp_i2c_adapter_path, + str(i2c_adapter_id), + hex(devid)[-2:]) + + # If sfp device is not present on bus, Add it + if not os.path.exists(sysfs_sfp_i2c_client_path): + if port_num in self.qsfp_dd_ports: + ret = self._add_new_sfp_device( + sysfs_sfp_i2c_adapter_path, devid, self.QSFP_DD_DEVICE_TYPE) + elif port_num in self.qsfp_ports: + ret = self._add_new_sfp_device( + sysfs_sfp_i2c_adapter_path, devid, self.QSFP_DEVICE_TYPE) + else: + ret = self._add_new_sfp_device( + sysfs_sfp_i2c_adapter_path, devid, self.SFP_DEVICE_TYPE) + if ret != 0: + print("Error adding sfp device") + return None + + sysfs_sfp_i2c_client_eeprom_path = "%s/eeprom" % sysfs_sfp_i2c_client_path + + return sysfs_sfp_i2c_client_eeprom_path + + def _read_eeprom_specific_bytes(self, sysfsfile_eeprom, offset, num_bytes): + eeprom_raw = [] + for i in range(0, num_bytes): + eeprom_raw.append("0x00") + + rv, raw = self._sfp_read_file_path(sysfsfile_eeprom, offset, num_bytes) + if rv == False: + return None + + try: + for n in range(0, num_bytes): + eeprom_raw[n] = hex(raw[n])[2:].zfill(2) + except: + return None + + return eeprom_raw + + def get_eeprom_dom_raw(self, port_num): + if port_num in self.qsfp_ports: + # QSFP DOM EEPROM is also at addr 0x50 and thus also stored in eeprom_ifraw + return None + else: + # Read dom eeprom at addr 0x51 + return self._read_eeprom_devid(port_num, self.IDENTITY_EEPROM_ADDR, 256) + + 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 + + cmd = "cat /sys/wb_plat/sff/sff{}/present".format(str(port_num+1)) + ret, output = subprocess.getstatusoutput(cmd) + if ret != 0: + return False + if output == "1": + return True + return False + + def check_is_qsfpdd(self, port_num): + try: + if self.get_presence(port_num) == False: + return False + + eeprom_path = self._get_port_eeprom_path(port_num, 0x50) + with open(eeprom_path, mode="rb", buffering=0) as eeprom: + eeprom_raw = self._read_eeprom_specific_bytes(eeprom, 0, 1) + # according to sff-8024 A0h Byte 0 is '1e' or '18' means the transceiver is qsfpdd + if (eeprom_raw[0] == '1e' or eeprom_raw[0] == '18'): + return True + except Exception as e: + print(traceback.format_exc()) + + return False + + def check_optoe_type(self, port_num, optoe_type): + if self.get_presence(port_num) == False: + return True + try: + eeprom_path = self._get_port_eeprom_path(port_num, 0x50) + dev_class_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/dev_class' + i2c_path = dev_class_path.format(str(self.port_to_i2cbus_mapping[port_num])) + cmd = "cat " + i2c_path + ret, output = subprocess.getstatusoutput(cmd) + if ret != 0: + print("cmd: %s execution fail, output:%s" % (cmd, output)) + return False + if int(output) != optoe_type: + cmd = "echo " + str(optoe_type) + " > " + i2c_path + ret, output = subprocess.getstatusoutput(cmd) + if ret != 0: + print("cmd: %s execution fail, output:%s" % (cmd, output)) + return False + return True + + except Exception as e: + print(traceback.format_exc()) + return False + + def get_low_power_mode(self, port_num): + # Check for invalid port_num + + return True + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + + 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 + + return True + + def get_transceiver_change_event(self, timeout=0): + + start_time = time.time() + current_port_dict = {} + forever = False + + if timeout == 0: + forever = True + elif timeout > 0: + timeout = timeout / float(1000) # Convert to secs + else: + print ("get_transceiver_change_event:Invalid timeout value", timeout) + return False, {} + + end_time = start_time + timeout + if start_time > end_time: + print ('get_transceiver_change_event:' \ + 'time wrap / invalid timeout value', timeout) + + return False, {} # Time wrap or possibly incorrect timeout + + while timeout >= 0: + # Check for OIR events and return updated port_dict + for x in range(self.PORT_START, self.PORTS_IN_BLOCK): + if self.get_presence(x): + current_port_dict[x] = self.SFP_STATUS_INSERTED + else: + current_port_dict[x] = self.SFP_STATUS_REMOVED + if (current_port_dict == self.port_dict): + if forever: + time.sleep(1) + else: + timeout = end_time - time.time() + if timeout >= 1: + time.sleep(1) # We poll at 1 second granularity + else: + if timeout > 0: + time.sleep(timeout) + return True, {} + else: + # Update reg value + self.port_dict = current_port_dict + return True, self.port_dict + print ("get_transceiver_change_event: Should not reach here.") + return False, {} + + def get_highest_temperature(self): + offset = 0 + hightest_temperature = -9999 + + presence_flag = False + read_eeprom_flag = False + temperature_valid_flag = False + + for port in range(self.PORT_START, self.PORTS_IN_BLOCK): + if self.get_presence(port) == False: + continue + + presence_flag = True + + if port in self.qsfp_dd_ports: + offset = 14 + elif port in self.qsfp_ports: + offset = 22 + else: + offset = 96 + + eeprom_path = self._get_port_eeprom_path(port, 0x50) + try: + with open(eeprom_path, mode="rb", buffering=0) as eeprom: + read_eeprom_flag = True + eeprom_raw = self._read_eeprom_specific_bytes(eeprom, offset, 2) + if len(eeprom_raw) != 0: + msb = int(eeprom_raw[0], 16) + lsb = int(eeprom_raw[1], 16) + + result = (msb << 8) | (lsb & 0xff) + result = float(result / 256.0) + if -50 <= result <= 200: + temperature_valid_flag = True + if hightest_temperature < result: + hightest_temperature = result + except Exception as e: + pass + + # all port not presence + if presence_flag == False: + hightest_temperature = -10000 + + # all port read eeprom fail + elif read_eeprom_flag == False: + hightest_temperature = -9999 + + # all port temperature invalid + elif read_eeprom_flag == True and temperature_valid_flag == False: + hightest_temperature = -10000 + + hightest_temperature = round(hightest_temperature, 2) + + return hightest_temperature diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/plugins/ssd_util.py b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/plugins/ssd_util.py new file mode 100644 index 000000000000..e8cf2e1a7cbc --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/plugins/ssd_util.py @@ -0,0 +1,318 @@ +# +# ssd_util.py +# +# Generic implementation of the SSD health API +# SSD models supported: +# - InnoDisk +# - StorFly +# - Virtium + +try: + import re + import os + import subprocess + from sonic_platform_base.sonic_storage.storage_base import StorageBase +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + +SMARTCTL = "smartctl {} -a" +INNODISK = "iSmart -d {}" +VIRTIUM = "SmartCmd -m {}" +DISK_LIST_CMD = "fdisk -l -o Device" +DISK_FREE_CMD = "df -h" +MOUNT_CMD = "mount" + +NOT_AVAILABLE = "N/A" +PE_CYCLE = 3000 +FAIL_PERCENT = 95 + +# Set Vendor Specific IDs +INNODISK_HEALTH_ID = 169 +INNODISK_TEMPERATURE_ID = 194 + +class SsdUtil(StorageBase): + """ + Generic implementation of the SSD health API + """ + model = NOT_AVAILABLE + serial = NOT_AVAILABLE + firmware = NOT_AVAILABLE + temperature = NOT_AVAILABLE + health = NOT_AVAILABLE + remaining_life = NOT_AVAILABLE + sata_rate = NOT_AVAILABLE + ssd_info = NOT_AVAILABLE + vendor_ssd_info = NOT_AVAILABLE + + def __init__(self, diskdev): + self.vendor_ssd_utility = { + "Generic" : { "utility" : SMARTCTL, "parser" : self.parse_generic_ssd_info }, + "InnoDisk" : { "utility" : INNODISK, "parser" : self.parse_innodisk_info }, + "M.2" : { "utility" : INNODISK, "parser" : self.parse_innodisk_info }, + "StorFly" : { "utility" : VIRTIUM, "parser" : self.parse_virtium_info }, + "Virtium" : { "utility" : VIRTIUM, "parser" : self.parse_virtium_info } + } + + """ + The dict model_attr keys relate the vendors + LITEON : "ER2-GD","AF2MA31DTDLT" + Intel : "SSDSCKKB" + SMI : "SM619GXC" + samsung: "MZNLH" + ADATA : "IM2S3134N" + """ + self.model_attr = { + "ER2-GD" : { "temperature" : "\n190\s+(.+?)\n", "remainingLife" : "\n202\s+(.+?)\n" }, + "AF2MA31DTDLT" : { "temperature" : "\n194\s+(.+?)\n", "remainingLife" : "\n202\s+(.+?)\n" }, + "SSDSCK" : { "temperature" : "\n194\s+(.+?)\n", "remainingLife" : "\n233\s+(.+?)\n" }, + "SM619GXC" : { "temperature" : "\n194\s+(.+?)\n", "remainingLife" : "\n169\s+(.+?)\n" }, + "MZNLH" : { "temperature" : "\n190\s+(.+?)\n", "remainingLife" : "\n245\s+(.+?)\n" }, + "IM2S3134N" : { "temperature" : "\n194\s+(.+?)\n", "remainingLife" : "\n231\s+(.+?)\n" }, + "MTFDDAV240TCB-1AR1ZABAA" : { "temperature" : "\n194\s+(.+?)\n", "remainingLife" : "\n202\s+(.+?)\n" } + } + + self.key_list = list(self.model_attr.keys()) + self.attr_info_rule = "[\s\S]*SMART Attributes Data Structure revision number: 1|SMART Error Log Version[\s\S]*" + self.dev = diskdev + # Generic part + self.fetch_generic_ssd_info(diskdev) + self.parse_generic_ssd_info() + self.fetch_vendor_ssd_info(diskdev, "Generic") + + # Known vendor part + if self.model: + model_short = self.model.split()[0] + if model_short in self.vendor_ssd_utility: + self.fetch_vendor_ssd_info(diskdev, model_short) + self.parse_vendor_ssd_info(model_short) + else: + # No handler registered for this disk model + pass + else: + # Failed to get disk model + self.model = "Unknown" + + def _execute_shell(self, cmd): + process = subprocess.Popen(cmd.split(), universal_newlines=True, stdout=subprocess.PIPE) + output, error = process.communicate() + exit_code = process.returncode + if exit_code: + return None + return output + + def _parse_re(self, pattern, buffer): + res_list = re.findall(pattern, str(buffer)) + return res_list[0] if res_list else NOT_AVAILABLE + + def fetch_generic_ssd_info(self, diskdev): + self.ssd_info = self._execute_shell(self.vendor_ssd_utility["Generic"]["utility"].format(diskdev)) + + # Health and temperature values may be overwritten with vendor specific data + def parse_generic_ssd_info(self): + if "nvme" in self.dev: + self.model = self._parse_re('Model Number:\s*(.+?)\n', self.ssd_info) + + health_raw = self._parse_re('Percentage Used\s*(.+?)\n', self.ssd_info) + if health_raw == NOT_AVAILABLE: + self.health = NOT_AVAILABLE + else: + health_raw = health_raw.split()[-1] + self.health = 100 - float(health_raw.strip('%')) + + temp_raw = self._parse_re('Temperature\s*(.+?)\n', self.ssd_info) + if temp_raw == NOT_AVAILABLE: + self.temperature = NOT_AVAILABLE + else: + temp_raw = temp_raw.split()[-2] + self.temperature = float(temp_raw) + else: + self.model = self._parse_re('Device Model:\s*(.+?)\n', self.ssd_info) + model_key = "" + for key in self.key_list: + if re.search(key, self.model): + model_key = key + break + if model_key != "": + self.remaining_life = self._parse_re(self.model_attr[model_key]["remainingLife"], re.sub(self.attr_info_rule,"",self.ssd_info)).split()[2] + self.temperature = self._parse_re(self.model_attr[model_key]["temperature"], re.sub(self.attr_info_rule,"",self.ssd_info)).split()[8] + self.health = self.remaining_life + # Get the LITEON ssd health value by (PE CYCLE - AVG ERASE CYCLE )/(PE CYCLE) + if model_key in ["ER2-GD", "AF2MA31DTDLT"]: + avg_erase = int(self._parse_re('\n173\s+(.+?)\n' ,re.sub(self.attr_info_rule,"",self.ssd_info)).split()[-1]) + self.health = int(round((PE_CYCLE - avg_erase)/PE_CYCLE*100,0)) + if self.remaining_life != NOT_AVAILABLE and int(self.remaining_life) < FAIL_PERCENT: + self.remaining_life = "Fail" + self.sata_rate = self._parse_re('SATA Version is:.*current: (.+?)\)\n', self.ssd_info) + self.serial = self._parse_re('Serial Number:\s*(.+?)\n', self.ssd_info) + self.firmware = self._parse_re('Firmware Version:\s*(.+?)\n', self.ssd_info) + + def parse_innodisk_info(self): + if self.vendor_ssd_info: + self.health = self._parse_re('Health:\s*(.+?)%', self.vendor_ssd_info) + self.temperature = self._parse_re('Temperature\s*\[\s*(.+?)\]', self.vendor_ssd_info) + else: + if self.health == NOT_AVAILABLE: + health_raw = self.parse_id_number(INNODISK_HEALTH_ID) + self.health = health_raw.split()[-1] + if self.temperature == NOT_AVAILABLE: + temp_raw = self.parse_id_number(INNODISK_TEMPERATURE_ID) + self.temperature = temp_raw.split()[-6] + + def parse_virtium_info(self): + if self.vendor_ssd_info: + self.temperature = self._parse_re('Temperature_Celsius\s*\d*\s*(\d+?)\s+', self.vendor_ssd_info) + nand_endurance = self._parse_re('NAND_Endurance\s*\d*\s*(\d+?)\s+', self.vendor_ssd_info) + avg_erase_count = self._parse_re('Average_Erase_Count\s*\d*\s*(\d+?)\s+', self.vendor_ssd_info) + try: + self.health = 100 - (float(avg_erase_count) * 100 / float(nand_endurance)) + except (ValueError, ZeroDivisionError): + # Invalid avg_erase_count or nand_endurance. + pass + + def fetch_vendor_ssd_info(self, diskdev, model): + self.vendor_ssd_info = self._execute_shell(self.vendor_ssd_utility[model]["utility"].format(diskdev)) + + def parse_vendor_ssd_info(self, model): + self.vendor_ssd_utility[model]["parser"]() + + def check_readonly2(self, partition, filesystem): + # parse mount cmd output info + mount_info = self._execute_shell(MOUNT_CMD) + for line in mount_info.split('\n'): + column_list = line.split() + if line == '': + continue + if column_list[0] == partition and column_list[2] == filesystem: + if column_list[5].split(',')[0][1:] == "ro": + return partition + else: + return NOT_AVAILABLE + return NOT_AVAILABLE + + def check_readonly(self, partition, filesystem): + ret = os.access(filesystem, os.W_OK) + if ret == False: + return partition + else: + return NOT_AVAILABLE + + def get_health(self): + """ + Retrieves current disk health in percentages + + Returns: + A float number of current ssd health + e.g. 83.5 + """ + if self.health == 'N/A': + return "NA" + else: + return float(self.health) + + def get_temperature(self): + """ + Retrieves current disk temperature in Celsius + + Returns: + A float number of current temperature in Celsius + e.g. 40.1 + """ + if self.temperature == 'N/A': + return 'NA' + else: + return float(self.temperature) + + def get_model(self): + """ + Retrieves model for the given disk device + + Returns: + A string holding disk model as provided by the manufacturer + """ + return self.model + + def get_firmware(self): + """ + Retrieves firmware version for the given disk device + + Returns: + A string holding disk firmware version as provided by the manufacturer + """ + return self.firmware + + def get_serial(self): + """ + Retrieves serial number for the given disk device + + Returns: + A string holding disk serial number as provided by the manufacturer + """ + return self.serial + def get_sata_rate(self): + """ + Retrieves SATA rate for the given disk device + Returns: + A string holding current SATA rate as provided by the manufacturer + """ + return self.sata_rate + def get_remaining_life(self): + """ + Retrieves remaining life for the given disk device + Returns: + A string holding disk remaining life as provided by the manufacturer + """ + return self.remaining_life + def get_vendor_output(self): + """ + Retrieves vendor specific data for the given disk device + + Returns: + A string holding some vendor specific disk information + """ + return self.vendor_ssd_info + + def parse_id_number(self, id): + return self._parse_re('{}\s*(.+?)\n'.format(id), self.ssd_info) + + def get_readonly_partition(self): + """ + Check the partition mount filesystem is readonly status,then output the result. + Returns: + The readonly partition list + """ + + ro_partition_list = [] + partition_list = [] + + # parse fdisk cmd output info + disk_info = self._execute_shell(DISK_LIST_CMD) + begin_flag = False + for line in disk_info.split('\n'): + if line == "Device": + begin_flag = True + continue + if begin_flag: + if line != "": + partition_list.append(line) + else: + break + + # parse df cmd output info + disk_free = self._execute_shell(DISK_FREE_CMD) + disk_dict = {} + line_num = 0 + for line in disk_free.split('\n'): + line_num = line_num + 1 + if line_num == 1 or line == "": + continue + column_list = line.split() + disk_dict[column_list[0]] = column_list[5] + + # get partition which is readonly + for partition in partition_list: + if partition in disk_dict: + ret = self.check_readonly(partition, disk_dict[partition]) + if (ret != NOT_AVAILABLE): + ro_partition_list.append(ret) + + return ro_partition_list diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/pmon_daemon_control.json b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..94592fa8cebc --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_ledd": true +} diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/postinit_cmd_file.soc b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/postinit_cmd_file.soc new file mode 100644 index 000000000000..6167c3d68f33 --- /dev/null +++ b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/postinit_cmd_file.soc @@ -0,0 +1,7 @@ +led load /usr/share/sonic/platform/custom_led.bin + +led auto on + +led start + +linkscan SwPortBitMap=xe,ce,cd diff --git a/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/system_health_monitoring_config.json b/device/micas/x86_64-micas_m2-w6520-24dc8qc-r0/system_health_monitoring_config.json new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/platform/broadcom/one-image.mk b/platform/broadcom/one-image.mk index 38c1a9521388..caac3b74f1b0 100755 --- a/platform/broadcom/one-image.mk +++ b/platform/broadcom/one-image.mk @@ -98,7 +98,8 @@ $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELL_S6000_PLATFORM_MODULE) \ $(UFISPACE_S9301_32D_PLATFORM_MODULE) \ $(UFISPACE_S9301_32DB_PLATFORM_MODULE) \ $(MICAS_M2_W6510_48V8C_PLATFORM_MODULE) \ - $(MICAS_M2_W6510_48GT4V_PLATFORM_MODULE) + $(MICAS_M2_W6510_48GT4V_PLATFORM_MODULE) \ + $(MICAS_M2_W6520_24DC8QC_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_LAZY_BUILD_INSTALLS = $(BRCM_OPENNSL_KERNEL) $(BRCM_DNX_OPENNSL_KERNEL) ifeq ($(INSTALL_DEBUG_TOOLS),y) diff --git a/platform/broadcom/platform-modules-micas.mk b/platform/broadcom/platform-modules-micas.mk index 5b7fd2cdcb07..fb2277921950 100644 --- a/platform/broadcom/platform-modules-micas.mk +++ b/platform/broadcom/platform-modules-micas.mk @@ -16,3 +16,11 @@ export MICAS_M2_W6510_48GT4V_PLATFORM_MODULE_VERSION MICAS_M2_W6510_48GT4V_PLATFORM_MODULE = platform-modules-micas-m2-w6510-48gt4v_$(MICAS_M2_W6510_48GT4V_PLATFORM_MODULE_VERSION)_amd64.deb $(MICAS_M2_W6510_48GT4V_PLATFORM_MODULE)_PLATFORM = x86_64-micas_m2-w6510-48gt4v-r0 $(eval $(call add_extra_package,$(MICAS_M2_W6510_48V8C_PLATFORM_MODULE),$(MICAS_M2_W6510_48GT4V_PLATFORM_MODULE))) + +## M2-W6520-24DC8QC +MICAS_M2_W6520_24DC8QC_PLATFORM_MODULE_VERSION = 1.0 +export MICAS_M2_W6520_24DC8QC_PLATFORM_MODULE_VERSION + +MICAS_M2_W6520_24DC8QC_PLATFORM_MODULE = platform-modules-micas-m2-w6520-24dc8qc_$(MICAS_M2_W6520_24DC8QC_PLATFORM_MODULE_VERSION)_amd64.deb +$(MICAS_M2_W6520_24DC8QC_PLATFORM_MODULE)_PLATFORM = x86_64-micas_m2-w6520-24dc8qc-r0 +$(eval $(call add_extra_package,$(MICAS_M2_W6510_48V8C_PLATFORM_MODULE),$(MICAS_M2_W6520_24DC8QC_PLATFORM_MODULE))) diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/dev_util/dfd_debug.c b/platform/broadcom/sonic-platform-modules-micas/common/app/dev_util/dfd_debug.c index 93ed6066efed..71d6cd510a88 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/app/dev_util/dfd_debug.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/dev_util/dfd_debug.c @@ -1,3 +1,23 @@ +/* + * An dfd_debug driver for dfd debug function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #include #include #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/dev_util/dfd_utest.c b/platform/broadcom/sonic-platform-modules-micas/common/app/dev_util/dfd_utest.c index c82b0baad4c3..dbf5f8462eb6 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/app/dev_util/dfd_utest.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/dev_util/dfd_utest.c @@ -1,3 +1,22 @@ +/* + * An dfd_utest driver for dfd utest function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ #include #include @@ -1865,10 +1884,6 @@ static int mdiodev_arg_parse(int argc, char* argv[], int *mdio_index, int *phyad } regaddr = strtoul(argv[4], &end, 0); - if (*end || regaddr > 0xffff) { - fprintf(stderr, "Error: regaddr invalid!\n"); - return -EINVAL; - } if (argc > 5) { value = strtoul(argv[5], &end, 0); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/dev_util/dfd_utest.h b/platform/broadcom/sonic-platform-modules-micas/common/app/dev_util/dfd_utest.h index 1ae65148ea9c..71445a449abd 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/app/dev_util/dfd_utest.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/dev_util/dfd_utest.h @@ -1,4 +1,23 @@ -/* monitor_utest.h */ +/* + * A header definition for dfd_utest driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #ifndef __DFD_UTEST_H__ #define __DFD_UTEST_H__ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/fw_upgrade/fw_upgrade/fw_upgrade.c b/platform/broadcom/sonic-platform-modules-micas/common/app/fw_upgrade/fw_upgrade/fw_upgrade.c index 2045608d5c3b..7141ef08be56 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/app/fw_upgrade/fw_upgrade/fw_upgrade.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/fw_upgrade/fw_upgrade/fw_upgrade.c @@ -1,3 +1,23 @@ +/* + * An fw_upgrade driver for firmware upgrade function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #include #include #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/fw_upgrade/fw_upgrade/fw_upgrade_debug.c b/platform/broadcom/sonic-platform-modules-micas/common/app/fw_upgrade/fw_upgrade/fw_upgrade_debug.c index a7a78d011011..0ee3a6f52ef0 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/app/fw_upgrade/fw_upgrade/fw_upgrade_debug.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/fw_upgrade/fw_upgrade/fw_upgrade_debug.c @@ -1,3 +1,23 @@ +/* + * An fw_upgrade_debug driver for firmware upgrade debug function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #include #include #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/fw_upgrade/fw_upgrade/include/fw_upgrade.h b/platform/broadcom/sonic-platform-modules-micas/common/app/fw_upgrade/fw_upgrade/include/fw_upgrade.h index bd806a94b154..aa012b8ab6d7 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/app/fw_upgrade/fw_upgrade/include/fw_upgrade.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/fw_upgrade/fw_upgrade/include/fw_upgrade.h @@ -1,3 +1,23 @@ +/* + * A header definition for fw_upgrade driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #ifndef _FW_UPGRADE_H_ #define _FW_UPGRADE_H_ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/app/fw_upgrade/fw_upgrade/include/fw_upgrade_debug.h b/platform/broadcom/sonic-platform-modules-micas/common/app/fw_upgrade/fw_upgrade/include/fw_upgrade_debug.h index 05911da62a7e..bc6a6ff33404 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/app/fw_upgrade/fw_upgrade/include/fw_upgrade_debug.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/app/fw_upgrade/fw_upgrade/include/fw_upgrade_debug.h @@ -1,3 +1,23 @@ +/* + * A header definition for fw_upgrade_debug driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #ifndef __FW_UPGRADE_DEBUG_H__ #define __FW_UPGRADE_DEBUG_H__ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/algorithm/hysteresis.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/algorithm/hysteresis.py index 81fd596e7fee..34aa0f8866ac 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/algorithm/hysteresis.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/algorithm/hysteresis.py @@ -1,4 +1,20 @@ #!/usr/bin/env python3 +# +# Copyright (C) 2024 Micas 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 os import syslog import copy diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/algorithm/openloop.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/algorithm/openloop.py index 3bb46b286998..3a284230271c 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/algorithm/openloop.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/algorithm/openloop.py @@ -1,4 +1,20 @@ #!/usr/bin/env python3 +# +# Copyright (C) 2024 Micas 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 os import syslog diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/algorithm/pid.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/algorithm/pid.py index 25c2069fea66..93a4ec545627 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/algorithm/pid.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/algorithm/pid.py @@ -1,4 +1,20 @@ #!/usr/bin/env python3 +# +# Copyright (C) 2024 Micas 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 os import syslog import copy diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/cust_fru.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/cust_fru.py index 940c722ce467..ea401f78fd00 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/cust_fru.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/cust_fru.py @@ -1,5 +1,20 @@ #!/usr/bin/python -# -*- coding: utf-8 -*- +# +# Copyright (C) 2024 Micas 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 sys import os diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/fantlv.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/fantlv.py index 4be78e7fdc03..f7f2d7731ed7 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/fantlv.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/fantlv.py @@ -1,5 +1,19 @@ #!/usr/bin/python3 -# -*- coding: utf-8 -*- +# +# Copyright (C) 2024 Micas 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 . class FantlvException(Exception): def __init__(self, message='fantlverror', code=-100): @@ -32,18 +46,34 @@ def dstatus(self): def typename(self): return self._typename + @typename.setter + def typename(self, value): + self._typename = value + @property def typesn(self): return self._typesn + @typesn.setter + def typesn(self, value): + self._typesn = value + @property def typehwinfo(self): return self._typehwinfo + @typehwinfo.setter + def typehwinfo(self, value): + self._typehwinfo = value + @property def typedevtype(self): return self._typedevtype + @typedevtype.setter + def typedevtype(self, value): + self._typedevtype = value + def __init__(self): self._typename = "" self._typesn = "" @@ -61,15 +91,15 @@ def strtoarr(self, val): def hex_to_str(self, s): len_t = len(s) - if len_t % 2 != 0: + if int(len_t % 2) != 0: return 0 ret = "" - for t in range(0, len_t / 2): + for t in range(0, int(len_t / 2)): ret += chr(int(s[2 * t:2 * t + 2], 16)) return ret - def generate_fan_value(self): - bin_buffer = [chr(0xff)] * 256 + def generate_fan_value(self, size=256): + bin_buffer = [chr(0x00)] * size bin_buffer[0] = chr(self.VERSION) bin_buffer[1] = chr(self.FLAG) bin_buffer[2] = chr(self.HW_VER) @@ -80,6 +110,10 @@ def generate_fan_value(self): total_len = len(self.typename) + len(self.typesn) + \ len(self.typehwinfo) + len(typedevtype_t) + 8 + rawdata_len = self._FAN_TLV_HDR_LEN + total_len + 2 + if rawdata_len > size: + raise FantlvException("Generate rg tlv value failed, totallen: %d more than e2_size: %d" % (rawdata_len, size), -10) + bin_buffer[4] = chr(total_len >> 8) bin_buffer[5] = chr(total_len & 0x00FF) diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/fru.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/fru.py index f95164e03601..c409a4e11202 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/fru.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/fru.py @@ -1,7 +1,22 @@ #!/usr/bin/python3 +# +# Copyright (C) 2024 Micas 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 collections from datetime import datetime, timedelta -from bitarray import bitarray __DEBUG__ = "N" @@ -27,17 +42,19 @@ def d_print(debug_info): class FruUtil(): @staticmethod def decodeLength(value): - a = bitarray(8) - a.setall(True) - a[0:1] = 0 - a[1:2] = 0 - x = ord(a.tobytes()) - return x & ord(value) + return 0x3f & ord(value) @staticmethod - def minToData(): + def minToData(endtime = None): starttime = datetime(1996, 1, 1, 0, 0, 0) - endtime = datetime.now() + if isinstance(endtime, str): + try: + endtime = datetime.strptime(endtime, "%Y-%m-%d %H:%M:%S") + except Exception as e: + d_print("Invalid endtime format, endtime: %s, errmsg: %s, used datetime.now" % (endtime, str(e))) + endtime = datetime.now() + else: + endtime = datetime.now() seconds = (endtime - starttime).total_seconds() mins = seconds // 60 m = int(round(mins)) @@ -51,12 +68,7 @@ def getTimeFormat(): def getTypeLength(value): if value is None or len(value) == 0: return 0 - a = bitarray(8) - a.setall(False) - a[0:1] = 1 - a[1:2] = 1 - x = ord(a.tobytes()) - return x | len(value) + return 0xc0 | len(value) @staticmethod def checksum(b): @@ -146,7 +158,7 @@ class BoardInfoArea(BaseArea): def __str__(self): formatstr = "version : %x\n" \ "length : %d \n" \ - "language : %x \n" \ + "language : %d \n" \ "mfg_date : %s \n" \ "boardManufacturer : %s \n" \ "boardProductName : %s \n" \ @@ -247,8 +259,9 @@ def fruSetValue(self, field, value): def recalcute(self): d_print("boardInfoArea version:%x" % ord(self.boardversion)) d_print("boardInfoArea length:%d" % self.size) - d_print("boardInfoArea language:%x" % self.language) - self.mfg_date = FruUtil.minToData() + d_print("boardInfoArea language:%d" % self.language) + + self.mfg_date = FruUtil.minToData(self.mfg_date) d_print("boardInfoArea mfg_date:%x" % self.mfg_date) self.data = chr(ord(self.boardversion)) + \ @@ -396,7 +409,7 @@ class ProductInfoArea(BaseArea): def __str__(self): formatstr = "version : %x\n" \ "length : %d \n" \ - "language : %x \n" \ + "language : %d \n" \ "productManufacturer : %s \n" \ "productName : %s \n" \ "productPartModelName: %s \n" \ @@ -576,7 +589,7 @@ def fruSetValue(self, field, value): def recalcute(self): d_print("product version:%x" % ord(self.areaversion)) d_print("product length:%d" % self.size) - d_print("product language:%x" % self.language) + d_print("product language:%d" % self.language) self.data = chr(ord(self.areaversion)) + \ chr(self.size // 8) + chr(self.language) @@ -928,7 +941,7 @@ def recalcuteCommonHead(self): if totallen < self._frusize: self.bindata = self.bindata.ljust(self._frusize, chr(self.INITVALUE[0])) else: - raise FruException('bin data more than %d' % self._frusize, -2) + raise FruException("Generate fru value failed, totallen: %d more than e2_size: %d" % (totallen, self._frusize), -2) def recalcutebin(self): self.bodybin = "" diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/onietlv.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/onietlv.py index a90f8f8453c8..e61b982ea122 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/onietlv.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/onietlv.py @@ -1,4 +1,20 @@ #!/usr/bin/python3 +# +# Copyright (C) 2024 Micas 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 binascii @@ -12,7 +28,7 @@ def __init__(self, message='onietlverror', code=-100): class onie_tlv(object): TLV_INFO_ID_STRING = "TlvInfo\x00" - TLV_INFO_INIA_ID = "\x00\x00\x13\x11" + TLV_INFO_IANA_HEADER = "\x00" TLV_INFO_VERSION = 0x01 TLV_INFO_LENGTH = 0x00 TLV_INFO_LENGTH_VALUE = 0xba @@ -186,7 +202,7 @@ def generate_ext(self, cardid): ret = chr(0x01) + chr(len(ret)) + ret return ret - def generate_value(self, _t): + def generate_value(self, _t, size=256): ret = [] for i in self.TLV_INFO_ID_STRING: ret.append(i) @@ -195,7 +211,8 @@ def generate_value(self, _t): ret.append(chr(self.TLV_INFO_LENGTH_VALUE)) total_len = 0 - for key in _t: + key_list = sorted(_t.keys()) + for key in key_list: x = self.getTLV_BODY(key, _t[key]) ret += x total_len += len(x) @@ -207,8 +224,11 @@ def generate_value(self, _t): for t in range(0, 4): ret.append(chr(int(s[2 * t + 2:2 * t + 4], 16))) totallen = len(ret) - if totallen < 256: - for left_t in range(0, 256 - totallen): + if totallen > size: + raise OnietlvException("Generate ONIE tlv value failed, totallen: %d more than e2_size: %d" % (totallen, size), -1) + + if totallen < size: + for left_t in range(0, size - totallen): ret.append(chr(0x00)) return (ret, True) @@ -236,7 +256,7 @@ def decode(self, e): ret = self.decode_tlv(e[tlv_index:tlv_end]) for item in ret: if item['code'] == self.TLV_CODE_VENDOR_EXT: - if item["value"][0:4] == self.TLV_INFO_INIA_ID: + if item["value"][0] == self.TLV_INFO_IANA_HEADER: rt = self.decode_tlv(item["value"][4:]) else: rt = self.decode_tlv(item["value"][0:]) diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/wedge.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/wedge.py new file mode 100755 index 000000000000..139977eccc7b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/wedge.py @@ -0,0 +1,418 @@ +#!/usr/bin/python3 +# +# Copyright (C) 2024 Micas 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 + +class WedgeException(Exception): + def __init__(self, message='wedgeerror', code=-100): + err = 'errcode: {0} message:{1}'.format(code, message) + Exception.__init__(self, err) + self.code = code + self.message = message + +class Wedge(): + MAGIC_HEAD_INFO = 0xfbfb + VERSION = 0x03 + WEDGE_SIZE = 196 + + _FBW_EEPROM_F_MAGIC = 2 + _FBW_EEPROM_F_VERSION = 1 + _FBW_EEPROM_F_PRODUCT_NAME = 20 + _FBW_EEPROM_F_PRODUCT_NUMBER = 8 + _FBW_EEPROM_F_ASSEMBLY_NUMBER = 12 + _FBW_EEPROM_F_FACEBOOK_PCBA_NUMBER = 12 + _FBW_EEPROM_F_FACEBOOK_PCB_NUMBER = 12 + _FBW_EEPROM_F_ODM_PCBA_NUMBER = 13 + _FBW_EEPROM_F_ODM_PCBA_SERIAL = 13 + _FBW_EEPROM_F_PRODUCT_STATE = 1 + _FBW_EEPROM_F_PRODUCT_VERSION = 1 + _FBW_EEPROM_F_PRODUCT_SUBVERSION = 1 + _FBW_EEPROM_F_PRODUCT_SERIAL = 13 + _FBW_EEPROM_F_PRODUCT_ASSET = 12 + _FBW_EEPROM_F_SYSTEM_MANUFACTURER = 8 + _FBW_EEPROM_F_SYSTEM_MANU_DATE = 4 + _FBW_EEPROM_F_PCB_MANUFACTURER = 8 + _FBW_EEPROM_F_ASSEMBLED = 8 + _FBW_EEPROM_F_LOCAL_MAC = 12 + _FBW_EEPROM_F_EXT_MAC_BASE = 12 + _FBW_EEPROM_F_EXT_MAC_SIZE = 2 + _FBW_EEPROM_F_LOCATION = 20 + _FBW_EEPROM_F_CRC8 = 1 + + def __init__(self): + self.magic = "" + self.fbw_version = "" + self.fbw_product_name = "" + self.fbw_product_number = "" + self.fbw_assembly_number = "" + self.fbw_facebook_pcba_number = "" + self.fbw_facebook_pcb_number = "" + self.fbw_odm_pcba_number = "" + self.fbw_odm_pcba_serial = "" + self.fbw_production_state = "" + self.fbw_product_version = "" + self.fbw_product_subversion = "" + self.fbw_product_serial = "" + self.fbw_product_asset = "" + self.fbw_system_manufacturer = "" + self.fbw_system_manufacturing_date = "" + self.fbw_system_manufacturing_date_show = "" + self.fbw_pcb_manufacturer = "" + self.fbw_assembled = "" + self.fbw_local_mac = "" + self.fbw_local_mac_show = "" + self.fbw_mac_base = "" + self.fbw_mac_base_show = "" + self.fbw_mac_size = "" + self.fbw_location = "" + self.fbw_crc8 = "" + + def isValidMac(self, mac): + if re.match(r"^\s*([0-9a-fA-F]{2,2}:){5,5}[0-9a-fA-F]{2,2}\s*$", mac): + return True + return False + + def mac_addr_decode(self, origin_mac): + mac = origin_mac.replace("0x", "") + if len(mac) != 12: + msg = "Invalid MAC address: %s" % origin_mac + return False, msg + release_mac = "" + for i in range(len(mac) // 2): + if i == 0: + release_mac += mac[i * 2:i * 2 + 2] + else: + release_mac += ":" + mac[i * 2:i * 2 + 2] + return True, release_mac + + def wedge_crc8(self, v): + # TBD + return '0x00' + + def strtoarr(self, str_tmp, size): + if len(str_tmp) > size: + raise WedgeException("Wedge eeprom str:%s exceed max len: %d" % (str_tmp, size), -10) + + s = [] + for index in str_tmp: + s.append(index) + + append_len = size - len(str_tmp) + if append_len > 0: + append_list = [chr(0x00)] * append_len + s.extend(append_list) + return s + + def generate_value(self, size=256): + bin_buffer = [chr(0x00)] * size + bin_buffer[0] = chr(0xfb) + bin_buffer[1] = chr(0xfb) + bin_buffer[2] = chr(0x03) + + index_start = 3 + # Product Name + bin_buffer[index_start: index_start + self._FBW_EEPROM_F_PRODUCT_NAME] = self.strtoarr(self.fbw_product_name, + self._FBW_EEPROM_F_PRODUCT_NAME) + index_start += self._FBW_EEPROM_F_PRODUCT_NAME + # Product Part Numbe + bin_buffer[index_start: index_start + self._FBW_EEPROM_F_PRODUCT_NUMBER] = self.strtoarr(self.fbw_product_number, + self._FBW_EEPROM_F_PRODUCT_NUMBER) + index_start += self._FBW_EEPROM_F_PRODUCT_NUMBER + + # System Assembly Part Number + bin_buffer[index_start: index_start + self._FBW_EEPROM_F_ASSEMBLY_NUMBER] = self.strtoarr(self.fbw_assembly_number, + self._FBW_EEPROM_F_ASSEMBLY_NUMBER) + index_start += self._FBW_EEPROM_F_ASSEMBLY_NUMBER + + # Facebook PCBA Part Number + bin_buffer[index_start: index_start + self._FBW_EEPROM_F_FACEBOOK_PCBA_NUMBER] = self.strtoarr(self.fbw_facebook_pcba_number, + self._FBW_EEPROM_F_FACEBOOK_PCBA_NUMBER) + index_start += self._FBW_EEPROM_F_FACEBOOK_PCBA_NUMBER + + # Facebook PCB Part Number + bin_buffer[index_start: index_start + self._FBW_EEPROM_F_FACEBOOK_PCB_NUMBER] = self.strtoarr(self.fbw_facebook_pcb_number, + self._FBW_EEPROM_F_FACEBOOK_PCB_NUMBER) + index_start += self._FBW_EEPROM_F_FACEBOOK_PCB_NUMBER + + # ODM PCBA Part Number + bin_buffer[index_start: index_start + self._FBW_EEPROM_F_ODM_PCBA_NUMBER] = self.strtoarr(self.fbw_odm_pcba_number, + self._FBW_EEPROM_F_ODM_PCBA_NUMBER) + index_start += self._FBW_EEPROM_F_ODM_PCBA_NUMBER + + # ODM PCBA Serial Number + bin_buffer[index_start: index_start + self._FBW_EEPROM_F_ODM_PCBA_SERIAL] = self.strtoarr(self.fbw_odm_pcba_serial, + self._FBW_EEPROM_F_ODM_PCBA_SERIAL) + index_start += self._FBW_EEPROM_F_ODM_PCBA_SERIAL + + # Product Production State + if self.fbw_production_state > 0xff: + raise WedgeException("Product Production State: %d config error, exceed 255" + % self.fbw_production_state, -10) + bin_buffer[index_start] = chr(self.fbw_production_state) + index_start += self._FBW_EEPROM_F_PRODUCT_STATE + + # Product Version + if self.fbw_product_version > 0xff: + raise WedgeException("Product Version: %d config error, exceed 255" + % self.fbw_product_version, -10) + bin_buffer[index_start] = chr(self.fbw_product_version) + index_start += self._FBW_EEPROM_F_PRODUCT_VERSION + + # Product Sub Version + if self.fbw_product_subversion > 0xff: + raise WedgeException("Product Sub Version: %d config error, exceed 255" + % self.fbw_product_subversion, -10) + bin_buffer[index_start] = chr(self.fbw_product_subversion) + index_start += self._FBW_EEPROM_F_PRODUCT_SUBVERSION + + # Product Serial Number + bin_buffer[index_start: index_start + self._FBW_EEPROM_F_PRODUCT_SERIAL] = self.strtoarr(self.fbw_product_serial, self._FBW_EEPROM_F_PRODUCT_SERIAL) + index_start += self._FBW_EEPROM_F_PRODUCT_SERIAL + + # Product Asset Tag + bin_buffer[index_start: index_start + self._FBW_EEPROM_F_PRODUCT_ASSET] = self.strtoarr(self.fbw_product_asset, self._FBW_EEPROM_F_PRODUCT_ASSET) + index_start += self._FBW_EEPROM_F_PRODUCT_ASSET + + # System Manufacturer + bin_buffer[index_start: index_start + self._FBW_EEPROM_F_SYSTEM_MANUFACTURER] = self.strtoarr(self.fbw_system_manufacturer, self._FBW_EEPROM_F_SYSTEM_MANUFACTURER) + index_start += self._FBW_EEPROM_F_SYSTEM_MANUFACTURER + + # System Manufacturing Date + if (len(self.fbw_system_manufacturing_date) != 8): + raise WedgeException("System Manufacturing Date config error, value: %s" + % self.fbw_system_manufacturing_date, -10) + + year = int(self.fbw_system_manufacturing_date[0:4]) + month = int(self.fbw_system_manufacturing_date[4:6]) + day = int(self.fbw_system_manufacturing_date[6:8]) + if month < 1 or month > 12 or day < 1 or day > 31: + raise WedgeException("System Manufacturing Date config error, value: %s" + % self.fbw_system_manufacturing_date, -10) + bin_buffer[index_start] = chr(year & 0xff) + bin_buffer[index_start + 1] = chr((year & 0xff00) >> 8) + bin_buffer[index_start + 2] = chr(month) + bin_buffer[index_start + 3] = chr(day) + index_start += self._FBW_EEPROM_F_SYSTEM_MANU_DATE + + # PCB Manufacturer + bin_buffer[index_start: index_start + self._FBW_EEPROM_F_PCB_MANUFACTURER] = self.strtoarr(self.fbw_pcb_manufacturer, + self._FBW_EEPROM_F_PCB_MANUFACTURER) + index_start += self._FBW_EEPROM_F_PCB_MANUFACTURER + + # Assembled At + bin_buffer[index_start: index_start + self._FBW_EEPROM_F_ASSEMBLED] = self.strtoarr(self.fbw_assembled, + self._FBW_EEPROM_F_ASSEMBLED) + index_start += self._FBW_EEPROM_F_ASSEMBLED + + # Local MAC Address + status, mac = self.mac_addr_decode(self.fbw_local_mac) + if self.isValidMac(mac) is False: + msg = "Invalid Local MAC Address: %s" % self.fbw_local_mac + raise WedgeException(msg , -10) + + bin_buffer[index_start: index_start + self._FBW_EEPROM_F_LOCAL_MAC] = self.strtoarr(self.fbw_local_mac, self._FBW_EEPROM_F_LOCAL_MAC) + index_start += self._FBW_EEPROM_F_LOCAL_MAC + # Extended MAC Address + status, mac = self.mac_addr_decode(self.fbw_mac_base) + if self.isValidMac(mac) is False: + msg = "Invalid Extended MAC Address: %s" % self.fbw_mac_base + raise WedgeException(msg , -10) + + bin_buffer[index_start: index_start + self._FBW_EEPROM_F_EXT_MAC_BASE] = self.strtoarr(self.fbw_mac_base, self._FBW_EEPROM_F_EXT_MAC_BASE) + index_start += self._FBW_EEPROM_F_EXT_MAC_BASE + + # Extended MAC Address Size + if self.fbw_mac_size > 0xffff: + raise WedgeException("Extended MAC Address Size: %d config error, exceed 65535" + % self.fbw_mac_size, -10) + bin_buffer[index_start] = chr(self.fbw_mac_size & 0xff) + bin_buffer[index_start + 1] = chr((self.fbw_mac_size & 0xff00) >> 8) + index_start += self._FBW_EEPROM_F_EXT_MAC_SIZE + + # Location on Fabric + bin_buffer[index_start: index_start + self._FBW_EEPROM_F_LOCATION] = self.strtoarr(self.fbw_location, + self._FBW_EEPROM_F_LOCATION) + index_start += self._FBW_EEPROM_F_LOCATION + + # CRC8 + bin_buffer[index_start] = chr(0x00) + index_start += self._FBW_EEPROM_F_CRC8 + return bin_buffer + + def decode(self, e2): + # header check + e2_index = 0 + head = ord(e2[0]) | (ord(e2[1]) << 8) + if head != self.MAGIC_HEAD_INFO: + raise WedgeException("Wedge eeprom head info error, not Wedge eeprom type, head:0x%04x" % head, -10) + self.magic = "0x%04x" % self.MAGIC_HEAD_INFO + e2_index += self._FBW_EEPROM_F_MAGIC + + # E2 format version check + if ord(e2[e2_index]) != self.VERSION: + raise WedgeException("Wedge eeprom version: 0x%02x, not V3 format" % ord(e2[e2_index]), -10) + self.fbw_version = self.VERSION + e2_index += self._FBW_EEPROM_F_VERSION + + # crc + self.fbw_crc8 = ord(e2[self.WEDGE_SIZE-1]) + + # Product Name + self.fbw_product_name = "%s" % (e2[e2_index:e2_index + self._FBW_EEPROM_F_PRODUCT_NAME]) + e2_index += self._FBW_EEPROM_F_PRODUCT_NAME + + # Product Part Numbe + self.fbw_product_number = "%s" % e2[e2_index:e2_index+self._FBW_EEPROM_F_PRODUCT_NUMBER] + #self.fbw_product_number = "%s-%s" % (e2[e2_index:e2_index+2], e2[e2_index + 2: e2_index + 8]) + e2_index += self._FBW_EEPROM_F_PRODUCT_NUMBER + + # System Assembly Part Number + self.fbw_assembly_number = "%s" % e2[e2_index:e2_index+self._FBW_EEPROM_F_ASSEMBLY_NUMBER] + #self.fbw_assembly_number = "%s-%s-%s" % (e2[e2_index:e2_index+3], e2[e2_index+3:e2_index+10], e2[e2_index+10:e2_index+12]) + e2_index += self._FBW_EEPROM_F_ASSEMBLY_NUMBER + + # Facebook PCBA Part Number + self.fbw_facebook_pcba_number = "%s" % e2[e2_index:e2_index+self._FBW_EEPROM_F_FACEBOOK_PCBA_NUMBER] + #self.fbw_facebook_pcba_number = "%s-%s-%s" % (e2[e2_index:e2_index+3], e2[e2_index+3:e2_index+10], e2[e2_index+10:e2_index+12]) + e2_index += self._FBW_EEPROM_F_FACEBOOK_PCBA_NUMBER + + # Facebook PCB Part Number + self.fbw_facebook_pcb_number ="%s" % e2[e2_index:e2_index+self._FBW_EEPROM_F_FACEBOOK_PCB_NUMBER] + #self.fbw_facebook_pcb_number = "%s-%s-%s" % (e2[e2_index:e2_index+3], e2[e2_index+3:e2_index+10], e2[e2_index+10:e2_index+12]) + e2_index += self._FBW_EEPROM_F_FACEBOOK_PCB_NUMBER + + # ODM PCBA Part Number + self.fbw_odm_pcba_number = "%s" % (e2[e2_index:e2_index + self._FBW_EEPROM_F_ODM_PCBA_NUMBER]) + e2_index += self._FBW_EEPROM_F_ODM_PCBA_NUMBER + + # ODM PCBA Serial Number + self.fbw_odm_pcba_serial = "%s" % (e2[e2_index:e2_index + self._FBW_EEPROM_F_ODM_PCBA_SERIAL]) + e2_index += self._FBW_EEPROM_F_ODM_PCBA_SERIAL + + # Product Production State + self.fbw_production_state = (ord(e2[e2_index])) + e2_index += self._FBW_EEPROM_F_PRODUCT_STATE + + # Product Version + self.fbw_product_version = (ord(e2[e2_index])) + e2_index += self._FBW_EEPROM_F_PRODUCT_VERSION + + # Product Version + self.fbw_product_subversion = (ord(e2[e2_index])) + e2_index += self._FBW_EEPROM_F_PRODUCT_SUBVERSION + + # Product Serial Number + self.fbw_product_serial = "%s" % (e2[e2_index:e2_index + self._FBW_EEPROM_F_PRODUCT_SERIAL]) + e2_index += self._FBW_EEPROM_F_PRODUCT_SERIAL + + # Product Asset Tag + self.fbw_product_asset = "%s" % (e2[e2_index:e2_index + self._FBW_EEPROM_F_PRODUCT_ASSET]) + e2_index += self._FBW_EEPROM_F_PRODUCT_ASSET + + # System Manufacturer + self.fbw_system_manufacturer = "%s" % (e2[e2_index:e2_index + self._FBW_EEPROM_F_SYSTEM_MANUFACTURER]) + e2_index += self._FBW_EEPROM_F_SYSTEM_MANUFACTURER + + # System Manufacturing Date + year = ord(e2[e2_index]) | (ord(e2[e2_index + 1]) << 8) + month = ord(e2[e2_index + 2]) + day = ord(e2[e2_index + 3]) + self.fbw_system_manufacturing_date = "%04d%02d%02d" % (year, month, day) + self.fbw_system_manufacturing_date_show = "%02d-%02d-%04d" % (month, day, year) + e2_index += self._FBW_EEPROM_F_SYSTEM_MANU_DATE + + # PCB Manufacturer + self.fbw_pcb_manufacturer = "%s" % (e2[e2_index:e2_index + self._FBW_EEPROM_F_PCB_MANUFACTURER]) + e2_index += self._FBW_EEPROM_F_PCB_MANUFACTURER + + # Assembled At + self.fbw_assembled = "%s" % (e2[e2_index:e2_index + self._FBW_EEPROM_F_ASSEMBLED]) + e2_index += self._FBW_EEPROM_F_ASSEMBLED + + # Local MAC Address + self.fbw_local_mac = "%s" % (e2[e2_index:e2_index + self._FBW_EEPROM_F_LOCAL_MAC]) + status, mac = self.mac_addr_decode(self.fbw_local_mac) + if status is False: + raise WedgeException("Wedge eeprom decode local MAC error, msg: %s" % mac, -10) + self.fbw_local_mac_show = mac.upper() + e2_index += self._FBW_EEPROM_F_LOCAL_MAC + + # Extended MAC Address + self.fbw_mac_base = "%s" % (e2[e2_index:e2_index + self._FBW_EEPROM_F_EXT_MAC_BASE]) + status, mac = self.mac_addr_decode(self.fbw_mac_base) + if status is False: + raise WedgeException("Wedge eeprom decode local MAC error, msg: %s" % mac, -10) + self.fbw_mac_base_show = mac.upper() + e2_index += self._FBW_EEPROM_F_EXT_MAC_BASE + + # Extended MAC Address Size + mac_size = ord(e2[e2_index]) | (ord(e2[e2_index + 1]) << 8) + self.fbw_mac_size = mac_size + e2_index += self._FBW_EEPROM_F_EXT_MAC_SIZE + + # Location on Fabric + self.fbw_location = "%s" % (e2[e2_index:e2_index + self._FBW_EEPROM_F_LOCATION]) + e2_index += self._FBW_EEPROM_F_LOCATION + return + + + def __str__(self): + formatstr = "Version : %d \n" \ + "Product Name : %s \n" \ + "Product Part Number : %s \n" \ + "System Assembly Part Number : %s \n" \ + "Facebook PCBA Part Number : %s \n" \ + "Facebook PCB Part Number : %s \n" \ + "ODM PCBA Part Number : %s \n" \ + "ODM PCBA Serial Number : %s \n" \ + "Product Production State : %d \n" \ + "Product Version : %d \n" \ + "Product Sub-Version : %d \n" \ + "Product Serial Number : %s \n" \ + "Product Asset Tag : %s \n" \ + "System Manufacturer : %s \n" \ + "System Manufacturing Date : %s \n" \ + "PCB Manufacturer : %s \n" \ + "Assembled At : %s \n" \ + "Local MAC : %s \n" \ + "Extended MAC Base : %s \n" \ + "Extended MAC Address Size : %d \n" \ + "Location on Fabric : %s \n" \ + "CRC8 : 0x%02x \n" + str_tmp = formatstr % (self.fbw_version, + self.fbw_product_name, + self.fbw_product_number, + self.fbw_assembly_number, + self.fbw_facebook_pcba_number, + self.fbw_facebook_pcb_number, + self.fbw_odm_pcba_number, + self.fbw_odm_pcba_serial, + self.fbw_production_state, + self.fbw_product_version, + self.fbw_product_subversion, + self.fbw_product_serial, + self.fbw_product_asset, + self.fbw_system_manufacturer, + self.fbw_system_manufacturing_date_show, + self.fbw_pcb_manufacturer, + self.fbw_assembled, + self.fbw_local_mac_show, + self.fbw_mac_base_show, + self.fbw_mac_size, + self.fbw_location, + self.fbw_crc8) + return str_tmp.replace("\x00","") \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/wedge_v5.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/wedge_v5.py new file mode 100755 index 000000000000..4d42865f619b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/eepromutil/wedge_v5.py @@ -0,0 +1,591 @@ +#!/usr/bin/python3 +# +# Copyright (C) 2024 Micas 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 + +class WedgeException(Exception): + def __init__(self, message='wedgeerror', code=-100): + err = 'errcode: {0} message:{1}'.format(code, message) + Exception.__init__(self, err) + self.code = code + self.message = message + +class WedgeV5(): + MAGIC_HEAD_INFO = 0xfbfb + VERSION = 0x05 + + FBWV5_PRODUCT_NAME = 0x01 + FBWV5_PRODUCT_PART_NUMBER = 0x02 + FBWV5_ASSEMBLY_PART_NUMBER = 0x03 + FBWV5_ASSEMBLY_PART_NUMBER_LEN = 8 + FBWV5_META_PCBA_PART_NUMBER = 0x04 + FBWV5_META_PCBA_PART_NUMBER_LEN = 12 + FBWV5_META_PCB_PART_NUMBER = 0x05 + FBWV5_META_PCB_PART_NUMBER_LEN = 12 + FBWV5_ODM_PCBA_PART_NUMBER = 0x06 + FBWV5_ODM_PCBA_SERIAL_NUMBER = 0x07 + FBWV5_PRODUCT_PRODUCTION_STATE = 0x08 + FBWV5_PRODUCT_PRODUCTION_STATE_LEN = 1 + FBWV5_PRODUCT_VERSION = 0x09 + FBWV5_PRODUCT_VERSION_LEN = 1 + FBWV5_PRODUCT_SUB_VERSION = 0x0A + FBWV5_PRODUCT_SUB_VERSION_LEN = 1 + FBWV5_PRODUCT_SERIAL_NUMBER = 0x0B + FBWV5_SYSTEM_MANUFACTURER = 0x0C + FBWV5_SYSTEM_MANUFACTURING_DATE = 0x0D + FBWV5_SYSTEM_MANUFACTURING_DATE_LEN = 8 + FBWV5_PCB_MANUFACTURER = 0x0E + FBWV5_ASSEMBLED_AT = 0x0F + FBWV5_E2_LOCATION_ON_FABRIC = 0x10 + FBWV5_X86_CPU_MAC = 0x11 + FBWV5_X86_CPU_MAC_LEN = 8 + FBWV5_BMC_MAC = 0x12 + FBWV5_BMC_MAC_LEN = 8 + FBWV5_SWITCH_ASIC_MAC = 0x13 + FBWV5_SWITCH_ASIC_MAC_LEN = 8 + FBWV5_META_RESERVED_MAC = 0x14 + FBWV5_META_RESERVED_MAC_LEN = 8 + FBWV5_CRC16 = 0xFA + + + @property + def product_name(self): + return self._ProductName + + @property + def product_part_number(self): + return self._ProductPartNumber + + @property + def assembly_part_number(self): + return self._AssemblyPartNumber + + @property + def meta_pcba_part_number(self): + return self._MetaPCBAPartNumber + + @property + def meta_pcb_part_number(self): + return self._MetaPCBPartNumber + + @property + def odm_pcba_part_number(self): + return self._ODMPCBAPartNumber + + @property + def odm_pcba_serial_number(self): + return self._ODMPCBASerialNumber + + @property + def product_production_state(self): + return self._ProductProductionState + + @property + def product_version(self): + return self._ProductVersion + + @property + def product_sub_version(self): + return self._ProductSubVersion + + @property + def product_serial_number(self): + return self._ProductSerialNumber + + @property + def system_manufacturer(self): + return self._SystemManufacturer + + @property + def system_manufacturing_date(self): + return self._SystemManufacturingDate + + @property + def pcb_manufacturer(self): + return self._PCBManufacturer + + @property + def assembled_at(self): + return self._AssembledAt + + @property + def e2_location_on_fabric(self): + return self._E2LocationOnFabric + + @property + def x86_cpu_mac(self): + return self._X86_CPU_MAC + + @property + def x86_cpu_mac_size(self): + return self._X86_CPU_MAC_SIZE + + @property + def bmc_mac(self): + return self._BMC_MAC + + @property + def bmc_mac_size(self): + return self._BMC_MAC_SIZE + + @property + def switch_asic_mac(self): + return self._SWITCH_ASIC_MAC + + @property + def switch_asic_mac_size(self): + return self._SWITCH_ASIC_MAC_SIZE + + @property + def meta_reserved_mac(self): + return self._MetaReservedMAC + + @property + def meta_reserved_mac_size(self): + return self._MetaReservedMAC_SIZE + + @property + def crc16(self): + return self._crc16 + + + def __init__(self): + self._ProductName = "" + self._ProductPartNumber = "" + self._AssemblyPartNumber = "" + self._MetaPCBAPartNumber = "" + self._MetaPCBPartNumber = "" + self._ODMPCBAPartNumber = "" + self._ODMPCBASerialNumber = "" + self._ProductProductionState = "" + self._ProductVersion = "" + self._ProductSubVersion = "" + self._ProductSerialNumber = "" + self._SystemManufacturer = "" + self._SystemManufacturingDate = "" + self._PCBManufacturer = "" + self._AssembledAt = "" + self._E2LocationOnFabric = "" + self._X86_CPU_MAC = "" + self._X86_CPU_MAC_SIZE = "" + self._BMC_MAC = "" + self._BMC_MAC_SIZE = "" + self._SWITCH_ASIC_MAC = "" + self._SWITCH_ASIC_MAC_SIZE = "" + self._MetaReservedMAC = "" + self._MetaReservedMAC_SIZE = "" + self._crc16 = "" + + def crc_ccitt(self, data, crc_init=0xFFFF, poly=0x1021): + ''' + CRC-16-CCITT Algorithm + ''' + + data_array = bytearray() + for x in data: + data_array.append(ord(x)) + + crc = crc_init + for byte in data_array: + crc ^= byte << 8 + for _ in range(8): + if crc & 0x8000: + crc = (crc << 1) ^ poly + else: + crc <<= 1 + crc &= 0xFFFF + + return '0x%04X' % (crc & 0xFFFF) + + + def check_mac_addr(self, mac): + if re.match(r"^\s*([0-9a-fA-F]{2,2}:){5,5}[0-9a-fA-F]{2,2}\s*$", mac): + return True + return False + + def decoce_mac_and_size(self, value): + mac_addr = ":".join(['%02X' % ord(T) for T in value[0:6]]).upper() + ret = self.check_mac_addr(mac_addr) + if ret is False: + return False, "Invalid MAC address: [%s]" % mac_addr + + mac_size = ((ord(value[6]) << 8) | ord(value[7])) + if mac_size == 0: + return False, "Invalid MAC address size: %d" % mac_size + return True, "" + + def getTLV_BODY(self, tlv_type, value): + x = [] + temp_t = None + if tlv_type == self.FBWV5_ASSEMBLY_PART_NUMBER and len(value) != self.FBWV5_ASSEMBLY_PART_NUMBER_LEN: + if len(value) > self.FBWV5_ASSEMBLY_PART_NUMBER_LEN: + raise WedgeException("Invalid System Assembly Part Number length. value: %s, length: %d, length must less than %d" % + (value, len(value), self.FBWV5_ASSEMBLY_PART_NUMBER_LEN), -1) + temp_list = list(value) + [chr(0x00)] * (self.FBWV5_ASSEMBLY_PART_NUMBER_LEN - len(value)) + temp_t = ''.join(temp_list) + + if tlv_type == self.FBWV5_META_PCBA_PART_NUMBER and len(value) != self.FBWV5_META_PCBA_PART_NUMBER_LEN: + if len(value) > self.FBWV5_META_PCBA_PART_NUMBER_LEN: + raise WedgeException("Invalid Meta PCBA Part Number length. value: %s, length: %d, length must be %d" % + (value, len(value), self.FBWV5_META_PCBA_PART_NUMBER_LEN), -1) + temp_list = list(value) + [chr(0x00)] * (self.FBWV5_META_PCBA_PART_NUMBER_LEN - len(value)) + temp_t = ''.join(temp_list) + + + if tlv_type == self.FBWV5_META_PCB_PART_NUMBER and len(value) != self.FBWV5_META_PCB_PART_NUMBER_LEN: + if len(value) > self.FBWV5_META_PCB_PART_NUMBER_LEN: + raise WedgeException("Invalid Meta PCB Part Number length. value: %s, length: %d, length must be %d" % + (value, len(value), self.FBWV5_META_PCB_PART_NUMBER_LEN), -1) + temp_list = list(value) + [chr(0x00)] * (self.FBWV5_META_PCB_PART_NUMBER_LEN - len(value)) + temp_t = ''.join(temp_list) + + if (tlv_type == self.FBWV5_PRODUCT_PRODUCTION_STATE + or tlv_type == self.FBWV5_PRODUCT_VERSION + or tlv_type == self.FBWV5_PRODUCT_SUB_VERSION): + if not isinstance(value, int) or value > 0xff or value < 0: + raise WedgeException("Invalid Wedge EEPROM Format V5 Tlv type: %d, value: %s" % + (tlv_type, value), -1) + temp_t = chr(value) + + if tlv_type == self.FBWV5_SYSTEM_MANUFACTURING_DATE and len(value) != self.FBWV5_SYSTEM_MANUFACTURING_DATE_LEN: + raise WedgeException("Invalid System Manufacturing Date. value: %s, length: %d, format must YYYYMMDD" + % (value, len(value)), -1) + + if tlv_type == self.FBWV5_X86_CPU_MAC: + if len(value) != self.FBWV5_X86_CPU_MAC_LEN: + raise WedgeException("Invalid X86 CPU MAC length: %d, must be %d" + % (len(value), self.FBWV5_X86_CPU_MAC_LEN), -1) + status, msg = self.decoce_mac_and_size(value) + if status is False: + raise WedgeException("Decode X86 CPU MAC failed, msg: %s" % (value, msg), -1) + + if tlv_type == self.FBWV5_BMC_MAC: + if len(value) != self.FBWV5_BMC_MAC_LEN: + raise WedgeException("Invalid BMC MAC length: %d, must be %d" + % (len(value), self.FBWV5_BMC_MAC_LEN), -1) + status, msg = self.decoce_mac_and_size(value) + if status is False: + raise WedgeException("Decode BMC MAC failed, msg: %s" % (value, msg), -1) + + if tlv_type == self.FBWV5_SWITCH_ASIC_MAC: + if len(value) != self.FBWV5_SWITCH_ASIC_MAC_LEN: + raise WedgeException("Invalid Switch ASIC MAC length: %d, must be %d" + % (len(value), self.FBWV5_SWITCH_ASIC_MAC_LEN), -1) + status, msg = self.decoce_mac_and_size(value) + if status is False: + raise WedgeException("Decode Switch ASIC MAC failed, msg: %s" % (value, msg), -1) + + if tlv_type == self.FBWV5_META_RESERVED_MAC: + if len(value) != self.FBWV5_META_RESERVED_MAC_LEN: + raise WedgeException("Invalid META Reserved MAC length: %d, must be %d" + % (len(value), self.FBWV5_META_RESERVED_MAC_LEN), -1) + status, msg = self.decoce_mac_and_size(value) + if status is False: + raise WedgeException("Decode META Reserved MAC failed, msg: %s" % (value, msg), -1) + + if temp_t is None: + temp_t = value + + x.append(chr(tlv_type)) + x.append(chr(len(temp_t))) + for i in temp_t: + x.append(i) + return x + + def generate_value(self, _t, size=256): + ret = [] + ret.append(chr(0xfb)) + ret.append(chr(0xfb)) + ret.append(chr(self.VERSION)) + ret.append(chr(0xff)) + + key_list = sorted(_t.keys()) + for key in key_list: + x = self.getTLV_BODY(key, _t[key]) + ret += x + + crc16_str = self.crc_ccitt(ret) + crc16_val = int(crc16_str, 16) + + ret.append(chr(self.FBWV5_CRC16)) + ret.append(chr(0x02)) + ret.append(chr((crc16_val >> 8) & 0xff)) + ret.append(chr((crc16_val & 0xff))) + + totallen = len(ret) + if (totallen > size): + raise WedgeException("Generate Wedge EEPROM Format V5 failed, totallen: %d more than e2_size: %d" + % (totallen, size), -1) + if (totallen < size): + for left_t in range(0, size - totallen): + ret.append(chr(0x00)) + return ret + + def decoder(self, t): + ret = [] + if ord(t[0]) == self.FBWV5_PRODUCT_NAME: + name = "Product Name" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._ProductName = value + elif ord(t[0]) == self.FBWV5_PRODUCT_PART_NUMBER: + name = "Product Part Number" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._ProductPartNumber = value + elif ord(t[0]) == self.FBWV5_ASSEMBLY_PART_NUMBER: + name = "System Assembly Part Number" + _len = ord(t[1]) + if _len != self.FBWV5_ASSEMBLY_PART_NUMBER_LEN: + raise WedgeException("Invalid System Assembly Part Number len: %d" % _len, -1) + value = t[2:2 + ord(t[1])] + self._AssemblyPartNumber = value + elif ord(t[0]) == self.FBWV5_META_PCBA_PART_NUMBER: + name = "Meta PCBA Part Number" + _len = ord(t[1]) + if _len != self.FBWV5_META_PCBA_PART_NUMBER_LEN: + raise WedgeException("Invalid Meta PCBA Part Number len: %d" % _len, -1) + value = t[2:2 + ord(t[1])] + self._MetaPCBAPartNumber = value + elif ord(t[0]) == self.FBWV5_META_PCB_PART_NUMBER: + name = "Meta PCB Part Number" + _len = ord(t[1]) + if _len != self.FBWV5_META_PCB_PART_NUMBER_LEN: + raise WedgeException("Invalid Meta PCB Part Number len: %d" % _len, -1) + value = t[2:2 + ord(t[1])] + self._MetaPCBPartNumber = value + elif ord(t[0]) == self.FBWV5_ODM_PCBA_PART_NUMBER: + name = "ODM/JDM PCBA Part Number" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._ODMPCBAPartNumber = value + elif ord(t[0]) == self.FBWV5_ODM_PCBA_SERIAL_NUMBER: + name = "ODM/JDM PCBA Serial Number" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._ODMPCBASerialNumber = value + elif ord(t[0]) == self.FBWV5_PRODUCT_PRODUCTION_STATE: + name = "Product Production State" + _len = ord(t[1]) + if _len != self.FBWV5_PRODUCT_PRODUCTION_STATE_LEN: + raise WedgeException("Invalid Product Production State len: %d" % _len, -1) + value = ord(t[2]) + self._ProductProductionState = value + elif ord(t[0]) == self.FBWV5_PRODUCT_VERSION: + name = "Product Version" + _len = ord(t[1]) + if _len != self.FBWV5_PRODUCT_VERSION_LEN: + raise WedgeException("Invalid Product Version len: %d" % _len, -1) + value = ord(t[2]) + self._ProductVersion = value + elif ord(t[0]) == self.FBWV5_PRODUCT_SUB_VERSION: + name = "Product Sub-Version" + _len = ord(t[1]) + if _len != self.FBWV5_PRODUCT_SUB_VERSION_LEN: + raise WedgeException("Invalid Product Sub-Version len: %d" % _len, -1) + value = ord(t[2]) + self._ProductSubVersion = value + elif ord(t[0]) == self.FBWV5_PRODUCT_SERIAL_NUMBER: + name = "Product Serial Number" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._ProductSerialNumber = value + elif ord(t[0]) == self.FBWV5_SYSTEM_MANUFACTURER: + name = "System Manufacturer" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._SystemManufacturer = value + elif ord(t[0]) == self.FBWV5_SYSTEM_MANUFACTURING_DATE: + name = "System Manufacturing Date" + _len = ord(t[1]) + if _len != self.FBWV5_SYSTEM_MANUFACTURING_DATE_LEN: + raise WedgeException("Invalid System Manufacturing Date len: %d" % _len, -1) + value = t[2:2 + ord(t[1])] + self._SystemManufacturingDate = value + elif ord(t[0]) == self.FBWV5_PCB_MANUFACTURER: + name = "PCB Manufacturer" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._PCBManufacturer = value + elif ord(t[0]) == self.FBWV5_ASSEMBLED_AT: + name = "Assembled at" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._AssembledAt = value + elif ord(t[0]) == self.FBWV5_E2_LOCATION_ON_FABRIC: + name = "EEPROM location on Fabric" + _len = ord(t[1]) + value = t[2:2 + ord(t[1])] + self._E2LocationOnFabric = value + elif ord(t[0]) == self.FBWV5_X86_CPU_MAC: + name = "X86 CPU MAC Base" + _len = ord(t[1]) + if _len != self.FBWV5_X86_CPU_MAC_LEN: + raise WedgeException("Invalid X86 CPU MAC Base len: %d" % _len, -1) + value = ":".join(['%02X' % ord(T) for T in t[2:8]]).upper() + self._X86_CPU_MAC = value + ret.append({"name": name, "code": ord(t[0]), "value": value, "lens": 6}) + # X86 CPU MAC Address Size + name = "X86 CPU MAC Address Size" + _len = 2 + value = ((ord(t[8]) << 8) | ord(t[9])) + self._X86_CPU_MAC_SIZE = value + elif ord(t[0]) == self.FBWV5_BMC_MAC: + name = "BMC MAC Base" + _len = ord(t[1]) + if _len != self.FBWV5_BMC_MAC_LEN: + raise WedgeException("Invalid BMC MAC Base len: %d" % _len, -1) + value = ":".join(['%02X' % ord(T) for T in t[2:8]]).upper() + self._BMC_MAC = value + ret.append({"name": name, "code": ord(t[0]), "value": value, "lens": 6}) + # BMC MAC Address Size + name = "BMC MAC Address Size" + _len = 2 + value = ((ord(t[8]) << 8) | ord(t[9])) + self._BMC_MAC_SIZE = value + elif ord(t[0]) == self.FBWV5_SWITCH_ASIC_MAC: + name = "Switch ASIC MAC Base" + _len = ord(t[1]) + if _len != self.FBWV5_SWITCH_ASIC_MAC_LEN: + raise WedgeException("Invalid Switch ASIC MAC Base len: %d" % _len, -1) + value = ":".join(['%02X' % ord(T) for T in t[2:8]]).upper() + self._SWITCH_ASIC_MAC = value + ret.append({"name": name, "code": ord(t[0]), "value": value, "lens": 6}) + # Switch ASIC MAC Address Size + name = "Switch ASIC MAC Address Size" + _len = 2 + value = ((ord(t[8]) << 8) | ord(t[9])) + self._SWITCH_ASIC_MAC_SIZE = value + elif ord(t[0]) == self.FBWV5_META_RESERVED_MAC: + name = "META Reserved MAC Base" + _len = ord(t[1]) + if _len != self.FBWV5_META_RESERVED_MAC_LEN: + raise WedgeException("Invalid META Reserved MAC Base len: %d" % _len, -1) + value = ":".join(['%02X' % ord(T) for T in t[2:8]]).upper() + self._MetaReservedMAC = value + ret.append({"name": name, "code": ord(t[0]), "value": value, "lens": 6}) + # META Reserved MAC Address Size + name = "META Reserved MAC Address Size" + _len = 2 + value = ((ord(t[8]) << 8) | ord(t[9])) + self._MetaReservedMAC_SIZE = value + elif ord(t[0]) == self.FBWV5_CRC16 and len(t) == 4: + name = "CRC16" + _len = ord(t[1]) + value = "0x%04X" % ((ord(t[2]) << 8) | (ord(t[3]))) + self._crc16 = value + else: + name = "Unknown" + _len = ord(t[1]) + value = "" + for c in t[2:2 + ord(t[1])]: + value += "0x%02X " % (ord(c),) + raise WedgeException("Unknown Wedge EEPROM Format V5 TLV type: 0x%02x, len: %d, value: %s" % (ord(t[0]), ord(t[1]), value), -1) + ret.append({"name": name, "code": ord(t[0]), "value": value, "lens": _len}) + return ret + + + def decode_tlv(self, e2): + tlv_index = 0 + tlv_end = len(e2) + ret = [] + while tlv_index < tlv_end: + rt = self.decoder(e2[tlv_index:tlv_index + 2 + ord(e2[tlv_index + 1])]) + ret.extend(rt) + if ord(e2[tlv_index]) == self.FBWV5_CRC16: + break + tlv_index += ord(e2[tlv_index + 1]) + 2 + return ret, tlv_index + + def decode(self, e2): + e2_index = 0 + head = ord(e2[0]) | (ord(e2[1]) << 8) + if head != self.MAGIC_HEAD_INFO: + raise WedgeException("Wedge eeprom head info error, not Wedge eeprom type, head:0x%04x" % head, -10) + e2_index += 2 + + # E2 Version check + if ord(e2[e2_index]) != self.VERSION: + raise WedgeException("Wedge eeprom version: 0x%02x, not V5 format" % ord(e2[e2_index]), -10) + e2_index += 1 + + # one byte Reserved + e2_index += 1 + + ret, tlv_data_len = self.decode_tlv(e2[e2_index:]) + + # check crc + e2_crc_data_len = tlv_data_len + 4 # two byte Magic word + one byte Format Version + one byte Reserved + + crc_calc = self.crc_ccitt(e2[0:e2_crc_data_len]) + crc_read = self.crc16 + if crc_calc != crc_read: + print("Wedge EEPROM Format V5 crc error, calc value: %s, read value: %s" % (crc_calc, crc_read), -1) + + return ret + + def __str__(self): + formatstr = "Product Name : %s \n" \ + "Product Part Number : %s \n" \ + "System Assembly Part Number : %s \n" \ + "Meta PCBA Part Number : %s \n" \ + "Meta PCB Part Number : %s \n" \ + "ODM/JDM PCBA Part Number : %s \n" \ + "ODM/JDM PCBA Serial Number : %s \n" \ + "Product Production State : %s \n" \ + "Product Version : %s \n" \ + "Product Sub-Version : %s \n" \ + "Product Serial Number : %s \n" \ + "System Manufacturer : %s \n" \ + "System Manufacturing Date : %s \n" \ + "PCB Manufacturer : %s \n" \ + "Assembled at : %s \n" \ + "EEPROM location on Fabric : %s \n" \ + "X86 CPU MAC Base : %s \n" \ + "X86 CPU MAC Address Size : %s \n" \ + "BMC MAC Base : %s \n" \ + "BMC MAC Address Size : %s \n" \ + "Switch ASIC MAC Base : %s \n" \ + "Switch ASIC MAC Address Size : %s \n" \ + "META Reserved MAC Base : %s \n" \ + "META Reserved MAC Address Size : %s \n" \ + "CRC16 : %s \n" + return formatstr % (self.product_name, + self.product_part_number, + self.assembly_part_number, + self.meta_pcba_part_number, + self.meta_pcb_part_number, + self.odm_pcba_part_number, + self.odm_pcba_serial_number, + self.product_production_state, + self.product_version, + self.product_sub_version, + self.product_serial_number, + self.system_manufacturer, + self.system_manufacturing_date, + self.pcb_manufacturer, + self.assembled_at, + self.e2_location_on_fabric, + self.x86_cpu_mac, + self.x86_cpu_mac_size, + self.bmc_mac, + self.bmc_mac_size, + self.switch_asic_mac, + self.switch_asic_mac_size, + self.meta_reserved_mac, + self.meta_reserved_mac_size, + self.crc16) \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/baseutil.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/baseutil.py index abf0ecf97d6b..12f9aa881daf 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/baseutil.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/baseutil.py @@ -1,10 +1,20 @@ #!/usr/bin/env python3 -####################################################### # -# baseutil.py -# Python implementation of the Class baseutil +# Copyright (C) 2024 Micas 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 importlib.machinery import os import syslog diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/chassisbase.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/chassisbase.py index 767d6da34ba9..ea1ef4930a15 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/chassisbase.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/chassisbase.py @@ -1,21 +1,31 @@ #!/usr/bin/env python3 -####################################################### # -# chassisbase.py -# Python implementation of the Class chassisbase +# Copyright (C) 2024 Micas 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 os from plat_hal.dcdc import dcdc from plat_hal.onie_e2 import onie_e2 from plat_hal.psu import psu from plat_hal.led import led -from plat_hal.temp import temp +from plat_hal.temp import temp, temp_s3ip from plat_hal.fan import fan from plat_hal.cpld import cpld from plat_hal.component import component from plat_hal.cpu import cpu from plat_hal.baseutil import baseutil - +from plat_hal.osutil import osutil class chassisbase(object): __onie_e2_list = [] @@ -89,6 +99,52 @@ def __init__(self, conftype=0, conf=None): temptemp.append(temp1) self.temp_list = temptemp + ''' + sensor print source select + ''' + self.__sensor_print_src = __confTemp.get("sensor_print_src", None) + + # temp_data_source. the following is example: + ''' + "temp_data_source": [ + { + "path": "/sys/s3ip/temp_sensor/", + "type": "temp", + "Unit": Unit.Temperature, + "read_times": 3, + "format": "float(float(%s)/1000)" + }, + ], + ''' + tmp_list = [] + temp_data_source_conf = __confTemp.get("temp_data_source", {}) + for item in temp_data_source_conf: + try: + path = item.get("path", None) + if path is None: + continue + sensor_type = item.get("type", None) + if sensor_type is None: + continue + number_path = "%s/%s" % (path, "number") + ret, number = osutil.readsysfs(number_path) + if ret is True: + for index in range(1, int(number) + 1): + sensor_dir = "%s%d" % (sensor_type, index) + # only monitored sensor add to list + monitor_flag_path = "%s/%s/%s" % (path, sensor_dir, "monitor_flag") + if os.path.exists(monitor_flag_path): + ret, monitor_flag = osutil.readsysfs(monitor_flag_path) + if ret is True and int(monitor_flag) == 0: + continue + s3ip_conf = item.copy() + s3ip_conf["sensor_dir"] = sensor_dir + obj = temp_s3ip(s3ip_conf) + tmp_list.append(obj) + except Exception: + pass + self.temp_list_s3ip = tmp_list + # fan fantemp = [] fanconfig = __confTemp.get('fans', []) @@ -105,6 +161,54 @@ def __init__(self, conftype=0, conf=None): dcdctemp.append(dcdc1) self.dcdc_list = dcdctemp + # dcdc_data_source. the following is example: + ''' + "dcdc_data_source": [ + { + "path": "/sys/s3ip/vol_sensor/", + "type": "vol", + "Unit": Unit.Voltage, + "read_times": 3, + "format": "float(float(%s)/1000)" + }, + { + "path": "/sys/s3ip/curr_sensor/", + "type": "curr", + "Unit": Unit.Current, + "read_times": 3, + "format": "float(float(%s)/1000)" + }, + ], + ''' + dcdc_data_source_conf = __confTemp.get("dcdc_data_source", {}) + tmp_list = [] + for item in dcdc_data_source_conf: + try: + path = item.get("path", None) + if path is None: + continue + sensor_type = item.get("type", None) + if sensor_type is None: + continue + number_path = "%s/%s" % (path, "number") + ret, number = osutil.readsysfs(number_path) + if ret is True: + for index in range(1, int(number) + 1): + sensor_dir = "%s%d" % (sensor_type, index) + # only monitored sensor add to list + monitor_flag_path = "%s/%s/%s" % (path, sensor_dir, "monitor_flag") + if os.path.exists(monitor_flag_path): + ret, monitor_flag = osutil.readsysfs(monitor_flag_path) + if ret is True and int(monitor_flag) == 0: + continue + s3ip_conf = item.copy() + s3ip_conf["sensor_dir"] = sensor_dir + dcdc_obj = dcdc(s3ip_conf = s3ip_conf) + tmp_list.append(dcdc_obj) + except Exception: + pass + self.dcdc_list.extend(tmp_list) + # cpld cpldtemp = [] cpldconfig = __confTemp.get('cplds', []) @@ -316,3 +420,7 @@ def cpu(self, val): def get_cpu_byname(self, name): return self.cpu + + @property + def sensor_print_src(self): + return self.__sensor_print_src diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/component.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/component.py index 0f2ad2167485..e0cd231308fa 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/component.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/component.py @@ -1,10 +1,20 @@ #!/usr/bin/env python3 -####################################################### # -# component.py -# Python implementation of the Class fan +# Copyright (C) 2024 Micas 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 . + from plat_hal.devicebase import devicebase from plat_hal.osutil import osutil diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/cpld.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/cpld.py index 09eed5f975ee..b0abe6e9c302 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/cpld.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/cpld.py @@ -1,10 +1,20 @@ #!/usr/bin/env python3 -####################################################### # -# fan.py -# Python implementation of the Class fan +# Copyright (C) 2024 Micas 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 . + from plat_hal.devicebase import devicebase diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/cpu.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/cpu.py index c6bec1abd1c2..8fb1d70e57e0 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/cpu.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/cpu.py @@ -1,9 +1,20 @@ #!/usr/bin/env python3 -############################################################################### # -# Hardware Abstraction Layer APIs -- CPU APIs. +# Copyright (C) 2024 Micas 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 . + from plat_hal.devicebase import devicebase diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/dcdc.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/dcdc.py index ba604995043d..719680f878b6 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/dcdc.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/dcdc.py @@ -1,11 +1,30 @@ #!/usr/bin/env python3 -from plat_hal.devicebase import devicebase -from plat_hal.sensor import sensor +# +# Copyright (C) 2024 Micas 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 . +from plat_hal.devicebase import devicebase +from plat_hal.sensor import sensor, sensor_s3ip class dcdc(devicebase): - def __init__(self, conf=None): + def __init__(self, conf = None, s3ip_conf = None): if conf is not None: self.name = conf.get('name', None) self.dcdc_id = conf.get("dcdc_id", None) self.sensor = sensor(conf) + if s3ip_conf is not None: + self.sensor = sensor_s3ip(s3ip_conf) + self.name = self.sensor.name + self.dcdc_id = self.sensor.sensor_id diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/devicebase.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/devicebase.py index 001b4ee239bf..4d8eb6dcf511 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/devicebase.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/devicebase.py @@ -1,10 +1,20 @@ #!/usr/bin/env python3 -####################################################### # -# devicebase.py -# Python implementation of the Class devicebase +# Copyright (C) 2024 Micas 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 subprocess import shlex import ast @@ -30,6 +40,8 @@ def get_op_value(self, node): value = node.n elif isinstance(node, ast.Str): # node is Str Constant value = node.s + elif isinstance(node, ast.List): # node is List Constant + value = [element.value for element in node.elts] else: raise NotImplementedError("Unsupport operand type: %s" % type(node)) return value @@ -78,7 +90,7 @@ def visit_Call(self, node): int support one or two parameters, eg: int(xxx) or int(xxx, 16) xxx can be ast.Call/ast.Constant(ast.Num/ast.Str)/ast.BinOp ''' - calc_tuple = ("float", "int", "str") + calc_tuple = ("float", "int", "str", "max", "min") if node.func.id not in calc_tuple: raise NotImplementedError("Unsupport function call type: %s" % node.func.id) @@ -86,7 +98,10 @@ def visit_Call(self, node): args_val_list = [] for item in node.args: ret = self.get_op_value(item) - args_val_list.append(ret) + if isinstance(ret, list): + args_val_list.extend(ret) + else: + args_val_list.append(ret) if node.func.id == "str": if len(args_val_list) != 1: @@ -101,6 +116,16 @@ def visit_Call(self, node): value = float(args_val_list[0]) self.value = value return value + + if node.func.id == "max": + value = max(args_val_list) + self.value = value + return value + + if node.func.id == "min": + value = min(args_val_list) + self.value = value + return value # int if len(args_val_list) == 1: value = int(args_val_list[0]) diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/fan.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/fan.py index 5b33af02527c..80543bec83a2 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/fan.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/fan.py @@ -1,12 +1,23 @@ #!/usr/bin/env python3 -####################################################### # -# fan.py -# Python implementation of the Class fan +# Copyright (C) 2024 Micas 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 . + from eepromutil.fru import ipmifru from eepromutil.fantlv import fan_tlv +from eepromutil.wedge_v5 import WedgeV5 from plat_hal.devicebase import devicebase from plat_hal.rotor import rotor @@ -50,6 +61,7 @@ def __init__(self, conf=None): self.EnableWatchdogConf = conf.get('EnableWatchdogConf', None) self.led_attrs_config = conf.get('led_attrs', None) self.led_config = conf.get('led', None) + self.led_map = conf.get('led_map', None) self.Rotor_config = conf.get('Rotor', None) self.fan_display_name_conifg = conf.get("fan_display_name", None) rotor_tmp = [] @@ -228,6 +240,12 @@ def get_led(self): if ret is False or value is None: return False, 'N/A' ledval = int(value) & mask + if self.led_map is not None: + led_color = self.led_map.get(ledval, None) + if led_color is None: + return False, 'N/A' + return True, led_color + for key, val in self.led_attrs_config.items(): if (ledval == val) and (key != "mask"): return True, key @@ -256,7 +274,7 @@ def get_rotor_byname(self, rotor_index): def get_presence(self): ret, val = self.get_value(self.present) - if ret is False or val is None or val == "no_support": + if ret is False or val is None or val == "no_support" or val == "NA" or val == "ACCESS FAILED": return False if isinstance(val, str): value = int(val, 16) @@ -273,9 +291,10 @@ def get_speed_pwm(self, rotor_index): rotor_item = self.get_rotor_index(rotor_index) if rotor_item is None: return False - if rotor_item.i2c_speed is None: + speed_pwm = rotor_item.i2c_speed + if speed_pwm is None: return False - val = round(rotor_item.i2c_speed * 100 / 255) + val = round(speed_pwm * 100 / 255) return val def feed_watchdog(self): @@ -286,16 +305,39 @@ def feed_watchdog(self): return ret return ret - def get_fru_info(self): + def get_wedge_v5_info(self, eeprom): + try: + product_version = None + product_sub_version = None + wegdev5 = WedgeV5() + rets = wegdev5.decode(eeprom) + for item in rets: + if item["code"] == wegdev5.FBWV5_PRODUCT_NAME: + self.productName = item["value"].replace("\x00", "").strip() + elif item["code"] == wegdev5.FBWV5_PRODUCT_SERIAL_NUMBER: + self.productSerialNumber = item["value"].replace("\x00", "").strip() + elif item["code"] == wegdev5.FBWV5_PRODUCT_VERSION: + product_version = "%d" % item["value"] + elif item["code"] == wegdev5.FBWV5_PRODUCT_SUB_VERSION: + product_sub_version = "%02d" % item["value"] + if product_version is not None and product_sub_version is not None: + self.hw_version = product_version + "." + product_sub_version + elif product_version is not None: + self.hw_version = product_version + elif product_sub_version is not None: + self.hw_version = product_sub_version + else: + self.hw_version = None + except Exception: + self.productName = None + self.productSerialNumber = None + self.hw_version = None + return False + return True + + def get_fru_info(self, eeprom): try: - if self.get_presence() is False: - raise Exception("%s: not present" % self.name) - eeprom = self.get_eeprom_info(self.e2loc) - if eeprom is None: - raise Exception("%s: value is none" % self.name) fru = ipmifru() - if isinstance(eeprom, bytes): - eeprom = self.byteTostr(eeprom) fru.decodeBin(eeprom) self.productName = fru.productInfoArea.productName.strip() # PN self.productSerialNumber = fru.productInfoArea.productSerialNumber.strip() # SN @@ -307,13 +349,8 @@ def get_fru_info(self): return False return True - def get_tlv_info(self): + def get_tlv_info(self, eeprom): try: - if self.get_presence() is False: - raise Exception("%s: not present" % self.name) - eeprom = self.get_eeprom_info(self.e2loc) - if eeprom is None: - raise Exception("%s: value is none" % self.name) tlv = fan_tlv() rets = tlv.decode(eeprom) for item in rets: @@ -330,14 +367,53 @@ def get_tlv_info(self): return False return True + def decode_eeprom_by_type(self, e2_type, eeprom): + if e2_type == "fru": + return self.get_fru_info(eeprom) + + if e2_type == "fantlv": + return self.get_tlv_info(eeprom) + + if e2_type == "wedge_v5": + return self.get_wedge_v5_info(eeprom) + return False + + def decode_eeprom_by_traverse(self, eeprom): + support_e2_type = ("fru", "fantlv", "wedge_v5") + for e2_type in support_e2_type: + status = self.decode_eeprom_by_type(e2_type, eeprom) + if status is True: + return True + return False + def decode_eeprom_info(self): '''get fan name, hw version, sn''' - if self.e2_type == "fru": - return self.get_fru_info() + try: + if self.get_presence() is False: + raise Exception("%s: not present" % self.name) - if self.e2_type == "fantlv": - return self.get_tlv_info() + eeprom = self.get_eeprom_info(self.e2loc) + if eeprom is None: + raise Exception("%s: value is none" % self.name) + + if isinstance(eeprom, bytes): + eeprom = self.byteTostr(eeprom) + if self.e2_type is None: + return self.decode_eeprom_by_traverse(eeprom) + + if isinstance(self.e2_type, str): + return self.decode_eeprom_by_type(self.e2_type, eeprom) + + if isinstance(self.e2_type, list): + for e2_type in self.e2_type: + status = self.decode_eeprom_by_type(e2_type, eeprom) + if status is True: + return True + except Exception: + self.productName = None + self.productSerialNumber = None + self.hw_version = None return False def get_AirFlow(self): diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/interface.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/interface.py index 88873a029b64..e12c469e612b 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/interface.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/interface.py @@ -1,13 +1,23 @@ #!/usr/bin/env python3 -####################################################### # -# interface.py -# Python implementation of the Class interface +# Copyright (C) 2024 Micas 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 collections from plat_hal.chassisbase import chassisbase -from plat_hal.baseutil import baseutil +from plat_hal.baseutil import baseutil, getplatform_name from plat_hal.osutil import osutil @@ -864,7 +874,7 @@ def get_dcdc_all_info(self): tmp = dcdc.sensor.Value if tmp is not None: dicttmp['Value'] = tmp - if tmp > dicttmp['Max'] or tmp < dicttmp['Min']: + if tmp > float(dicttmp['Max']) or tmp < float(dicttmp['Min']): dicttmp["Status"] = "NOT OK" else: dicttmp["Status"] = "OK" @@ -914,6 +924,8 @@ def get_monitor_temp_by_id(self, temp_id): dic["High"] = self.error_ret dic["Value"] = self.error_ret dic["Unit"] = self.error_ret + dic["Invalid"] = self.error_ret + dic["Error"] = self.error_ret else: dic["Name"] = temptmp.name dic["Api_name"] = temptmp.api_name @@ -924,6 +936,8 @@ def get_monitor_temp_by_id(self, temp_id): temp_value = temptmp.Value dic["Value"] = temp_value if (temp_value is not None) else self.error_ret dic["Unit"] = temptmp.Unit + dic["Invalid"] = temptmp.temp_invalid + dic["Error"] = temptmp.temp_error return dic def get_temp_info(self): @@ -942,6 +956,22 @@ def get_temp_info(self): val_list[temp.name] = dic return val_list + def get_temp_info_s3ip(self): + val_list = collections.OrderedDict() + # temp + templist = self.chas.temp_list_s3ip + for temp in templist: + dic = collections.OrderedDict() + dic["Min"] = temp.Min + dic["Max"] = temp.Max + dic["Low"] = temp.Low + dic["High"] = temp.High + temp_value = temp.Value + dic["Value"] = temp_value if (temp_value is not None) else self.error_ret + dic["Unit"] = temp.Unit + val_list[temp.name] = dic + return val_list + def get_sensor_info(self): val_list = collections.OrderedDict() # temp @@ -1337,3 +1367,10 @@ def get_cpu_reboot_cause(self): return "Unknown reboot cause" return cpu.get_cpu_reboot_cause() + def get_sensor_print_src(self): + """ + Get sensor data source + @return string of sensor data source + """ + return self.chas.sensor_print_src + diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/led.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/led.py index 7fb869c74d7f..0ae751b81e3d 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/led.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/led.py @@ -1,10 +1,20 @@ #!/usr/bin/env python3 -####################################################### # -# led.py -# Python implementation of the Class led +# Copyright (C) 2024 Micas 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 . + from plat_hal.devicebase import devicebase @@ -15,6 +25,7 @@ def __init__(self, conf=None): self.led_type = conf.get('led_type', None) self.led_attrs_config = conf.get('led_attrs', None) self.led_config = conf.get('led', None) + self.led_map = conf.get('led_map', None) def set_color(self, color): status = self.led_attrs_config.get(color, None) @@ -46,6 +57,11 @@ def get_color(self): if ret is False or value is None: return False, 'N/A' ledval = int(value) & mask + if self.led_map is not None: + led_color = self.led_map.get(ledval, None) + if led_color is None: + return False, 'N/A' + return True, led_color for key, val in self.led_attrs_config.items(): if (ledval == val) and (key != "mask"): return True, key diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/onie_e2.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/onie_e2.py index 9ac32cace263..d09fa70973c7 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/onie_e2.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/onie_e2.py @@ -1,10 +1,20 @@ #!/usr/bin/env python3 -####################################################### # -# onie_e2.py -# Python implementation of the Class onie_e2 +# Copyright (C) 2024 Micas 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 . + from plat_hal.devicebase import devicebase from eepromutil.onietlv import onie_tlv diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/osutil.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/osutil.py index 684e26bb9ecd..4501bcf5f29a 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/osutil.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/osutil.py @@ -1,10 +1,19 @@ #!/usr/bin/env python3 -####################################################### # -# osutil.py -# Python implementation of the Class osutil +# Copyright (C) 2024 Micas 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 os import glob @@ -53,37 +62,31 @@ def wrapper(*args, **kwargs): return decorator -pidfile = None - - def file_rw_lock(file_path): - global pidfile pidfile = open(file_path, "r") try: fcntl.flock(pidfile, fcntl.LOCK_EX | fcntl.LOCK_NB) - platform_hal_debug("file_rw_lock success") - return True + platform_hal_debug("%s file_rw_lock success, pidfile: %s" % (file_path, pidfile)) + return True, pidfile except Exception: if pidfile is not None: pidfile.close() pidfile = None - return False + return False, pidfile -def file_rw_unlock(): +def file_rw_unlock(pidfile): try: - global pidfile - if pidfile is not None: fcntl.flock(pidfile, fcntl.LOCK_UN) pidfile.close() + platform_hal_debug("file_rw_unlock success, pidfile: %s" % pidfile) pidfile = None - platform_hal_debug("file_rw_unlock success") else: platform_hal_debug("pidfile is invalid, do nothing") return True except Exception as e: - platform_hal_debug("file_rw_unlock err, msg: %s" % (str(e))) + platform_hal_debug("file_rw_unlock err, pidfile: %s, msg: %s" % (pidfile, str(e))) return False @@ -91,11 +94,11 @@ def take_file_rw_lock(file_path): loop = 1000 ret = False for i in range(0, loop): - ret = file_rw_lock(file_path) + ret, pidfile = file_rw_lock(file_path) if ret is True: break time.sleep(0.001) - return ret + return ret, pidfile class osutil(object): @@ -252,6 +255,7 @@ def io_rd(reg_addr, read_len=1): @staticmethod def readsysfs(location, flock_path=None): flock_path_tmp = None + pidfile = None platform_hal_debug("readsysfs, location:%s, flock_path:%s" % (location, flock_path)) try: if flock_path is not None: @@ -259,7 +263,7 @@ def readsysfs(location, flock_path=None): if len(flock_paths) != 0: flock_path_tmp = flock_paths[0] platform_hal_debug("try to get file lock, path:%s" % flock_path_tmp) - ret = take_file_rw_lock(flock_path_tmp) + ret, pidfile = take_file_rw_lock(flock_path_tmp) if ret is False: platform_hal_debug("take file lock timeout, path:%s" % flock_path_tmp) return False, ("take file rw lock timeout, path:%s" % flock_path_tmp) @@ -270,14 +274,14 @@ def readsysfs(location, flock_path=None): with open(locations[0], 'rb') as fd1: retval = fd1.read() retval = osutil.byteTostr(retval) - if flock_path_tmp is not None: - file_rw_unlock() + if pidfile is not None: + file_rw_unlock(pidfile) retval = retval.rstrip('\r\n') retval = retval.lstrip(" ") except Exception as e: - if flock_path_tmp is not None: - file_rw_unlock() + if pidfile is not None: + file_rw_unlock(pidfile) platform_hal_debug("readsysfs error, msg:%s" % str(e)) return False, (str(e) + " location[%s]" % location) return True, retval diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/psu.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/psu.py index a7fc90e0fe23..c62da1929d34 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/psu.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/psu.py @@ -1,10 +1,20 @@ #!/usr/bin/env python3 -####################################################### # -# psu.py -# Python implementation of the Class psu +# Copyright (C) 2024 Micas 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 . + from eepromutil.fru import ipmifru from eepromutil.cust_fru import CustFru from plat_hal.devicebase import devicebase @@ -428,7 +438,7 @@ def psu_not_present_pwm(self, val): @property def present(self): ret, val = self.get_value(self.__presentconfig) - if ret is False or val is None or val == "no_support": + if ret is False or val is None or val == "no_support" or val == "NA" or val == "ACCESS FAILED": return False mask = self.__presentconfig.get("mask") if isinstance(val, str): diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/rotor.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/rotor.py index ff120cb474b2..0b96bf340ce3 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/rotor.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/rotor.py @@ -1,10 +1,20 @@ #!/usr/bin/env python3 -####################################################### # -# rotor.py -# Python implementation of the Class rotor +# Copyright (C) 2024 Micas 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 . + from plat_hal.devicebase import devicebase from plat_hal.sensor import sensor @@ -32,7 +42,7 @@ def __init__(self, conf=None): def getRunning(self): ret, val = self.get_value(self.rotor_run_conf) - if ret is False or val is None or val == "no_support": + if ret is False or val is None or val == "no_support" or val == "NA" or val == "ACCESS FAILED": return False if isinstance(val, str): value = int(val, 16) @@ -120,7 +130,7 @@ def rotor_HwAlarm(self): ret, val = self.get_value(self.rotor_HwAlarm_conf) mask = self.rotor_HwAlarm_conf.get("mask") no_alarm_value = self.rotor_HwAlarm_conf.get("no_alarm") - if ret is False or val is None: + if ret is False or val is None or val == "no_support" or val == "NA" or val == "ACCESS FAILED": return False if isinstance(val, str): value = int(val, 16) diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/sensor.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/sensor.py index af2a5384b618..99396923c41a 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/sensor.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/sensor.py @@ -1,10 +1,20 @@ #!/usr/bin/env python3 -####################################################### # -# sensor.py -# Python implementation of the Class sensor +# Copyright (C) 2024 Micas 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 time from plat_hal.devicebase import devicebase @@ -103,9 +113,9 @@ def get_median(self, value_config, read_times): val_list = [] for i in range(0, read_times): ret, real_value = self.get_value(value_config) - if i != (read_times - 1): - time.sleep(0.01) if ret is False or real_value is None: + if i != (read_times - 1): + time.sleep(0.01) continue val_list.append(real_value) val_list.sort() @@ -272,3 +282,65 @@ def __str__(self): self.Max, self.Unit, self.format) return tmpstr + +class sensor_s3ip(sensor): + def __init__(self, s3ip_conf): + self.s3ip_conf = s3ip_conf + value_conf = {} + value_conf["loc"] = "%s/%s/%s" % (self.s3ip_conf.get("path"), self.s3ip_conf.get("sensor_dir"), "value") + value_conf["way"] = "sysfs" + conf = {} + conf["value"] = value_conf + conf["read_times"] = s3ip_conf.get("read_times", 1) + conf["Unit"] = unit = s3ip_conf.get("Unit", None) + conf["format"] = unit = s3ip_conf.get("format", None) + super(sensor_s3ip, self).__init__(conf) + self.min_path = "%s/%s/%s" % (self.s3ip_conf.get("path"), self.s3ip_conf.get("sensor_dir"), "min") + self.max_path = "%s/%s/%s" % (self.s3ip_conf.get("path"), self.s3ip_conf.get("sensor_dir"), "max") + self.alias = "%s/%s/%s" % (self.s3ip_conf.get("path"), self.s3ip_conf.get("sensor_dir"), "alias") + self.sensor_id = self.s3ip_conf.get("type").upper() + + @property + def Min(self): + try: + ret, val = self.get_sysfs(self.min_path) + if ret is True: + return val + except Exception: + pass + return None + + @Min.setter + def Min(self, val): + try: + return self.set_sysfs(self.min_path, val) + except Exception as e: + return False, (str(e) + " location[%s][%d]" % (self.min_path, val)) + + @property + def Max(self): + try: + ret, val = self.get_sysfs(self.max_path) + if ret is True: + return val + except Exception: + pass + return None + + @Max.setter + def Max(self, val): + try: + return self.set_sysfs(self.max_path, val) + except Exception as e: + return False, (str(e) + " location[%s][%d]" % (self.max_path, val)) + + @property + def name(self): + try: + ret, val = self.get_sysfs(self.alias) + if ret is True: + return val + except Exception: + pass + return None + diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/temp.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/temp.py index a202c20339c9..1dbd443f71c3 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/temp.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/plat_hal/temp.py @@ -1,14 +1,23 @@ #!/usr/bin/env python3 -####################################################### # -# temp.py -# Python implementation of the Class temp +# Copyright (C) 2024 Micas 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 os import syslog -from plat_hal.sensor import sensor - +from plat_hal.sensor import sensor, sensor_s3ip PLATFORM_HAL_TEMP_DEBUG_FILE = "/etc/.platform_hal_temp_debug_flag" @@ -82,7 +91,7 @@ def get_max_value(self, conf): ret, val = self.get_value(conf) if ret is False or val is None: return None - return val + return float(val) except Exception: return None @@ -120,6 +129,25 @@ def Value(self): self.__Value = int(max_val) else: self.__Value = self.get_format_value(self.format % max_val) + elif isinstance(self.ValueConfig, dict) and self.ValueConfig.get("val_conf_list") is not None: + val_list = [] + fail_set = set() + for index, val_conf_item in enumerate(self.ValueConfig["val_conf_list"]): + val_tmp = self.get_max_value(val_conf_item) + if val_tmp is None: + fail_set.add(index) + fail_val = val_conf_item.get("fail_val") + if fail_val is None: + return None + val_tmp = fail_val + val_list.append(val_tmp) + # check fail set + fail_conf_set_list = self.ValueConfig.get("fail_conf_set_list",[]) + for item in fail_conf_set_list: + if item.issubset(fail_set): + return None + val_tuple = tuple(val_list) + self.__Value = self.get_format_value(self.ValueConfig["format"] % (val_tuple)) else: ret, val = self.get_value(self.ValueConfig) if ret is False or val is None: @@ -137,3 +165,8 @@ def Value(self): @Value.setter def Value(self, val): self.__Value = val + +class temp_s3ip(sensor_s3ip): + def __init__(self, s3ip_conf = None): + super(temp_s3ip, self).__init__(s3ip_conf) + self.temp_id = s3ip_conf.get("type").upper() diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/restful_util/restful_api.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/restful_util/restful_api.py index 2cb7f5273a44..86e102594cab 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/restful_util/restful_api.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/restful_util/restful_api.py @@ -1,11 +1,26 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- +# +# Copyright (C) 2024 Micas 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 os import syslog import requests + class RestfulApiClient(): Debug_file = "/tmp/restful_api_debug" BmcBaseUrl = 'http://240.1.1.2:8080' @@ -14,12 +29,13 @@ class RestfulApiClient(): HostnameUrl = '/api/v1.0/hostname' EventsUrl = '/api/v1.0/events' SensorsUrl = '/api/v1.0/sys_switch/sensors' + TempSensorsUrl = '/api/v1.0/sys_switch/temp_sensor' + VolSensorsUrl = '/api/v1.0/sys_switch/vol_sensor' + CurSensorsUrl = '/api/v1.0/sys_switch/cur_sensor' SyseepromUrl = '/api/v1.0/syseeprom' FansUrl = '/api/v1.0/sys_switch/fans' - # FanUrl = '/api/v1.0/sys_switch/fan/fan1' FanUrl = '/api/v1.0/sys_switch/fan/' PsusUrl = '/api/v1.0/sys_switch/psus' - # PsuUrl = '/api/v1.0/sys_switch/psu/psu1' PsuUrl = '/api/v1.0/sys_switch/psu/' LEDsUrl = '/api/v1.0/sys_switch/leds' FirmwaresUrl = '/api/v1.0/sys_switch/firmwares' @@ -28,7 +44,6 @@ class RestfulApiClient(): TimeUrl = '/api/v1.0/time' TimezoneUrl = '/api/v1.0/timezone' NtpUrl = '/api/v1.0/ntp' - PowerUrl = '/api/v1.0/power' def restful_api_error_log(self, msg): syslog.openlog("restful_api") diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/wbutil/baseutil.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/wbutil/baseutil.py index 340a1f7a733f..fdc4410e2c20 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/wbutil/baseutil.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/wbutil/baseutil.py @@ -1,4 +1,20 @@ #!/usr/bin/env python3 +# +# Copyright (C) 2024 Micas 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 os diff --git a/platform/broadcom/sonic-platform-modules-micas/common/lib/wbutil/smbus.py b/platform/broadcom/sonic-platform-modules-micas/common/lib/wbutil/smbus.py index 5f1659b3bbf0..d474cffa2d35 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/lib/wbutil/smbus.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/lib/wbutil/smbus.py @@ -1,25 +1,19 @@ #!/usr/bin/env python3 -# smbus2 - A drop-in replacement for smbus-cffi/smbus-python -# The MIT License (MIT) -# Copyright (c) 2017 Karl-Petter Lindegaard # -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: +# Copyright (C) 2024 Micas Networks Inc. # -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. +# 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. # -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. +# 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 os import sys diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/Makefile b/platform/broadcom/sonic-platform-modules-micas/common/modules/Makefile index e432430dba46..4e106f013819 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/Makefile +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/Makefile @@ -8,9 +8,11 @@ module_out_put_dir := $(PWD)/build export module_out_put_dir PLAT_SYSFS_DIR = $(PWD)/plat_sysfs +S3IP_SYSFS_DIR = $(PWD)/s3ip_sysfs PINCTRL = $(PWD)/pinctrl export PLAT_SYSFS_DIR +export S3IP_SYSFS_DIR platform_common-objs := platform_common_module.o dfd_tlveeprom.o obj-m += platform_common.o @@ -39,9 +41,14 @@ obj-m += wb_i2c_mux_pca9641.o obj-m += wb_i2c_mux_pca954x.o obj-m += wb_xdpe132g5c_pmbus.o obj-m += wb_i2c_gpio_device.o +obj-m += ct7148.o +obj-m += wb_ucd9081.o +obj-m += wb_indirect_dev.o + all : $(MAKE) -C $(PLAT_SYSFS_DIR) + $(MAKE) -C $(S3IP_SYSFS_DIR) $(MAKE) -C $(PINCTRL) $(MAKE) -C $(KERNEL_SRC)/build M=$(PWD) modules @if [ ! -d $(module_out_put_dir) ]; then mkdir -p $(module_out_put_dir) ;fi diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/ct7148.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/ct7148.c new file mode 100644 index 000000000000..fff4b0e0eecc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/ct7148.c @@ -0,0 +1,237 @@ +/* + * An ct7148 driver for tmp ct7148 function + * + * Copyright (C) 2024 Micas 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, 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 + +/* debug switch level */ +typedef enum { + DBG_START, + DBG_VERBOSE, + DBG_KEY, + DBG_WARN, + DBG_ERROR, + DBG_END, +} dbg_level_t; + +static int debuglevel = 0; +module_param(debuglevel, int, S_IRUGO | S_IWUSR); + +#define CT7318_DEBUG(fmt, arg...) do { \ + if (debuglevel > DBG_START && debuglevel < DBG_ERROR) { \ + printk(KERN_INFO "[DEBUG]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \ + } else if (debuglevel >= DBG_ERROR) { \ + printk(KERN_ERR "[DEBUG]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \ + } else { } \ +} while (0) + +#define CT7318_ERROR(fmt, arg...) do { \ + if (debuglevel > DBG_START) { \ + printk(KERN_ERR "[ERROR]:<%s, %d>:"fmt, __FUNCTION__, __LINE__, ##arg); \ + } \ + } while (0) + +enum chips { ct7318 }; + +/* The CT7318 registers */ +#define CT7318_CONFIG_REG_1 0x09 +#define CT7318_CONVERSION_RATE_REG 0x0A +#define CT7318_MANUFACTURER_ID_REG 0xFE +#define CT7318_DEVICE_ID_REG 0xFF + +static const u8 CT7318_TEMP_MSB[2] = { 0x00, 0x01 }; +static const u8 CT7318_TEMP_LSB[2] = { 0x15, 0x10 }; + +/* Flags */ +#define CT7318_CONFIG_SHUTDOWN 0x40 +#define CT7318_CONFIG_RANGE 0x04 + +/* Manufacturer / Device ID's */ +#define CT7318_MANUFACTURER_ID 0x59 +#define CT7318_DEVICE_ID 0x8D + +static const struct i2c_device_id ct7318_id[] = { + { "ct7318", 2 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, ct7318_id); + +static const struct of_device_id ct7318_of_match[] = { + {.compatible = "sensylink,ct7318"}, + { }, +}; +MODULE_DEVICE_TABLE(of, ct7318_of_match); + +struct ct7318_data { + struct i2c_client *client; + struct mutex update_lock; + u32 temp_config[5]; + struct hwmon_channel_info temp_info; + const struct hwmon_channel_info *info[2]; + struct hwmon_chip_info chip; + char valid; + unsigned long last_updated; + unsigned long channels; + u8 config; + s16 temp[4]; +}; + +static int ct7318_register_to_temp(s16 reg) +{ + s16 tmp_val; + int val; + + CT7318_DEBUG("reg_data, data=0x%04x \n", reg); + + /* Positive number:reg*0.125 */ + if (!(reg & 0x400)) { + val = reg * 125; + /* Negative number: The first bit is the sign bit, and the rest is inverted +1 */ + } else { + tmp_val = ((~((s16)reg)) & 0x7ff) + 1; + CT7318_DEBUG("ct7318, tmp_val=0x%08x -- %d\n", tmp_val, tmp_val); + val = -(tmp_val * 125); + } + + CT7318_DEBUG("ct7318 reg2data, val=0x%08x -- %d \n", val, val); + + return val; +} + +static struct ct7318_data *ct7318_update_device(struct device *dev) +{ + struct ct7318_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + int i; + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + (HZ / 16)) || !data->valid) { + + for (i = 0; i < data->channels; i++) { + data->temp[i] = i2c_smbus_read_byte_data(client, CT7318_TEMP_MSB[i]) << 3; + data->temp[i] |= (i2c_smbus_read_byte_data(client, CT7318_TEMP_LSB[i]) >> 5); + } + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; +} + +static int ct7318_read(struct device *dev, enum hwmon_sensor_types type, + u32 attr, int channel, long *val) +{ + struct ct7318_data *ct7318 = ct7318_update_device(dev); + + switch (attr) { + case hwmon_temp_input: + *val = ct7318_register_to_temp(ct7318->temp[channel]); + return 0; + case hwmon_temp_fault: + /* + * The OPEN bit signals a fault. This is bit 0 of the temperature + * register (low byte). + */ + return 0; + default: + return -EOPNOTSUPP; + } +} + +static umode_t ct7318_is_visible(const void *data, enum hwmon_sensor_types type, u32 attr, int channel) +{ + switch (attr) { + case hwmon_temp_fault: + if (channel == 0) { + return 0; + } + return 0444; + case hwmon_temp_input: + return 0444; + default: + return 0; + } +} + +static const struct hwmon_ops ct7318_ops = { + .read = ct7318_read, + .is_visible = ct7318_is_visible, +}; + +static int ct7318_probe(struct i2c_client *client) +{ + struct device *dev = &client->dev; + struct device *hwmon_dev; + struct ct7318_data *data; + int i; + + data = devm_kzalloc(dev, sizeof(struct ct7318_data), GFP_KERNEL); + if (!data) { + return -ENOMEM; + } + + mutex_init(&data->update_lock); + + data->channels = i2c_match_id(ct7318_id, client)->driver_data; + data->client = client; + + for (i = 0; i < data->channels; i++) { + data->temp_config[i] = HWMON_T_INPUT; + } + + data->chip.ops = &ct7318_ops; + data->chip.info = data->info; + + data->info[0] = &data->temp_info; + + data->temp_info.type = hwmon_temp; + data->temp_info.config = data->temp_config; + + hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, data, &data->chip, NULL); + return PTR_ERR_OR_ZERO(hwmon_dev); +} + +static struct i2c_driver ct7318_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "ct7318", + .of_match_table = of_match_ptr(ct7318_of_match), + }, + .probe_new = ct7318_probe, + .id_table = ct7318_id, +}; + +module_i2c_driver(ct7318_driver); + +MODULE_AUTHOR("sonic_rd@whitebox"); +MODULE_DESCRIPTION("Sensylink CT7318 temperature sensor driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/dfd_tlveeprom.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/dfd_tlveeprom.c index 0d6f38ecc551..7469c760a568 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/dfd_tlveeprom.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/dfd_tlveeprom.c @@ -1,9 +1,11 @@ /* - * Copyright (C) 2003-2014 FreeIPMI Core Team + * An dfd_tlveeprom driver for dfd rlveeprom function * - * This program is free software: you can redistribute it and/or modify + * Copyright (C) 2024 Micas 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 + * 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, @@ -12,33 +14,10 @@ * 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 . - * + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/*****************************************************************************\ - * Copyright (C) 2007-2014 Lawrence Livermore National Security, LLC. - * Copyright (C) 2007 The Regents of the University of California. - * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). - * Written by Albert Chu - * UCRL-CODE-232183 - * - * This file is part of Ipmi-fru, a tool used for retrieving - * motherboard field replaceable unit (FRU) information. For details, - * see http://www.llnl.gov/linux/. - * - * Ipmi-fru 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. - * - * Ipmi-fru 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 Ipmi-fru. If not, see . -\*****************************************************************************/ + #include #include #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/dfd_tlveeprom.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/dfd_tlveeprom.h index 6eaac5848223..30991eca5bc8 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/dfd_tlveeprom.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/dfd_tlveeprom.h @@ -1,3 +1,23 @@ +/* + * A header definition for dfd_tlveeprom driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #ifndef DFD_OPENBMC_TLVEEPROM_H #define DFD_OPENBMC_TLVEEPROM_H diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/fpga_i2c.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/fpga_i2c.h index 649a8452debe..293484605cf7 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/fpga_i2c.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/fpga_i2c.h @@ -1,3 +1,23 @@ +/* + * A header definition for fpga_i2c driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #ifndef _FPGA_I2C_H #define _FPGA_I2C_H diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/hw_test.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/hw_test.c index e74f4e800582..84d3f54943fd 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/hw_test.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/hw_test.c @@ -1,9 +1,21 @@ /* - * hw_test.c - * Original Author : support, 2020-10-15 + * An hw_test driver for hw test read/write function * - * History - * v1.0 support 2020-10-15 Initial version. + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/hw_test.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/hw_test.h index 695fa336c4ff..231396390272 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/hw_test.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/hw_test.h @@ -1,3 +1,22 @@ +/* + * A header definition for hw_test driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ #ifndef _LINUX_DRAM_DRIVER_H #define _LINUX_DRAM_DRIVER_H diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/pinctrl/core.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/pinctrl/core.h index 840103c40c14..81655ead6007 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/pinctrl/core.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/pinctrl/core.h @@ -1,11 +1,24 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ /* - * Core private header for the pin control subsystem + * A header definition for pin control subsystem * + * Copyright (C) 2024 Micas Networks Inc. + * + * Based on core.h * Copyright (C) 2011 ST-Ericsson SA - * Written on behalf of Linaro for ST-Ericsson * - * Author: Linus Walleij + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/pinctrl/wb_gpio_c3000.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/pinctrl/wb_gpio_c3000.c index 753c8a061a86..7689ba1371bf 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/pinctrl/wb_gpio_c3000.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/pinctrl/wb_gpio_c3000.c @@ -1,9 +1,21 @@ -// SPDX-License-Identifier: GPL-2.0 /* - * Intel Denverton SoC pinctrl/GPIO driver + * An wb_gpio_c3000 driver for gpio c3000 function * - * Copyright (C) 2017, Intel Corporation - * Author: Mika Westerberg + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/pinctrl/wb_gpio_c3000_device.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/pinctrl/wb_gpio_c3000_device.c index 33ab19a5ac44..ddfc5791b706 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/pinctrl/wb_gpio_c3000_device.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/pinctrl/wb_gpio_c3000_device.c @@ -1,3 +1,23 @@ +/* + * An wb_gpio_c3000_device driver for gpio c3000 device function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #include #include #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/pinctrl/wb_pinctrl_intel.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/pinctrl/wb_pinctrl_intel.c index 7a52f17ac8f9..98d735ea6a1a 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/pinctrl/wb_pinctrl_intel.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/pinctrl/wb_pinctrl_intel.c @@ -1,10 +1,24 @@ -// SPDX-License-Identifier: GPL-2.0 /* - * Intel pinctrl/GPIO core driver. + * An wb_pinctrl_intel driver for pinctrl intel function * + * Copyright (C) 2024 Micas Networks Inc. + * + * Based on pinctrl-intel.c * Copyright (C) 2015, Intel Corporation - * Authors: Mathias Nyman - * Mika Westerberg + * + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/pinctrl/wb_pinctrl_intel.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/pinctrl/wb_pinctrl_intel.h index 5ed0cc0651a5..111edabacfcc 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/pinctrl/wb_pinctrl_intel.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/pinctrl/wb_pinctrl_intel.h @@ -1,10 +1,24 @@ -/* SPDX-License-Identifier: GPL-2.0 */ /* - * Core pinctrl/GPIO driver for Intel GPIO controllers + * A header definition for pinctrl_intel driver * + * Copyright (C) 2024 Micas Networks Inc. + * + * Based on pinctrl-intel.h * Copyright (C) 2015, Intel Corporation - * Authors: Mathias Nyman - * Mika Westerberg + * + * 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 PINCTRL_INTEL_H diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg.c index 22962556eb0d..44bfe8e95b6f 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg.c @@ -1,3 +1,23 @@ +/* + * An dfd_cfg driver for cfg function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #include #include #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_adapter.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_adapter.c index 9c8dc6aa098e..cd26851725cc 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_adapter.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_adapter.c @@ -1,3 +1,23 @@ +/* + * An dfd_cfg_adapter driver for cfg adapter function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #include #include #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_file.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_file.c index ac1c22ff1c51..eaf58f6bc519 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_file.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_file.c @@ -1,3 +1,23 @@ +/* + * An dfd_cfg_file driver for cfg file function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #include #include #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_info.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_info.c index c1ad958bc8bb..26a7fab2c967 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_info.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_info.c @@ -1,3 +1,23 @@ +/* + * An dfd_cfg_info driver for cfg information function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #include #include #include @@ -551,6 +571,22 @@ static int dfd_info_reg2data_mac_th5(int data, int *temp_value) return DFD_RV_OK; } +static int dfd_info_reg2data_mac_th4(int data, int *temp_value) +{ + int tmp_val; + int val; + + DBG_DEBUG(DBG_VERBOSE, "reg2data_mac_th4, data=%d\n", data); + + tmp_val = data >> 4; + val = 356070 - (((tmp_val - 2) * 237340) / 2000); + + DBG_DEBUG(DBG_VERBOSE, "reg2data_mac_th4, val=%d\n", val); + *temp_value = val; + + return DFD_RV_OK; +} + static int dfd_info_reg2data_mac_td3(int data, int *temp_value) { int val; @@ -658,6 +694,9 @@ static int dfd_info_get_cpld_temperature(int key, int *value) case MAC_TD3: rv = dfd_info_reg2data_mac_td3(temp_reg, &temp_value); break; + case MAC_TH4: + rv = dfd_info_reg2data_mac_th4(temp_reg, &temp_value); + break; default: temp_value = temp_reg; rv = DFD_RV_OK; diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_listnode.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_listnode.c index d6fd7e104c9f..450d8a360173 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_listnode.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/cfg/dfd_cfg_listnode.c @@ -1,3 +1,23 @@ +/* + * An dfd_cfg_listnode driver for cfg listnode function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #include #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_fan_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_fan_driver.c index d8965d75c9c0..203a8cc0d637 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_fan_driver.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_fan_driver.c @@ -1,3 +1,23 @@ +/* + * An dfd_fan_driver driver for dfd fan function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #include #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_module.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_module.c index 9e5b00b795de..c937cb790fd1 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_module.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_module.c @@ -1,3 +1,23 @@ +/* + * An dfd_module driver for dfd module function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #include #include "../dev_sysfs/include/sysfs_common.h" diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_psu_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_psu_driver.c index 55e2e4339ae7..bb0eba0bfa05 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_psu_driver.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_psu_driver.c @@ -1,3 +1,23 @@ +/* + * An dfd_psu_driver driver for dfd psu function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #include #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_sensors_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_sensors_driver.c index bfca20290efb..433a51dc75ff 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_sensors_driver.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_sensors_driver.c @@ -1,3 +1,23 @@ +/* + * An dfd_sensor_driver driver for dfd sensor function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #include #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_sff_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_sff_driver.c index 5c1faff975b1..f768c5640e76 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_sff_driver.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_sff_driver.c @@ -1,3 +1,23 @@ +/* + * An dfd_sff_driver driver for dfd sff function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #include #include "./include/dfd_module.h" diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_slot_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_slot_driver.c index 69c82adabef0..6e3c70abea6f 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_slot_driver.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/dfd_slot_driver.c @@ -1,3 +1,23 @@ +/* + * An dfd_slot_driver driver for dfd slot function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #include #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg.h index af3de1ca9938..2b698f37af61 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg.h @@ -1,3 +1,23 @@ +/* + * A header definition for dfd_cfg driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #ifndef __DFD_CFG_H__ #define __DFD_CFG_H__ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_adapter.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_adapter.h index 70d8b536c437..c599250dd225 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_adapter.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_adapter.h @@ -1,3 +1,23 @@ +/* + * A header definition for dfd_cfg_adapter driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #ifndef __DFD_CFG_ADAPTER_H__ #define __DFD_CFG_ADAPTER_H__ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_file.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_file.h index 50d7a42d5564..d74bfae0d697 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_file.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_file.h @@ -1,3 +1,23 @@ +/* + * A header definition for dfd_cfg_file driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #ifndef __DFD_CFG_FILE_H__ #define __DFD_CFG_FILE_H__ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_info.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_info.h index 88e8f92c10fe..def93cd51353 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_info.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_info.h @@ -1,3 +1,23 @@ +/* + * A header definition for dfd_cfg_info driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #ifndef __DFD_CFG_INFO_H__ #define __DFD_CFG_INFO_H__ @@ -97,7 +117,8 @@ typedef enum sensor_format_mem_s { LINEAR16, TMP464, MAC_TH5, - MAC_TD3 + MAC_TD3, + MAC_TH4 } sensor_format_mem_t; typedef int (*info_hwmon_buf_f)(uint8_t *buf, int buf_len, uint8_t *buf_new, int *buf_len_new, info_ctrl_t *info_ctrl); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_listnode.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_listnode.h index 955dfa96e42e..9c4bb057beb8 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_listnode.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_cfg_listnode.h @@ -1,3 +1,23 @@ +/* + * A header definition for dfd_cfg_listnode driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #ifndef __DFD_CFG_LISTNODE_H__ #define __DFD_CFG_LISTNODE_H__ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_fan_driver.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_fan_driver.h index 1065fd9eed3f..e1987b0f06cd 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_fan_driver.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_fan_driver.h @@ -1,3 +1,23 @@ +/* + * A header definition for dfd_fan_driver driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #ifndef _DFD_FAN_DRIVER_H_ #define _DFD_FAN_DRIVER_H_ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_module.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_module.h index a547255cf3ab..8ed110e7ae69 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_module.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_module.h @@ -1,3 +1,23 @@ +/* + * A header definition for dfd_module driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #ifndef __DFD_MODULE_H__ #define __DFD_MODULE_H__ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_psu_driver.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_psu_driver.h index ce7199660557..a9d7f465915e 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_psu_driver.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_psu_driver.h @@ -1,3 +1,23 @@ +/* + * A header definition for dfd_psu_driver driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #ifndef _DFD_PSU_DRIVER_H_ #define _DFD_PSU_DRIVER_H_ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_sensors_driver.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_sensors_driver.h index 16733b26029f..25998164ab36 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_sensors_driver.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_sensors_driver.h @@ -1,3 +1,23 @@ +/* + * A header definition for dfd_sensor_driver driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #ifndef _DFD_SENSORS_DRIVER_H_ #define _DFD_SENSORS_DRIVER_H_ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_sff_driver.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_sff_driver.h index 7107b72ee4b2..3e9305d6647c 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_sff_driver.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_sff_driver.h @@ -1,3 +1,23 @@ +/* + * A header definition for dfd_aff_driver driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #ifndef _DFD_SFF_DRIVER_H_ #define _DFD_SFF_DRIVER_H_ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_slot_driver.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_slot_driver.h index c68caecd2e66..1e628c0e9754 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_slot_driver.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_cfg/include/dfd_slot_driver.h @@ -1,3 +1,23 @@ +/* + * A header definition for dfd_slot_driver driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #ifndef _DFD_SLOT_DRIVER_H_ #define _DFD_SLOT_DRIVER_H_ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/include/plat_switch.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/include/plat_switch.h index bbd813e87114..b862ef7121cf 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/include/plat_switch.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/include/plat_switch.h @@ -1,3 +1,23 @@ +/* + * A header definition for plat_switch driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #ifndef _PLAT_SWITCH_H_ #define _PLAT_SWITCH_H_ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/include/sysfs_common.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/include/sysfs_common.h index 5b73731e1fbf..4ac0cee1a4a6 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/include/sysfs_common.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/include/sysfs_common.h @@ -1,3 +1,23 @@ +/* + * A header definition for sysfs_common driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #ifndef _SYSFS_COMMON_H_ #define _SYSFS_COMMON_H_ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_fan.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_fan.c index 931c7c243a21..3809da9ec1a1 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_fan.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_fan.c @@ -1,8 +1,21 @@ /* - * plat_fan.c + * An plat_fan driver for plat fan function * - * This module create fan kobjects and attributes in /sys/wb_plat/fan + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_psu.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_psu.c index 197f94b64991..4207b9bc8ca7 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_psu.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_psu.c @@ -1,8 +1,21 @@ /* - * plat_psu.c + * An plat_psu driver for plat psu function * - * This module create psu kobjects and attributes in /sys/wb_plat/psu + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_sensor.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_sensor.c index aaf62f4c1a3c..da7d5a872350 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_sensor.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_sensor.c @@ -1,7 +1,21 @@ /* - * plat_sensor.c + * An plat_sensor driver for plat sensor function * - * This module create sensor kobjects and attributes in /sys/wb_plat/sensor + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_sff.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_sff.c index 50c0f78aede9..cf2cd5181f01 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_sff.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_sff.c @@ -1,8 +1,21 @@ /* - * plat_sff.c + * An plat_sff driver for plat sff function * - * This module create sff kobjects and attributes in /sys/wb_plat/sff + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_slot.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_slot.c index 7c50f283bd06..979de7418475 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_slot.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_slot.c @@ -1,8 +1,21 @@ /* - * plat_slot.c + * An plat_slot driver for plat slot function * - * This module create sff kobjects and attributes in /sys/wb_plat/slot + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_switch.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_switch.c index fea008b41bfe..e36ff6657c90 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_switch.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/plat_sysfs/dev_sysfs/plat_switch.c @@ -1,11 +1,23 @@ /* - * plat_switch.c + * An plat_switch driver for plat switch function * - * This module create a kset in sysfs called /sys/wb_plat - * Then other switch kobjects are created and assigned to this kset, - * such as "board", "cpld", "fan", "psu", "sff", ... + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + #include "./include/plat_switch.h" #define SWITCH_INFO(fmt, args...) LOG_INFO("switch: ", fmt, ##args) diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/platform_common.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/platform_common.h index 9e4a4fae00c1..ffd752204e4f 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/platform_common.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/platform_common.h @@ -1,3 +1,23 @@ +/* + * A header definition for platfrom_common driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #ifndef __PLATFORM_COMMON_H__ #define __PLATFORM_COMMON_H__ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/platform_common_module.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/platform_common_module.c index 189a3aa056b2..57f436e5b8af 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/platform_common_module.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/platform_common_module.c @@ -1,3 +1,23 @@ +/* + * An platform_common_module driver for platform common modules function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #include #include #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/pmbus.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/pmbus.h index 10fb17879f8e..853dba4333e3 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/pmbus.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/pmbus.h @@ -1,9 +1,25 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ /* - * pmbus.h - Common defines and structures for PMBus devices + * A header definition for pmbus driver * + * Copyright (C) 2024 Micas Networks Inc. + * + * Based on kernel pmbus.h * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/Makefile b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/Makefile new file mode 100644 index 000000000000..c4e5d6928bb0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/Makefile @@ -0,0 +1,19 @@ +PWD = $(shell pwd) +SYSFS_OUT_PUT := $(PWD)/build +sysfs_out_put_dir := $(SYSFS_OUT_PUT)/S3IP_sysfs/ +sysfs_cfg_dir := $(SYSFS_OUT_PUT)/dfd_cfg/ +export sysfs_out_put_dir sysfs_cfg_dir + +SYSFS_DRIVER_DIR = $(PWD)/sysfs_driver +SWITCH_DRIVER_DIR = $(PWD)/switch_driver +DEVICE_DRIVER_DIR = $(PWD)/device_driver + +export SYSFS_DRIVER_DIR SWITCH_DRIVER_DIR + +all : + $(MAKE) -C $(SYSFS_DRIVER_DIR) + $(MAKE) -C $(SWITCH_DRIVER_DIR) + $(MAKE) -C $(DEVICE_DRIVER_DIR) + +clean : + -rm -rf $(SYSFS_OUT_PUT) \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/Makefile b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/Makefile new file mode 100644 index 000000000000..a971e0bf3844 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/Makefile @@ -0,0 +1,36 @@ +PWD = $(shell pwd) + +MAKEFILE_FILE_PATH = $(abspath $(lastword $(MAKEFILE_LIST))) +DEV_SYSFS_HEADER_DIR = $(abspath $(MAKEFILE_FILE_PATH)/../../sysfs_driver/include) +SWITCH_DVR_HEADER_DIR = $(abspath $(MAKEFILE_FILE_PATH)/../../switch_driver/include) +EXTRA_CFLAGS:= -I$(M)/include +EXTRA_CFLAGS+= -I$(DEV_SYSFS_HEADER_DIR) +EXTRA_CFLAGS+= -I$(SWITCH_DVR_HEADER_DIR) +EXTRA_CFLAGS+= -Wall + +KBUILD_EXTRA_SYMBOLS += $(SYSFS_DRIVER_DIR)/Module.symvers +KBUILD_EXTRA_SYMBOLS += $(SWITCH_DRIVER_DIR)/Module.symvers + +obj-m := syseeprom_device_driver.o +obj-m += fan_device_driver.o +obj-m += cpld_device_driver.o +obj-m += sysled_device_driver.o +obj-m += slot_device_driver.o +obj-m += psu_device_driver.o +obj-m += transceiver_device_driver.o +obj-m += temp_sensor_device_driver.o +obj-m += vol_sensor_device_driver.o +obj-m += curr_sensor_device_driver.o +obj-m += fpga_device_driver.o +obj-m += watchdog_device_driver.o +obj-m += system_device_driver.o +obj-m += eeprom_device_driver.o + +all: + $(MAKE) -C $(KERNEL_SRC)/build M=$(PWD) modules + @if [ ! -d $(module_out_put_dir) ]; then mkdir -p $(module_out_put_dir) ;fi + cp -p $(PWD)/*.ko $(module_out_put_dir) +clean: + rm -f $(PWD)/*.o $(PWD)/*.ko $(PWD)/*.mod.c $(PWD)/.*.cmd + rm -f $(PWD)/Module.markers $(PWD)/Module.symvers $(PWD)/modules.order + rm -rf $(PWD)/.tmp_versions \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/cpld_device_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/cpld_device_driver.c new file mode 100644 index 000000000000..de760b7bc775 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/cpld_device_driver.c @@ -0,0 +1,217 @@ +/* + * An cpld_device_driver driver for cpld devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#include "device_driver_common.h" +#include "cpld_sysfs.h" +#include "dfd_sysfs_common.h" + +#define CPLD_INFO(fmt, args...) LOG_INFO("cpld: ", fmt, ##args) +#define CPLD_ERR(fmt, args...) LOG_ERR("cpld: ", fmt, ##args) +#define CPLD_DBG(fmt, args...) LOG_DBG("cpld: ", fmt, ##args) + +static int g_loglevel = 0; +static struct switch_drivers_s *g_drv = NULL; + +/******************************************CPLD***********************************************/ +static int wb_get_main_board_cpld_number(void) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_cpld_number); + + ret = g_drv->get_main_board_cpld_number(); + return ret; +} + +/* + * wb_get_main_board_cpld_alias - Used to identify the location of cpld, + * @cpld_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_cpld_alias(unsigned int cpld_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_cpld_alias); + + ret = g_drv->get_main_board_cpld_alias(cpld_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_cpld_type - Used to get cpld model name + * @cpld_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_cpld_type(unsigned int cpld_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_cpld_type); + + ret = g_drv->get_main_board_cpld_type(cpld_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_cpld_firmware_version - Used to get cpld firmware version, + * @cpld_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_cpld_firmware_version(unsigned int cpld_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_cpld_firmware_version); + + ret = g_drv->get_main_board_cpld_firmware_version(cpld_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_cpld_board_version - Used to get cpld board version, + * @cpld_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_cpld_board_version(unsigned int cpld_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_cpld_board_version); + + ret = g_drv->get_main_board_cpld_board_version(cpld_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_cpld_test_reg - Used to test cpld register read + * filled the value to buf, value is hexadecimal, start with 0x + * @cpld_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_cpld_test_reg(unsigned int cpld_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_cpld_test_reg); + + ret = g_drv->get_main_board_cpld_test_reg(cpld_index, buf, count); + return ret; +} + +/* + * wb_set_main_board_cpld_test_reg - Used to test cpld register write + * @cpld_index: start with 1 + * @value: value write to cpld + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int wb_set_main_board_cpld_test_reg(unsigned int cpld_index, unsigned int value) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->set_main_board_cpld_test_reg); + + ret = g_drv->set_main_board_cpld_test_reg(cpld_index, value); + return ret; +} +/***************************************end of CPLD*******************************************/ + +static struct s3ip_sysfs_cpld_drivers_s drivers = { + /* + * set ODM CPLD drivers to /sys/s3ip/cpld, + * if not support the function, set corresponding hook to NULL. + */ + .get_main_board_cpld_number = wb_get_main_board_cpld_number, + .get_main_board_cpld_alias = wb_get_main_board_cpld_alias, + .get_main_board_cpld_type = wb_get_main_board_cpld_type, + .get_main_board_cpld_firmware_version = wb_get_main_board_cpld_firmware_version, + .get_main_board_cpld_board_version = wb_get_main_board_cpld_board_version, + .get_main_board_cpld_test_reg = wb_get_main_board_cpld_test_reg, + .set_main_board_cpld_test_reg = wb_set_main_board_cpld_test_reg, +}; + +static int __init cpld_device_driver_init(void) +{ + int ret; + + CPLD_INFO("cpld_init...\n"); + g_drv = s3ip_switch_driver_get(); + check_p(g_drv); + + ret = s3ip_sysfs_cpld_drivers_register(&drivers); + if (ret < 0) { + CPLD_ERR("cpld drivers register err, ret %d.\n", ret); + return ret; + } + + CPLD_INFO("cpld_init success.\n"); + return 0; +} + +static void __exit cpld_device_driver_exit(void) +{ + s3ip_sysfs_cpld_drivers_unregister(); + CPLD_INFO("cpld_exit success.\n"); + return; +} + +module_init(cpld_device_driver_init); +module_exit(cpld_device_driver_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4, all=0xf).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("cpld device driver"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/curr_sensor_device_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/curr_sensor_device_driver.c new file mode 100644 index 000000000000..1c2a1e25f6de --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/curr_sensor_device_driver.c @@ -0,0 +1,220 @@ +/* + * An curr_sensor_device_driver driver for current devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#include "device_driver_common.h" +#include "curr_sensor_sysfs.h" +#include "dfd_sysfs_common.h" + +#define CURR_SENSOR_INFO(fmt, args...) LOG_INFO("curr_sensor: ", fmt, ##args) +#define CURR_SENSOR_ERR(fmt, args...) LOG_ERR("curr_sensor: ", fmt, ##args) +#define CURR_SENSOR_DBG(fmt, args...) LOG_DBG("curr_sensor: ", fmt, ##args) + +static int g_loglevel = 0; +static struct switch_drivers_s *g_drv = NULL; + +/*************************************main board current***************************************/ +static int wb_get_main_board_curr_number(void) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_curr_number); + + ret = g_drv->get_main_board_curr_number(); + return ret; +} + +/* + * wb_get_main_board_curr_alias - Used to identify the location of the current sensor, + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_curr_alias(unsigned int curr_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_curr_alias); + + ret = g_drv->get_main_board_curr_alias(curr_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_curr_type - Used to get the model of current sensor, + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_curr_type(unsigned int curr_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_curr_type); + + ret = g_drv->get_main_board_curr_type(curr_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_curr_max - Used to get the maximum threshold of current sensor + * filled the value to buf, the value is integer with mA + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_curr_max(unsigned int curr_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_curr_max); + + ret = g_drv->get_main_board_curr_max(curr_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_curr_min - Used to get the minimum threshold of current sensor + * filled the value to buf, the value is integer with mA + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_curr_min(unsigned int curr_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_curr_min); + + ret = g_drv->get_main_board_curr_min(curr_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_curr_value - Used to get the input value of current sensor + * filled the value to buf, the value is integer with mA + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_curr_value(unsigned int curr_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_curr_value); + + ret = g_drv->get_main_board_curr_value(curr_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_curr_monitor_flag - Used to get the monitor flag of current sensor + * filled the value to buf, the value is integer with mA + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_curr_monitor_flag(unsigned int curr_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_curr_monitor_flag); + + ret = g_drv->get_main_board_curr_monitor_flag(curr_index, buf, count); + return ret; +} +/*********************************end of main board current************************************/ + +static struct s3ip_sysfs_curr_sensor_drivers_s drivers = { + /* + * set ODM current sensor drivers to /sys/s3ip/curr_sensor, + * if not support the function, set corresponding hook to NULL. + */ + .get_main_board_curr_number = wb_get_main_board_curr_number, + .get_main_board_curr_alias = wb_get_main_board_curr_alias, + .get_main_board_curr_type = wb_get_main_board_curr_type, + .get_main_board_curr_max = wb_get_main_board_curr_max, + .get_main_board_curr_min = wb_get_main_board_curr_min, + .get_main_board_curr_value = wb_get_main_board_curr_value, + .get_main_board_curr_monitor_flag = wb_get_main_board_curr_monitor_flag, +}; + +static int __init curr_sensor_dev_drv_init(void) +{ + int ret; + + CURR_SENSOR_INFO("curr_sensor_init...\n"); + g_drv = s3ip_switch_driver_get(); + check_p(g_drv); + + ret = s3ip_sysfs_curr_sensor_drivers_register(&drivers); + if (ret < 0) { + CURR_SENSOR_ERR("curr sensor drivers register err, ret %d.\n", ret); + return ret; + } + + CURR_SENSOR_INFO("curr_sensor_init success.\n"); + return 0; +} + +static void __exit curr_sensor_dev_drv_exit(void) +{ + s3ip_sysfs_curr_sensor_drivers_unregister(); + CURR_SENSOR_INFO("curr_sensor_exit success.\n"); + return; +} + +module_init(curr_sensor_dev_drv_init); +module_exit(curr_sensor_dev_drv_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4, all=0xf).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("current sensors device driver"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/eeprom_device_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/eeprom_device_driver.c new file mode 100644 index 000000000000..ee5d3495ed19 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/eeprom_device_driver.c @@ -0,0 +1,209 @@ +/* + * An eeprom_device_driver driver for eeprom devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#include "device_driver_common.h" +#include "eeprom_sysfs.h" +#include "dfd_sysfs_common.h" + +#define EEPROM_INFO(fmt, args...) LOG_INFO("eeprom: ", fmt, ##args) +#define EEPROM_ERR(fmt, args...) LOG_ERR("eeprom: ", fmt, ##args) +#define EEPROM_DBG(fmt, args...) LOG_DBG("eeprom: ", fmt, ##args) + +static int g_loglevel = 0; +static struct switch_drivers_s *g_drv = NULL; + +/*****************************************eeprom*******************************************/ + +/* + * wb_get_eeprom_number - Used to get eeprom number + * + * This function returns the size of eeprom by your switch, + * otherwise it returns a negative value on failed. + */ +static int wb_get_eeprom_number(void) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_eeprom_number); + + ret = g_drv->get_eeprom_number(); + return ret; +} + +/* + * wb_get_eeprom_size - Used to get eeprom size + * + * This function returns the size of eeprom by your switch, + * otherwise it returns a negative value on failed. + */ +static int wb_get_eeprom_size(unsigned int e2_index) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_eeprom_size); + + ret = g_drv->get_eeprom_size(e2_index); + return ret; +} + +/* + * wb_get_eeprom_alias - Used to get eeprom alias + * + * This function returns the size of eeprom by your switch, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_eeprom_alias(unsigned int e2_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_eeprom_alias); + + ret = g_drv->get_eeprom_alias(e2_index, buf, count); + return ret; +} + +/* + * wb_get_eeprom_tag - Used to get eeprom tag + * + * This function returns the size of eeprom by your switch, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_eeprom_tag(unsigned int e2_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_eeprom_tag); + + ret = g_drv->get_eeprom_tag(e2_index, buf, count); + return ret; +} + +/* + * wb_get_eeprom_type - Used to get eeprom type + * + * This function returns the size of eeprom by your switch, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_eeprom_type(unsigned int e2_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_eeprom_type); + + ret = g_drv->get_eeprom_type(e2_index, buf, count); + return ret; +} + + +/* + * wb_read_eeprom_data - Used to read eeprom data, + * @buf: Data read buffer + * @offset: offset address to read eeprom data + * @count: length of buf + * + * This function returns the length of the filled buffer, + * returns 0 means EOF, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_read_eeprom_data(unsigned int e2_index, char *buf, loff_t offset, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->read_eeprom_data); + + ret = g_drv->read_eeprom_data(e2_index, buf, offset, count); + return ret; +} + +/* + * wb_write_eeprom_data - Used to write eeprom data + * @buf: Data write buffer + * @offset: offset address to write eeprom data + * @count: length of buf + * + * This function returns the written length of eeprom, + * returns 0 means EOF, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_write_eeprom_data(unsigned int e2_index, char *buf, loff_t offset, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->write_eeprom_data); + + ret = g_drv->write_eeprom_data(e2_index, buf, offset, count); + return ret; +} +/*************************************end of eeprom****************************************/ + +static struct s3ip_sysfs_eeprom_drivers_s drivers = { + /* + * set ODM eeprom drivers to /sys/s3ip/eeprom, + * if not support the function, set corresponding hook to NULL. + */ + .get_eeprom_number = wb_get_eeprom_number, + .get_eeprom_alias = wb_get_eeprom_alias, + .get_eeprom_tag = wb_get_eeprom_tag, + .get_eeprom_type = wb_get_eeprom_type, + .get_eeprom_size = wb_get_eeprom_size, + .read_eeprom_data = wb_read_eeprom_data, + .write_eeprom_data = wb_write_eeprom_data, +}; + +static int __init eeprom_dev_drv_init(void) +{ + int ret; + + EEPROM_INFO("eeprom_dev_drv_init...\n"); + g_drv = s3ip_switch_driver_get(); + check_p(g_drv); + + ret = s3ip_sysfs_eeprom_drivers_register(&drivers); + if (ret < 0) { + EEPROM_ERR("eeprom drivers register err, ret %d.\n", ret); + return ret; + } + EEPROM_INFO("eeprom_dev_drv_init success.\n"); + return 0; +} + +static void __exit eeprom_dev_drv_exit(void) +{ + s3ip_sysfs_eeprom_drivers_unregister(); + EEPROM_INFO("eeprom_exit success.\n"); + return; +} + +module_init(eeprom_dev_drv_init); +module_exit(eeprom_dev_drv_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4, all=0xf).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("eeprom device driver"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/fan_device_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/fan_device_driver.c new file mode 100644 index 000000000000..5360043678db --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/fan_device_driver.c @@ -0,0 +1,542 @@ +/* + * An fan_device_driver driver for fan devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#include "device_driver_common.h" +#include "fan_sysfs.h" +#include "dfd_sysfs_common.h" + +#define FAN_INFO(fmt, args...) LOG_INFO("fan: ", fmt, ##args) +#define FAN_ERR(fmt, args...) LOG_ERR("fan: ", fmt, ##args) +#define FAN_DBG(fmt, args...) LOG_DBG("fan: ", fmt, ##args) + +static int g_loglevel = 0; +static struct switch_drivers_s *g_drv = NULL; + +/********************************************fan**********************************************/ +static int wb_get_fan_number(void) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_fan_number); + + ret = g_drv->get_fan_number(); + return ret; +} + +static int wb_get_fan_motor_number(unsigned int fan_index) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_fan_motor_number); + + ret = g_drv->get_fan_motor_number(fan_index); + return ret; +} + +/* + * wb_get_fan_model_name - Used to get fan model name, + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_fan_model_name(unsigned int fan_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_fan_model_name); + + ret = g_drv->get_fan_model_name(fan_index, buf, count); + return ret; +} + +/* + * wb_get_fan_vendor - Used to get vendor, + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_fan_vendor(unsigned int fan_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_fan_vendor); + + ret = g_drv->get_fan_vendor(fan_index, buf, count); + return ret; +} + +/* + * wb_get_fan_serial_number - Used to get fan serial number, + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_fan_serial_number(unsigned int fan_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_fan_serial_number); + + ret = g_drv->get_fan_serial_number(fan_index, buf, count); + return ret; +} + +/* + * wb_get_fan_part_number - Used to get fan part number, + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_fan_part_number(unsigned int fan_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_fan_part_number); + + ret = g_drv->get_fan_part_number(fan_index, buf, count); + return ret; +} + +/* + * wb_get_fan_hardware_version - Used to get fan hardware version, + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_fan_hardware_version(unsigned int fan_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_fan_hardware_version); + + ret = g_drv->get_fan_hardware_version(fan_index, buf, count); + return ret; +} + +/* + * wb_get_fan_status - Used to get fan status, + * filled the value to buf, fan status define as below: + * 0: ABSENT + * 1: OK + * 2: NOT OK + * + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_fan_status(unsigned int fan_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_fan_status); + + ret = g_drv->get_fan_status(fan_index, buf, count); + return ret; +} + +/* + * wb_get_fan_present - Used to get fan present status, + * filled the value to buf, fan status define as below: + * 0: ABSENT + * 1: PRESENT + * + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_fan_present(unsigned int fan_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_fan_present); + + ret = g_drv->get_fan_present(fan_index, buf, count); + return ret; +} + +/* + * wb_get_fan_led_status - Used to get fan led status + * filled the value to buf, led status value define as below: + * 0: dark + * 1: green + * 2: yellow + * 3: red + * 4:blue + * 5: green light flashing + * 6: yellow light flashing + * 7: red light flashing + * 8:blue light flashing + * + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_fan_led_status(unsigned int fan_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_fan_led_status); + + ret = g_drv->get_fan_led_status(fan_index, buf, count); + return ret; +} + +/* + * wb_set_fan_led_status - Used to set fan led status + * @fan_index: start with 1 + * @status: led status, led status value define as below: + * 0: dark + * 1: green + * 2: yellow + * 3: red + * 4: blue + * 5: green light flashing + * 6: yellow light flashing + * 7: red light flashing + * 8: blue light flashing + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int wb_set_fan_led_status(unsigned int fan_index, int status) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->set_fan_led_status); + + ret = g_drv->set_fan_led_status(fan_index, status); + return ret; +} + +/* + * wb_get_fan_direction - Used to get fan air flow direction, + * filled the value to buf, air flow direction define as below: + * 0: F2B + * 1: B2F + * + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_fan_direction(unsigned int fan_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_fan_direction); + + ret = g_drv->get_fan_direction(fan_index, buf, count); + return ret; +} + +/* + * wb_get_fan_motor_status - Used to get fan motor status + * filled the value to buf + * @fan_index: start with 1 + * @motor_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_fan_motor_status(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_fan_motor_status); + + ret = g_drv->get_fan_motor_status(fan_index, motor_index, buf, count); + return ret; +} + +/* + * wb_get_fan_motor_speed - Used to get fan motor speed + * filled the value to buf + * @fan_index: start with 1 + * @motor_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_fan_motor_speed(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_fan_motor_speed); + + ret = g_drv->get_fan_motor_speed(fan_index, motor_index, buf, count); + return ret; +} + +/* + * wb_get_fan_motor_speed_tolerance - Used to get fan motor speed tolerance + * filled the value to buf + * @fan_index: start with 1 + * @motor_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_fan_motor_speed_tolerance(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_fan_motor_speed_tolerance); + + ret = g_drv->get_fan_motor_speed_tolerance(fan_index, motor_index, buf, count); + return ret; +} + +/* + * wb_get_fan_motor_speed_target - Used to get fan motor speed target + * filled the value to buf + * @fan_index: start with 1 + * @motor_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_fan_motor_speed_target(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_fan_motor_speed_target); + + ret = g_drv->get_fan_motor_speed_target(fan_index, motor_index, buf, count); + return ret; +} + +/* + * wb_get_fan_motor_speed_max - Used to get the maximum threshold of fan motor + * filled the value to buf + * @fan_index: start with 1 + * @motor_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_fan_motor_speed_max(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_fan_motor_speed_max); + + ret = g_drv->get_fan_motor_speed_max(fan_index, motor_index, buf, count); + return ret; +} + +/* + * wb_get_fan_motor_speed_min - Used to get the minimum threshold of fan motor + * filled the value to buf + * @fan_index: start with 1 + * @motor_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_fan_motor_speed_min(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_fan_motor_speed_min); + + ret = g_drv->get_fan_motor_speed_min(fan_index, motor_index, buf, count); + return ret; +} + +/* + * wb_get_fan_ratio - Used to get the ratio of fan + * filled the value to buf + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_fan_ratio(unsigned int fan_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_fan_ratio); + + ret = g_drv->get_fan_ratio(fan_index, buf, count); + return ret; +} + +/* + * wb_set_fan_ratio - Used to set the ratio of fan + * @fan_index: start with 1 + * @ratio: motor speed ratio, from 0 to 100 + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int wb_set_fan_ratio(unsigned int fan_index, int ratio) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->set_fan_ratio); + + ret = g_drv->set_fan_ratio(fan_index, ratio); + return ret; +} +/****************************************end of fan*******************************************/ + +static struct s3ip_sysfs_fan_drivers_s drivers = { + /* + * set ODM fan drivers to /sys/s3ip/fan, + * if not support the function, set corresponding hook to NULL. + */ + .get_fan_number = wb_get_fan_number, + .get_fan_motor_number = wb_get_fan_motor_number, + .get_fan_model_name = wb_get_fan_model_name, + .get_fan_vendor = wb_get_fan_vendor, + .get_fan_serial_number = wb_get_fan_serial_number, + .get_fan_part_number = wb_get_fan_part_number, + .get_fan_hardware_version = wb_get_fan_hardware_version, + .get_fan_status = wb_get_fan_status, + .get_fan_present = wb_get_fan_present, + .get_fan_led_status = wb_get_fan_led_status, + .set_fan_led_status = wb_set_fan_led_status, + .get_fan_direction = wb_get_fan_direction, + .get_fan_motor_status = wb_get_fan_motor_status, + .get_fan_motor_speed = wb_get_fan_motor_speed, + .get_fan_motor_speed_tolerance = wb_get_fan_motor_speed_tolerance, + .get_fan_motor_speed_target = wb_get_fan_motor_speed_target, + .get_fan_motor_speed_max = wb_get_fan_motor_speed_max, + .get_fan_motor_speed_min = wb_get_fan_motor_speed_min, + .get_fan_ratio = wb_get_fan_ratio, + .set_fan_ratio = wb_set_fan_ratio +}; + +static int __init fan_dev_drv_init(void) +{ + int ret; + + FAN_INFO("fan_init...\n"); + g_drv = s3ip_switch_driver_get(); + check_p(g_drv); + + ret = s3ip_sysfs_fan_drivers_register(&drivers); + if (ret < 0) { + FAN_ERR("fan drivers register err, ret %d.\n", ret); + return ret; + } + + FAN_INFO("fan_init success.\n"); + return 0; +} + +static void __exit fan_dev_drv_exit(void) +{ + s3ip_sysfs_fan_drivers_unregister(); + FAN_INFO("fan_exit success.\n"); + return; +} + +module_init(fan_dev_drv_init); +module_exit(fan_dev_drv_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4, all=0xf).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("fan device driver"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/fpga_device_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/fpga_device_driver.c new file mode 100644 index 000000000000..7fda8b9b7184 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/fpga_device_driver.c @@ -0,0 +1,216 @@ +/* + * An fpga_device_driver driver for fpga devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#include "device_driver_common.h" +#include "fpga_sysfs.h" +#include "dfd_sysfs_common.h" + +#define FPGA_INFO(fmt, args...) LOG_INFO("fpga: ", fmt, ##args) +#define FPGA_ERR(fmt, args...) LOG_ERR("fpga: ", fmt, ##args) +#define FPGA_DBG(fmt, args...) LOG_DBG("fpga: ", fmt, ##args) + +static int g_loglevel = 0; +static struct switch_drivers_s *g_drv = NULL; + +/******************************************FPGA***********************************************/ +static int wb_get_main_board_fpga_number(void) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_fpga_number); + + ret = g_drv->get_main_board_fpga_number(); + return ret; +} + +/* + * wb_get_main_board_fpga_alias - Used to identify the location of fpga, + * @fpga_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_fpga_alias(unsigned int fpga_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_fpga_alias); + + ret = g_drv->get_main_board_fpga_alias(fpga_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_fpga_type - Used to get fpga model name + * @fpga_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_fpga_type(unsigned int fpga_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_fpga_type); + + ret = g_drv->get_main_board_fpga_type(fpga_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_fpga_firmware_version - Used to get fpga firmware version, + * @fpga_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_fpga_firmware_version(unsigned int fpga_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_fpga_firmware_version); + + ret = g_drv->get_main_board_fpga_firmware_version(fpga_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_fpga_board_version - Used to get fpga board version, + * @fpga_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_fpga_board_version(unsigned int fpga_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_fpga_board_version); + + ret = g_drv->get_main_board_fpga_board_version(fpga_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_fpga_test_reg - Used to test fpga register read + * filled the value to buf, value is hexadecimal, start with 0x + * @fpga_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_fpga_test_reg(unsigned int fpga_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_fpga_test_reg); + + ret = g_drv->get_main_board_fpga_test_reg(fpga_index, buf, count); + return ret; +} + +/* + * wb_set_main_board_fpga_test_reg - Used to test fpga register write + * @fpga_index: start with 1 + * @value: value write to fpga + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int wb_set_main_board_fpga_test_reg(unsigned int fpga_index, unsigned int value) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->set_main_board_fpga_test_reg); + + ret = g_drv->set_main_board_fpga_test_reg(fpga_index, value); + return ret; +} +/***************************************end of FPGA*******************************************/ + +static struct s3ip_sysfs_fpga_drivers_s drivers = { + /* + * set ODM FPGA drivers to /sys/s3ip/fpga, + * if not support the function, set corresponding hook to NULL. + */ + .get_main_board_fpga_number = wb_get_main_board_fpga_number, + .get_main_board_fpga_alias = wb_get_main_board_fpga_alias, + .get_main_board_fpga_type = wb_get_main_board_fpga_type, + .get_main_board_fpga_firmware_version = wb_get_main_board_fpga_firmware_version, + .get_main_board_fpga_board_version = wb_get_main_board_fpga_board_version, + .get_main_board_fpga_test_reg = wb_get_main_board_fpga_test_reg, + .set_main_board_fpga_test_reg = wb_set_main_board_fpga_test_reg, +}; + +static int __init fpga_dev_drv_init(void) +{ + int ret; + + FPGA_INFO("fpga_init...\n"); + g_drv = s3ip_switch_driver_get(); + check_p(g_drv); + + ret = s3ip_sysfs_fpga_drivers_register(&drivers); + if (ret < 0) { + FPGA_ERR("fpga drivers register err, ret %d.\n", ret); + return ret; + } + FPGA_INFO("fpga_init success.\n"); + return 0; +} + +static void __exit fpga_dev_drv_exit(void) +{ + s3ip_sysfs_fpga_drivers_unregister(); + FPGA_INFO("fpga_exit success.\n"); + return; +} + +module_init(fpga_dev_drv_init); +module_exit(fpga_dev_drv_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4, all=0xf).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("fpga device driver"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/include/device_driver_common.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/include/device_driver_common.h new file mode 100644 index 000000000000..5628c298b9c9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/include/device_driver_common.h @@ -0,0 +1,69 @@ +/* + * A header definition for devcie_driver_common driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _DEVICE_DRIVER_COMMON_H_ +#define _DEVICE_DRIVER_COMMON_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +enum LOG_LEVEL { + INFO = 0x1, + ERR = 0x2, + DBG = 0x4, + ALL = 0xf +}; + +#define LOG_INFO(_prefix, fmt, args...) do { \ + if (g_loglevel & INFO) { \ + printk(KERN_INFO _prefix "%s "fmt, __FUNCTION__, ##args); \ + } \ +} while (0) + +#define LOG_ERR(_prefix, fmt, args...) do { \ + if (g_loglevel & ERR) { \ + printk(KERN_ERR _prefix "%s "fmt, __FUNCTION__, ##args); \ + } \ +} while (0) + +#define LOG_DBG(_prefix, fmt, args...) do { \ + if (g_loglevel & DBG) { \ + printk(KERN_DEBUG _prefix "%s "fmt, __FUNCTION__, ##args); \ + } \ +} while (0) + +#define check_pfun(p) do { \ + if (p == NULL) { \ + if (g_loglevel & ERR) { \ + printk(KERN_ERR "%s, %s is NULL.\n", __FUNCTION__, #p); \ + } \ + return -ENOSYS; \ + } \ +} while (0) + +#define check_p(p) check_pfun(p) + +#endif /* _DEVICE_DRIVER_COMMON_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/psu_device_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/psu_device_driver.c new file mode 100644 index 000000000000..c97f4814523d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/psu_device_driver.c @@ -0,0 +1,1025 @@ +/* + * An psu_device_driver driver for psu devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#include + +#include "device_driver_common.h" +#include "psu_sysfs.h" +#include "dfd_sysfs_common.h" + +#define PSU_INFO(fmt, args...) LOG_INFO("psu: ", fmt, ##args) +#define PSU_ERR(fmt, args...) LOG_ERR("psu: ", fmt, ##args) +#define PSU_DBG(fmt, args...) LOG_DBG("psu: ", fmt, ##args) + +static int g_loglevel = 0; +static struct switch_drivers_s *g_drv = NULL; + +/********************************************psu**********************************************/ +static int wb_get_psu_number(void) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_psu_number); + + ret = g_drv->get_psu_number(); + return ret; +} + +static int wb_get_psu_temp_number(unsigned int psu_index) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_psu_temp_number); + + ret = g_drv->get_psu_temp_number(psu_index); + return ret; +} + +/* + * wb_get_psu_model_name - Used to get psu model name, + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_model_name(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_model_name); + + ret = g_drv->get_psu_model_name(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_vendor - Used to get psu model name, + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_vendor(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_vendor); + + ret = g_drv->get_psu_vendor(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_date - Used to get psu date, + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_date(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_date); + + ret = g_drv->get_psu_date(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_status - Used to get psu status, + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_status(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_status); + + ret = g_drv->get_psu_status(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_hw_status - Used to get psu status, + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_hw_status(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_hw_status); + + ret = g_drv->get_psu_hw_status(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_alarm - Used to get psu alarm status, + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_alarm(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_alarm); + + ret = g_drv->get_psu_alarm(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_serial_number - Used to get psu serial number, + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_serial_number(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_serial_number); + + ret = g_drv->get_psu_serial_number(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_part_number - Used to get psu part number, + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_part_number(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_part_number); + + ret = g_drv->get_psu_part_number(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_hardware_version - Used to get psu hardware version, + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_hardware_version(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_hardware_version); + + ret = g_drv->get_psu_hardware_version(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_type - Used to get the input type of psu + * filled the value to buf, input type value define as below: + * 0: DC + * 1: AC + * + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_type(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_type); + + ret = g_drv->get_psu_type(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_in_curr - Used to get the input current of psu + * filled the value to buf, the value is integer with mA + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_in_curr(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_in_curr); + + ret = g_drv->get_psu_in_curr(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_in_vol - Used to get the input voltage of psu + * filled the value to bu, the value is integer with mV + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_in_vol(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_in_vol); + + ret = g_drv->get_psu_in_vol(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_in_power - Used to get the input power of psu + * filled the value to buf, the value is integer with uW + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_in_power(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_in_power); + + ret = g_drv->get_psu_in_power(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_out_curr - Used to get the output current of psu + * filled the value to buf, the value is integer with mA + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_out_curr(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_out_curr); + + ret = g_drv->get_psu_out_curr(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_out_vol - Used to get the output voltage of psu + * filled the value to buf, the value is integer with mV + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_out_vol(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_out_vol); + + ret = g_drv->get_psu_out_vol(psu_index, buf, count); + return ret; +} + +static ssize_t wb_get_psu_attr_threshold(unsigned int psu_index, unsigned int type, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_attr_threshold); + + ret = g_drv->get_psu_attr_threshold(psu_index, type, buf, count); + return ret; +} + +/* + * wb_get_psu_out_power - Used to get the output power of psu + * filled the value to buf, the value is integer with uW + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_out_power(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_out_power); + + ret = g_drv->get_psu_out_power(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_out_max_power - Used to get the output max power of psu + * filled the value to buf, the value is integer with uW + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_out_max_power(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_out_max_power); + + ret = g_drv->get_psu_out_max_power(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_present_status - Used to get psu present status + * filled the value to buf, psu present status define as below: + * 0: ABSENT + * 1: PRESENT + * + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_present_status(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_present_status); + + ret = g_drv->get_psu_present_status(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_in_status - Used to get psu input status + * filled the value to buf, psu input status define as below: + * 0: NOT OK + * 1: OK + * + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_in_status(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_in_status); + + ret = g_drv->get_psu_in_status(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_status_pmbus - Used to get psu status from pmbus + * filled the value to buf, psu output status define as below: + * 0: NOT OK + * 1: OK + * + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_status_pmbus(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_status_pmbus); + + ret = g_drv->get_psu_status_pmbus(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_out_status - Used to get psu output status + * filled the value to buf, psu output status define as below: + * 0: NOT OK + * 1: OK + * + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_out_status(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_out_status); + + ret = g_drv->get_psu_out_status(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_fan_speed_cal - Used to get psu fan speed cal + * filled the value to buf + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_fan_speed_cal(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_fan_speed_cal); + + ret = g_drv->get_psu_fan_speed_cal(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_fan_speed - Used to get psu fan speed + * filled the value to buf + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_fan_speed(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_fan_speed); + + ret = g_drv->get_psu_fan_speed(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_fan_ratio - Used to get the ratio of psu fan + * filled the value to buf + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_fan_ratio(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_fan_ratio); + + ret = g_drv->get_psu_fan_ratio(psu_index, buf, count); + return ret; +} + +/* + * wb_set_psu_fan_ratio - Used to set the ratio of psu fan + * @psu_index: start with 1 + * @ratio: from 0 to 100 + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int wb_set_psu_fan_ratio(unsigned int psu_index, int ratio) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->set_psu_fan_ratio); + + ret = g_drv->set_psu_fan_ratio(psu_index, ratio); + return ret; +} + +/* + * wb_get_psu_fan_direction - Used to get psu air flow direction, + * filled the value to buf, air flow direction define as below: + * 0: F2B + * 1: B2F + * + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_fan_direction(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_fan_direction); + + ret = g_drv->get_psu_fan_direction(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_led_status - Used to get psu led status + * filled the value to buf, led status value define as below: + * 0: dark + * 1: green + * 2: yellow + * 3: red + * 4: blue + * 5: green light flashing + * 6: yellow light flashing + * 7: red light flashing + * 8: blue light flashing + * + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_led_status(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_led_status); + + ret = g_drv->get_psu_led_status(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_temp_alias - Used to identify the location of the temperature sensor of psu, + * @psu_index: start with 1 + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_temp_alias(unsigned int psu_index, unsigned int temp_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_temp_alias); + + ret = g_drv->get_psu_temp_alias(psu_index, temp_index, buf, count); + return ret; +} + +/* + * wb_get_psu_temp_type - Used to get the model of temperature sensor of psu, + * @psu_index: start with 1 + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_temp_type(unsigned int psu_index, unsigned int temp_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_temp_type); + + ret = g_drv->get_psu_temp_type(psu_index, temp_index, buf, count); + return ret; + +} + +/* + * wb_get_psu_temp_max - Used to get the maximum threshold of temperature sensor of psu, + * filled the value to buf, the value is integer with millidegree Celsius + * @psu_index: start with 1 + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_temp_max(unsigned int psu_index, unsigned int temp_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_temp_max); + + ret = g_drv->get_psu_temp_max(psu_index, temp_index, buf, count); + return ret; +} + +/* + * wb_set_psu_temp_max - Used to set the maximum threshold of temperature sensor of psu, + * get value from buf and set it to maximum threshold of psu temperature sensor + * @psu_index: start with 1 + * @temp_index: start with 1 + * @buf: the buf store the data to be set, eg '80.000' + * @count: length of buf + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int wb_set_psu_temp_max(unsigned int psu_index, unsigned int temp_index, + const char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->set_psu_temp_max); + + ret = g_drv->set_psu_temp_max(psu_index, temp_index, buf, count); + return ret; +} + +/* + * wb_get_psu_temp_min - Used to get the minimum threshold of temperature sensor of psu, + * filled the value to buf, the value is integer with millidegree Celsius + * @psu_index: start with 1 + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_temp_min(unsigned int psu_index, unsigned int temp_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_temp_min); + + ret = g_drv->get_psu_temp_min(psu_index, temp_index, buf, count); + return ret; +} + +/* + * wb_set_psu_temp_min - Used to set the minimum threshold of temperature sensor of psu, + * get value from buf and set it to minimum threshold of psu temperature sensor + * @psu_index: start with 1 + * @temp_index: start with 1 + * @buf: the buf store the data to be set, eg '50.000' + * @count: length of buf + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int wb_set_psu_temp_min(unsigned int psu_index, unsigned int temp_index, + const char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->set_psu_temp_min); + + ret = g_drv->set_psu_temp_min(psu_index, temp_index, buf, count); + return ret; +} + +/* + * wb_get_psu_temp_value - Used to get the input value of temperature sensor of psu + * filled the value to buf, the value is integer with millidegree Celsius + * @psu_index: start with 1 + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_temp_value(unsigned int psu_index, unsigned int temp_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_temp_value); + + ret = g_drv->get_psu_temp_value(psu_index, temp_index, buf, count); + return ret; +} + +/* + * wb_get_psu_eeprom_size - Used to get psu eeprom size + * + * This function returns the size of port eeprom, + * otherwise it returns a negative value on failed. + */ +static int wb_get_psu_eeprom_size(unsigned int psu_index) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_psu_eeprom_size); + + ret = g_drv->get_psu_eeprom_size(psu_index); + return ret; +} + +/* + * wb_read_psu_eeprom_data - Used to read psu eeprom data, + * @buf: Data read buffer + * @offset: offset address to read psu eeprom data + * @count: length of buf + * + * This function returns the length of the filled buffer, + * returns 0 means EOF, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_read_psu_eeprom_data(unsigned int psu_index, char *buf, loff_t offset, + size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->read_psu_eeprom_data); + + ret = g_drv->read_psu_eeprom_data(psu_index, buf, offset, count); + return ret; +} + +/* + * wb_get_psu_blackbox_info - Used to get psu blackbox information, + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_blackbox_info(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_blackbox_info); + + ret = g_drv->get_psu_blackbox_info(psu_index, buf, count); + return ret; +} + +/* + * wb_get_psu_pmbus_info - Used to get psu pmbus information, + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_psu_pmbus_info(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_psu_pmbus_info); + + ret = g_drv->get_psu_pmbus_info(psu_index, buf, count); + return ret; +} + +/* + * wb_clear_psu_blackbox - Used to clear psu blackbox information + * @psu_index: start with 1 + * @value: 1 + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int wb_clear_psu_blackbox(unsigned int psu_index, uint8_t value) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->clear_psu_blackbox); + + ret = g_drv->clear_psu_blackbox(psu_index, value); + return ret; +} + +/****************************************end of psu*******************************************/ + +static struct s3ip_sysfs_psu_drivers_s drivers = { + /* + * set ODM psu drivers to /sys/s3ip/psu, + * if not support the function, set corresponding hook to NULL. + */ + .get_psu_number = wb_get_psu_number, + .get_psu_temp_number = wb_get_psu_temp_number, + .get_psu_model_name = wb_get_psu_model_name, + .get_psu_vendor = wb_get_psu_vendor, + .get_psu_date = wb_get_psu_date, + .get_psu_status = wb_get_psu_status, + .get_psu_hw_status = wb_get_psu_hw_status, + .get_psu_alarm = wb_get_psu_alarm, + .get_psu_serial_number = wb_get_psu_serial_number, + .get_psu_part_number = wb_get_psu_part_number, + .get_psu_hardware_version = wb_get_psu_hardware_version, + .get_psu_type = wb_get_psu_type, + .get_psu_in_curr = wb_get_psu_in_curr, + .get_psu_in_vol = wb_get_psu_in_vol, + .get_psu_in_power = wb_get_psu_in_power, + .get_psu_out_curr = wb_get_psu_out_curr, + .get_psu_out_vol = wb_get_psu_out_vol, + .get_psu_out_power = wb_get_psu_out_power, + .get_psu_out_max_power = wb_get_psu_out_max_power, + .get_psu_present_status = wb_get_psu_present_status, + .get_psu_status_pmbus = wb_get_psu_status_pmbus, + .get_psu_in_status = wb_get_psu_in_status, + .get_psu_out_status = wb_get_psu_out_status, + .get_psu_fan_speed = wb_get_psu_fan_speed, + .get_psu_fan_ratio = wb_get_psu_fan_ratio, + .set_psu_fan_ratio = wb_set_psu_fan_ratio, + .get_psu_fan_direction = wb_get_psu_fan_direction, + .get_psu_led_status = wb_get_psu_led_status, + .get_psu_temp_alias = wb_get_psu_temp_alias, + .get_psu_temp_type = wb_get_psu_temp_type, + .get_psu_temp_max = wb_get_psu_temp_max, + .set_psu_temp_max = wb_set_psu_temp_max, + .get_psu_temp_min = wb_get_psu_temp_min, + .set_psu_temp_min = wb_set_psu_temp_min, + .get_psu_temp_value = wb_get_psu_temp_value, + .get_psu_fan_speed_cal = wb_get_psu_fan_speed_cal, + .get_psu_attr_threshold = wb_get_psu_attr_threshold, + .get_psu_eeprom_size = wb_get_psu_eeprom_size, + .read_psu_eeprom_data = wb_read_psu_eeprom_data, + .get_psu_blackbox_info = wb_get_psu_blackbox_info, + .get_psu_pmbus_info = wb_get_psu_pmbus_info, + .clear_psu_blackbox = wb_clear_psu_blackbox, +}; + +static int __init psu_dev_drv_init(void) +{ + int ret; + + PSU_INFO("psu_init...\n"); + g_drv = s3ip_switch_driver_get(); + check_p(g_drv); + + ret = s3ip_sysfs_psu_drivers_register(&drivers); + if (ret < 0) { + PSU_ERR("psu drivers register err, ret %d.\n", ret); + return ret; + } + PSU_INFO("psu_init success.\n"); + return 0; +} + +static void __exit psu_dev_drv_exit(void) +{ + s3ip_sysfs_psu_drivers_unregister(); + PSU_INFO("psu_exit ok.\n"); + + return; +} + +module_init(psu_dev_drv_init); +module_exit(psu_dev_drv_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4, all=0xf).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("psu device driver"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/slot_device_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/slot_device_driver.c new file mode 100644 index 000000000000..f22e51e1613e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/slot_device_driver.c @@ -0,0 +1,1100 @@ +/* + * An slot_device_driver driver for slot devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#include + +#include "device_driver_common.h" +#include "slot_sysfs.h" +#include "dfd_sysfs_common.h" + +#define SLOT_INFO(fmt, args...) LOG_INFO("slot: ", fmt, ##args) +#define SLOT_ERR(fmt, args...) LOG_ERR("slot: ", fmt, ##args) +#define SLOT_DBG(fmt, args...) LOG_DBG("slot: ", fmt, ##args) + +static int g_loglevel = 0; +static struct switch_drivers_s *g_drv = NULL; + +/******************************************slot***********************************************/ +static int wb_get_slot_number(void) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_slot_number); + + ret = g_drv->get_slot_number(); + return ret; +} + +static int wb_get_slot_temp_number(unsigned int slot_index) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_slot_temp_number); + + ret = g_drv->get_slot_temp_number(slot_index); + return ret; +} + +static int wb_get_slot_vol_number(unsigned int slot_index) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_slot_vol_number); + + ret = g_drv->get_slot_vol_number(slot_index); + return ret; +} + +static int wb_get_slot_curr_number(unsigned int slot_index) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_slot_curr_number); + + ret = g_drv->get_slot_curr_number(slot_index); + return ret; +} + +static int wb_get_slot_fpga_number(unsigned int slot_index) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_slot_fpga_number); + + ret = g_drv->get_slot_fpga_number(slot_index); + return ret; +} + +static int wb_get_slot_cpld_number(unsigned int slot_index) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_slot_cpld_number); + + ret = g_drv->get_slot_cpld_number(slot_index); + return ret; +} + +/* + * wb_get_slot_model_name - Used to get slot model name, + * @slot_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_model_name(unsigned int slot_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_model_name); + + ret = g_drv->get_slot_model_name(slot_index, buf, count); + return ret; +} + +/* + * wb_get_slot_vendor - Used to get slot model name, + * @slot_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_vendor(unsigned int slot_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_vendor); + + ret = g_drv->get_slot_vendor(slot_index, buf, count); + return ret; +} + +/* + * wb_get_slot_serial_number - Used to get slot serial number, + * @slot_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_serial_number(unsigned int slot_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_serial_number); + + ret = g_drv->get_slot_serial_number(slot_index, buf, count); + return ret; +} + +/* + * wb_get_slot_part_number - Used to get slot part number, + * @slot_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_part_number(unsigned int slot_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_part_number); + + ret = g_drv->get_slot_part_number(slot_index, buf, count); + return ret; +} + +/* + * wb_get_slot_hardware_version - Used to get slot hardware version, + * @slot_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_hardware_version(unsigned int slot_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_hardware_version); + + ret = g_drv->get_slot_hardware_version(slot_index, buf, count); + return ret; +} + +/* + * wb_get_slot_status - Used to get slot status, + * filled the value to buf, slot status define as below: + * 0: ABSENT + * 1: OK + * 2: NOT OK + * + * @slot_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_status(unsigned int slot_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_status); + + ret = g_drv->get_slot_status(slot_index, buf, count); + return ret; +} + +/* + * wb_get_slot_led_status - Used to get slot led status + * filled the value to buf, led status value define as below: + * 0: dark + * 1: green + * 2: yellow + * 3: red + * 4: blue + * 5: green light flashing + * 6: yellow light flashing + * 7: red light flashing + * 8: blue light flashing + * + * @slot_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_led_status(unsigned int slot_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_led_status); + + ret = g_drv->get_slot_led_status(slot_index, buf, count); + return ret; +} + +/* + * wb_set_slot_led_status - Used to set slot led status + * @slot_index: start with 1 + * @status: led status, led status value define as below: + * 0: dark + * 1: green + * 2: yellow + * 3: red + * 4:blue + * 5: green light flashing + * 6: yellow light flashing + * 7: red light flashing + * 8:blue light flashing + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int wb_set_slot_led_status(unsigned int slot_index, int status) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->set_slot_led_status); + + ret = g_drv->set_slot_led_status(slot_index, status); + return ret; +} + +/* + * wb_set_slot_power_status - Used to set slot power status, + * filled the value to buf, slot status define as below: + * 0: OFF + * 1: ON + * + * @slot_index: start with 1 + * @status: power status + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static int wb_set_slot_power_status(unsigned int slot_index, int status) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->set_slot_power_status); + + ret = g_drv->set_slot_power_status(slot_index, status); + return ret; +} + +/* + * wb_get_slot_power_status - Used to get slot power status, + * filled the value to buf, slot status define as below: + * 0: OFF + * 1: ON + * + * @slot_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_power_status(unsigned int slot_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_power_status); + + ret = g_drv->get_slot_power_status(slot_index, buf, count); + return ret; +} + +/* + * wb_get_slot_temp_alias - Used to identify the location of the temperature sensor of slot, + * @slot_index: start with 1 + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_temp_alias(unsigned int slot_index, unsigned int temp_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_temp_alias); + + ret = g_drv->get_slot_temp_alias(slot_index, temp_index, buf, count); + return ret; +} + +/* + * wb_get_slot_temp_type - Used to get the model of temperature sensor of slot, + * @slot_index: start with 1 + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_temp_type(unsigned int slot_index, unsigned int temp_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_temp_type); + + ret = g_drv->get_slot_temp_type(slot_index, temp_index, buf, count); + return ret; +} + +/* + * wb_get_slot_temp_max - Used to get the maximum threshold of temperature sensor of slot, + * filled the value to buf, the value is integer with millidegree Celsius + * @slot_index: start with 1 + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_temp_max(unsigned int slot_index, unsigned int temp_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_temp_max); + + ret = g_drv->get_slot_temp_max(slot_index, temp_index, buf, count); + return ret; +} + +/* + * wb_get_slot_temp_min - Used to get the minimum threshold of temperature sensor of slot, + * filled the value to buf, the value is integer with millidegree Celsius + * @slot_index: start with 1 + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_temp_min(unsigned int slot_index, unsigned int temp_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_temp_min); + + ret = g_drv->get_slot_temp_min(slot_index, temp_index, buf, count); + return ret; +} + +/* + * wb_get_slot_temp_value - Used to get the input value of temperature sensor of slot, + * filled the value to buf, the value is integer with millidegree Celsius + * @slot_index: start with 1 + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_temp_value(unsigned int slot_index, unsigned int temp_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_temp_value); + + ret = g_drv->get_slot_temp_value(slot_index, temp_index, buf, count); + return ret; +} + +/* + * wb_get_slot_vol_alias - Used to identify the location of the voltage sensor of slot, + * @slot_index: start with 1 + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_vol_alias(unsigned int slot_index, unsigned int vol_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_vol_alias); + + ret = g_drv->get_slot_vol_alias(slot_index, vol_index, buf, count); + return ret; +} + +/* + * wb_get_slot_vol_type - Used to get the model of voltage sensor of slot, + * such as udc90160, tps53622 and so on + * @slot_index: start with 1 + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_vol_type(unsigned int slot_index, unsigned int vol_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_vol_type); + + ret = g_drv->get_slot_vol_type(slot_index, vol_index, buf, count); + return ret; +} + +/* + * wb_get_slot_vol_max - Used to get the maximum threshold of voltage sensor of slot, + * filled the value to buf, the value is integer with mV + * @slot_index: start with 1 + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_vol_max(unsigned int slot_index, unsigned int vol_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_vol_max); + + ret = g_drv->get_slot_vol_max(slot_index, vol_index, buf, count); + return ret; +} + +/* + * wb_get_slot_vol_min - Used to get the minimum threshold of voltage sensor of slot, + * filled the value to buf, the value is integer with mV + * @slot_index: start with 1 + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_vol_min(unsigned int slot_index, unsigned int vol_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_vol_min); + + ret = g_drv->get_slot_vol_min(slot_index, vol_index, buf, count); + return ret; +} + +/* + * wb_get_slot_vol_range - Used to get the output error value of voltage sensor of slot, + * filled the value to buf + * @slot_index: start with 1 + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_vol_range(unsigned int slot_index, unsigned int vol_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_vol_range); + + ret = g_drv->get_slot_vol_range(slot_index, vol_index, buf, count); + return ret; +} + +/* + * wb_get_slot_vol_nominal_value - Used to get the nominal value of voltage sensor of slot, + * filled the value to buf + * @slot_index: start with 1 + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_vol_nominal_value(unsigned int slot_index, + unsigned int vol_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_vol_nominal_value); + + ret = g_drv->get_slot_vol_nominal_value(slot_index, vol_index, buf, count); + return ret; +} + +/* + * wb_get_slot_vol_value - Used to get the input value of voltage sensor of slot, + * filled the value to buf, the value is integer with mV + * @slot_index: start with 1 + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_vol_value(unsigned int slot_index, unsigned int vol_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_vol_value); + + ret = g_drv->get_slot_vol_value(slot_index, vol_index, buf, count); + return ret; +} + +/* + * wb_get_slot_curr_alias - Used to identify the location of the current sensor of slot, + * @slot_index: start with 1 + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_curr_alias(unsigned int slot_index, unsigned int curr_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_curr_alias); + + ret = g_drv->get_slot_curr_alias(slot_index, curr_index, buf, count); + return ret; +} + +/* + * wb_get_slot_curr_type - Used to get the model of current sensor of slot, + * @slot_index: start with 1 + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_curr_type(unsigned int slot_index, unsigned int curr_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_curr_type); + + ret = g_drv->get_slot_curr_type(slot_index, curr_index, buf, count); + return ret; +} + +/* + * wb_get_slot_curr_max - Used to get the maximum threshold of current sensor of slot, + * filled the value to buf, the value is integer with mA + * @slot_index: start with 1 + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_curr_max(unsigned int slot_index, unsigned int curr_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_curr_max); + + ret = g_drv->get_slot_curr_max(slot_index, curr_index, buf, count); + return ret; +} + +/* + * wb_get_slot_curr_min - Used to get the minimum threshold of current sensor of slot, + * filled the value to buf, the value is integer with mA + * @slot_index: start with 1 + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_curr_min(unsigned int slot_index, unsigned int curr_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_curr_min); + + ret = g_drv->get_slot_curr_min(slot_index, curr_index, buf, count); + return ret; +} + +/* + * wb_get_slot_curr_value - Used to get the input value of current sensor of slot, + * filled the value to buf, the value is integer with mA + * @slot_index: start with 1 + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_curr_value(unsigned int slot_index, unsigned int curr_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_curr_value); + + ret = g_drv->get_slot_curr_value(slot_index, curr_index, buf, count); + return ret; +} + +/* + * wb_get_slot_fpga_alias - Used to identify the location of slot fpga, + * @slot_index: start with 1 + * @fpga_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_fpga_alias(unsigned int slot_index, unsigned int fpga_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_fpga_alias); + + ret = g_drv->get_slot_fpga_alias(slot_index, fpga_index, buf, count); + return ret; +} + +/* + * wb_get_slot_fpga_type - Used to get slot fpga model name + * @slot_index: start with 1 + * @fpga_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_fpga_type(unsigned int slot_index, unsigned int fpga_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_fpga_type); + + ret = g_drv->get_slot_fpga_type(slot_index, fpga_index, buf, count); + return ret; +} + +/* + * wb_get_slot_fpga_firmware_version - Used to get slot fpga firmware version, + * @slot_index: start with 1 + * @fpga_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_fpga_firmware_version(unsigned int slot_index, unsigned int fpga_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_fpga_firmware_version); + + ret = g_drv->get_slot_fpga_firmware_version(slot_index, fpga_index, buf, count); + return ret; +} + +/* + * wb_get_slot_fpga_board_version - Used to get slot fpga board version, + * @slot_index: start with 1 + * @fpga_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_fpga_board_version(unsigned int slot_index, unsigned int fpga_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_fpga_board_version); + + ret = g_drv->get_slot_fpga_board_version(slot_index, fpga_index, buf, count); + return ret; +} + +/* + * wb_get_slot_fpga_test_reg - Used to test slot fpga register read + * filled the value to buf, value is hexadecimal, start with 0x + * @slot_index: start with 1 + * @fpga_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_fpga_test_reg(unsigned int slot_index, unsigned int fpga_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_fpga_test_reg); + + ret = g_drv->get_slot_fpga_test_reg(slot_index, fpga_index, buf, count); + return ret; +} + +/* + * wb_set_slot_fpga_test_reg - Used to test slot fpga register write + * @slot_index: start with 1 + * @fpga_index: start with 1 + * @value: value write to slot fpga + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int wb_set_slot_fpga_test_reg(unsigned int slot_index, unsigned int fpga_index, + unsigned int value) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->set_slot_fpga_test_reg); + + ret = g_drv->set_slot_fpga_test_reg(slot_index, fpga_index, value); + return ret; +} + +/* + * wb_get_slot_cpld_alias - Used to identify the location of slot cpld, + * @slot_index: start with 1 + * @cpld_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_cpld_alias(unsigned int slot_index, unsigned int cpld_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_cpld_alias); + + ret = g_drv->get_slot_cpld_alias(slot_index, cpld_index, buf, count); + return ret; +} + +/* + * wb_get_slot_cpld_type - Used to get slot cpld model name + * @slot_index: start with 1 + * @cpld_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_cpld_type(unsigned int slot_index, unsigned int cpld_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_cpld_type); + + ret = g_drv->get_slot_cpld_type(slot_index, cpld_index, buf, count); + return ret; +} + +/* + * wb_get_slot_cpld_firmware_version - Used to get slot cpld firmware version, + * @slot_index: start with 1 + * @cpld_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_cpld_firmware_version(unsigned int slot_index, unsigned int cpld_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_cpld_firmware_version); + + ret = g_drv->get_slot_cpld_firmware_version(slot_index, cpld_index, buf, count); + return ret; +} + +/* + * wb_get_slot_cpld_board_version - Used to get slot cpld board version, + * @slot_index: start with 1 + * @cpld_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_cpld_board_version(unsigned int slot_index, unsigned int cpld_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_cpld_board_version); + + ret = g_drv->get_slot_cpld_board_version(slot_index, cpld_index, buf, count); + return ret; +} + +/* + * wb_get_slot_cpld_test_reg - Used to test slot cpld register read + * filled the value to buf, value is hexadecimal, start with 0x + * @slot_index: start with 1 + * @cpld_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_slot_cpld_test_reg(unsigned int slot_index, unsigned int cpld_index, + char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_slot_cpld_test_reg); + + ret = g_drv->get_slot_cpld_test_reg(slot_index, cpld_index, buf, count); + return ret; +} + +/* + * wb_set_slot_cpld_test_reg - Used to test slot cpld register write + * @slot_index: start with 1 + * @cpld_index: start with 1 + * @value: value write to slot cpld + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int wb_set_slot_cpld_test_reg(unsigned int slot_index, unsigned int cpld_index, + unsigned int value) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->set_slot_cpld_test_reg); + + ret = g_drv->set_slot_cpld_test_reg(slot_index, cpld_index, value); + return ret; +} +/***************************************end of slot*******************************************/ + +static struct s3ip_sysfs_slot_drivers_s drivers = { + /* + * set ODM slot drivers to /sys/s3ip/slot, + * if not support the function, set corresponding hook to NULL. + */ + .get_slot_number = wb_get_slot_number, + .get_slot_temp_number = wb_get_slot_temp_number, + .get_slot_vol_number = wb_get_slot_vol_number, + .get_slot_curr_number = wb_get_slot_curr_number, + .get_slot_cpld_number = wb_get_slot_cpld_number, + .get_slot_fpga_number = wb_get_slot_fpga_number, + .get_slot_model_name = wb_get_slot_model_name, + .get_slot_vendor = wb_get_slot_vendor, + .get_slot_serial_number = wb_get_slot_serial_number, + .get_slot_part_number = wb_get_slot_part_number, + .get_slot_hardware_version = wb_get_slot_hardware_version, + .get_slot_status = wb_get_slot_status, + .get_slot_led_status = wb_get_slot_led_status, + .set_slot_led_status = wb_set_slot_led_status, + .get_slot_power_status = wb_get_slot_power_status, + .set_slot_power_status = wb_set_slot_power_status, + .get_slot_temp_alias = wb_get_slot_temp_alias, + .get_slot_temp_type = wb_get_slot_temp_type, + .get_slot_temp_max = wb_get_slot_temp_max, + .get_slot_temp_min = wb_get_slot_temp_min, + .get_slot_temp_value = wb_get_slot_temp_value, + .get_slot_vol_alias = wb_get_slot_vol_alias, + .get_slot_vol_type = wb_get_slot_vol_type, + .get_slot_vol_max = wb_get_slot_vol_max, + .get_slot_vol_min = wb_get_slot_vol_min, + .get_slot_vol_range = wb_get_slot_vol_range, + .get_slot_vol_nominal_value = wb_get_slot_vol_nominal_value, + .get_slot_vol_value = wb_get_slot_vol_value, + .get_slot_curr_alias = wb_get_slot_curr_alias, + .get_slot_curr_type = wb_get_slot_curr_type, + .get_slot_curr_max = wb_get_slot_curr_max, + .get_slot_curr_min = wb_get_slot_curr_min, + .get_slot_curr_value = wb_get_slot_curr_value, + .get_slot_fpga_alias = wb_get_slot_fpga_alias, + .get_slot_fpga_alias = wb_get_slot_fpga_alias, + .get_slot_fpga_type = wb_get_slot_fpga_type, + .get_slot_fpga_firmware_version = wb_get_slot_fpga_firmware_version, + .get_slot_fpga_board_version = wb_get_slot_fpga_board_version, + .get_slot_fpga_test_reg = wb_get_slot_fpga_test_reg, + .set_slot_fpga_test_reg = wb_set_slot_fpga_test_reg, + .get_slot_cpld_alias = wb_get_slot_cpld_alias, + .get_slot_cpld_type = wb_get_slot_cpld_type, + .get_slot_cpld_firmware_version = wb_get_slot_cpld_firmware_version, + .get_slot_cpld_board_version = wb_get_slot_cpld_board_version, + .get_slot_cpld_test_reg = wb_get_slot_cpld_test_reg, + .set_slot_cpld_test_reg = wb_set_slot_cpld_test_reg, +}; + +static int __init slot_dev_drv_init(void) +{ + int ret; + + SLOT_INFO("slot_init...\n"); + g_drv = s3ip_switch_driver_get(); + check_p(g_drv); + + ret = s3ip_sysfs_slot_drivers_register(&drivers); + if (ret < 0) { + SLOT_ERR("slot drivers register err, ret %d.\n", ret); + return ret; + } + SLOT_INFO("slot_init success.\n"); + return 0; +} + +static void __exit slot_dev_drv_exit(void) +{ + s3ip_sysfs_slot_drivers_unregister(); + SLOT_INFO("slot_exit success.\n"); + return; +} + +module_init(slot_dev_drv_init); +module_exit(slot_dev_drv_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4, all=0xf).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("slot device driver"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/syseeprom_device_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/syseeprom_device_driver.c new file mode 100644 index 000000000000..c431c5dbb703 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/syseeprom_device_driver.c @@ -0,0 +1,136 @@ +/* + * An syseeprom_device_driver driver for syseeprom devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#include + +#include "device_driver_common.h" +#include "syseeprom_sysfs.h" +#include "dfd_sysfs_common.h" + +#define SYSE2_INFO(fmt, args...) LOG_INFO("syseeprom: ", fmt, ##args) +#define SYSE2_ERR(fmt, args...) LOG_ERR("syseeprom: ", fmt, ##args) +#define SYSE2_DBG(fmt, args...) LOG_DBG("syseeprom: ", fmt, ##args) + +static int g_loglevel = 0; +static struct switch_drivers_s *g_drv = NULL; + +/*****************************************syseeprom*******************************************/ +/* + * wb_get_syseeprom_size - Used to get syseeprom size + * + * This function returns the size of syseeprom by your switch, + * otherwise it returns a negative value on failed. + */ +static int wb_get_syseeprom_size(void) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_syseeprom_size); + + ret = g_drv->get_syseeprom_size(); + return ret; +} + +/* + * wb_read_syseeprom_data - Used to read syseeprom data, + * @buf: Data read buffer + * @offset: offset address to read syseeprom data + * @count: length of buf + * + * This function returns the length of the filled buffer, + * returns 0 means EOF, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_read_syseeprom_data(char *buf, loff_t offset, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->read_syseeprom_data); + + ret = g_drv->read_syseeprom_data(buf, offset, count); + return ret; +} + +/* + * wb_write_syseeprom_data - Used to write syseeprom data + * @buf: Data write buffer + * @offset: offset address to write syseeprom data + * @count: length of buf + * + * This function returns the written length of syseeprom, + * returns 0 means EOF, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_write_syseeprom_data(char *buf, loff_t offset, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->write_syseeprom_data); + + ret = g_drv->write_syseeprom_data(buf, offset, count); + return ret; +} +/*************************************end of syseeprom****************************************/ + +static struct s3ip_sysfs_syseeprom_drivers_s drivers = { + /* + * set ODM syseeprom drivers to /sys/s3ip/syseeprom, + * if not support the function, set corresponding hook to NULL. + */ + .get_syseeprom_size = wb_get_syseeprom_size, + .read_syseeprom_data = wb_read_syseeprom_data, + .write_syseeprom_data = wb_write_syseeprom_data, +}; + +static int __init syseeprom_dev_drv_init(void) +{ + int ret; + + SYSE2_INFO("syseeprom_dev_drv_init...\n"); + g_drv = s3ip_switch_driver_get(); + check_p(g_drv); + + ret = s3ip_sysfs_syseeprom_drivers_register(&drivers); + if (ret < 0) { + SYSE2_ERR("syseeprom drivers register err, ret %d.\n", ret); + return ret; + } + SYSE2_INFO("syseeprom_dev_drv_init success.\n"); + return 0; +} + +static void __exit syseeprom_dev_drv_exit(void) +{ + s3ip_sysfs_syseeprom_drivers_unregister(); + SYSE2_INFO("syseeprom_exit success.\n"); + return; +} + +module_init(syseeprom_dev_drv_init); +module_exit(syseeprom_dev_drv_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4, all=0xf).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("syseeprom device driver"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/sysled_device_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/sysled_device_driver.c new file mode 100644 index 000000000000..05da8b680084 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/sysled_device_driver.c @@ -0,0 +1,240 @@ +/* + * An sysled_device_driver driver for sysled devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#include + +#include "device_driver_common.h" +#include "sysled_sysfs.h" +#include "dfd_sysfs_common.h" + +#define SYSLED_INFO(fmt, args...) LOG_INFO("sysled: ", fmt, ##args) +#define SYSLED_ERR(fmt, args...) LOG_ERR("sysled: ", fmt, ##args) +#define SYSLED_DBG(fmt, args...) LOG_DBG("sysled: ", fmt, ##args) + +static int g_loglevel = 0; +static struct switch_drivers_s *g_drv = NULL; + +/*****************************************sysled**********************************************/ +/* + * wb_get_sys_led_status - Used to get sys led status + * filled the value to buf, led status value define as below: + * 0: dark + * 1: green + * 2: yellow + * 3: red + * 4: blue + * 5: green light flashing + * 6: yellow light flashing + * 7: red light flashing + * 8: blue light flashing + * + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_sys_led_status(char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_sys_led_status); + + ret = g_drv->get_sys_led_status(buf, count); + return ret; +} + +/* + * wb_set_sys_led_status - Used to set sys led status + * @status: led status, led status value define as below: + * 0: dark + * 1: green + * 2: yellow + * 3: red + * 4: blue + * 5: green light flashing + * 6: yellow light flashing + * 7: red light flashing + * 8: blue light flashing + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int wb_set_sys_led_status(int status) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->set_sys_led_status); + + ret = g_drv->set_sys_led_status(status); + return ret; +} + +/* Similar to wb_get_sys_led_status */ +static ssize_t wb_get_bmc_led_status(char *buf, size_t count) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_bmc_led_status); + + ret = g_drv->get_bmc_led_status(buf, count); + return ret; +} + +/* Similar to wb_set_sys_led_status */ +static int wb_set_bmc_led_status(int status) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->set_bmc_led_status); + + ret = g_drv->set_bmc_led_status(status); + return ret; +} + +/* Similar to wb_get_sys_led_status */ +static ssize_t wb_get_sys_fan_led_status(char *buf, size_t count) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_sys_fan_led_status); + + ret = g_drv->get_sys_fan_led_status(buf, count); + return ret; +} + +/* Similar to wb_set_sys_led_status */ +static int wb_set_sys_fan_led_status(int status) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->set_sys_fan_led_status); + + ret = g_drv->set_sys_fan_led_status(status); + return ret; +} + +/* Similar to wb_get_sys_led_status */ +static ssize_t wb_get_sys_psu_led_status(char *buf, size_t count) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_sys_psu_led_status); + + ret = g_drv->get_sys_psu_led_status(buf, count); + return ret; +} + +/* Similar to wb_set_sys_led_status */ +static int wb_set_sys_psu_led_status(int status) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->set_sys_psu_led_status); + + ret = g_drv->set_sys_psu_led_status(status); + return ret; +} + +/* Similar to wb_get_sys_led_status */ +static ssize_t wb_get_id_led_status(char *buf, size_t count) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_id_led_status); + + ret = g_drv->get_id_led_status(buf, count); + return ret; +} + +/* Similar to wb_set_sys_led_status */ +static int wb_set_id_led_status(int status) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->set_id_led_status); + + ret = g_drv->set_id_led_status(status); + return ret; +} + +/**************************************end of sysled******************************************/ + +static struct s3ip_sysfs_sysled_drivers_s drivers = { + /* + * set ODM sysled drivers to /sys/s3ip/sysled, + * if not support the function, set corresponding hook to NULL. + */ + .get_sys_led_status = wb_get_sys_led_status, + .set_sys_led_status = wb_set_sys_led_status, + .get_bmc_led_status = wb_get_bmc_led_status, + .set_bmc_led_status = wb_set_bmc_led_status, + .get_sys_fan_led_status = wb_get_sys_fan_led_status, + .set_sys_fan_led_status = wb_set_sys_fan_led_status, + .get_sys_psu_led_status = wb_get_sys_psu_led_status, + .set_sys_psu_led_status = wb_set_sys_psu_led_status, + .get_id_led_status = wb_get_id_led_status, + .set_id_led_status = wb_set_id_led_status, +}; + +static int __init sysled_init(void) +{ + int ret; + + SYSLED_INFO("sysled_init...\n"); + g_drv = s3ip_switch_driver_get(); + check_p(g_drv); + + ret = s3ip_sysfs_sysled_drivers_register(&drivers); + if (ret < 0) { + SYSLED_ERR("sysled drivers register err, ret %d.\n", ret); + return ret; + } + + SYSLED_INFO("sysled create success.\n"); + return 0; +} + +static void __exit sysled_exit(void) +{ + s3ip_sysfs_sysled_drivers_unregister(); + SYSLED_INFO("sysled_exit ok.\n"); + return; +} + +module_init(sysled_init); +module_exit(sysled_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4, all=0xf).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("sysled device driver"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/system_device_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/system_device_driver.c new file mode 100644 index 000000000000..65013163cb90 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/system_device_driver.c @@ -0,0 +1,109 @@ +/* + * An system_device_driver driver for system devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#include + +#include "device_driver_common.h" +#include "system_sysfs.h" +#include "dfd_sysfs_common.h" + +#define TEMP_SENSOR_INFO(fmt, args...) LOG_INFO("system: ", fmt, ##args) +#define TEMP_SENSOR_ERR(fmt, args...) LOG_ERR("system: ", fmt, ##args) +#define TEMP_SENSOR_DBG(fmt, args...) LOG_DBG("system: ", fmt, ##args) + +static int g_loglevel = 0; +static struct switch_drivers_s *g_drv = NULL; + +static ssize_t wb_set_system_value(unsigned int type, int value) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->set_system_value); + + ret = g_drv->set_system_value(type, value); + return ret; +} + +static ssize_t wb_get_system_value(unsigned int type, int *value, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_system_value); + + ret = g_drv->get_system_value(type, value, buf, count); + return ret; +} + +static ssize_t wb_get_system_port_power_status(unsigned int type, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_system_port_power_status); + + ret = g_drv->get_system_port_power_status(type, buf, count); + return ret; +} +/***********************************end of main board temp*************************************/ + +static struct s3ip_sysfs_system_drivers_s drivers = { + /* + * set ODM system drivers to /sys/s3ip/system, + * if not support the function, set corresponding hook to NULL. + */ + .get_system_value = wb_get_system_value, + .set_system_value = wb_set_system_value, + .get_system_port_power_status = wb_get_system_port_power_status, +}; + +static int __init system_dev_drv_init(void) +{ + int ret; + + TEMP_SENSOR_INFO("system_init...\n"); + g_drv = s3ip_switch_driver_get(); + check_p(g_drv); + + ret = s3ip_sysfs_system_drivers_register(&drivers); + if (ret < 0) { + TEMP_SENSOR_ERR("temp sensor drivers register err, ret %d.\n", ret); + return ret; + } + TEMP_SENSOR_INFO("system_init success.\n"); + return 0; +} + +static void __exit system_dev_drv_exit(void) +{ + s3ip_sysfs_system_drivers_unregister(); + TEMP_SENSOR_INFO("system_exit success.\n"); + return; +} + +module_init(system_dev_drv_init); +module_exit(system_dev_drv_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4, all=0xf).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("system device driver"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/temp_sensor_device_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/temp_sensor_device_driver.c new file mode 100644 index 000000000000..afd0bc25c8d0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/temp_sensor_device_driver.c @@ -0,0 +1,275 @@ +/* + * An temp_sensor_device_driver driver for temperature devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#include + +#include "device_driver_common.h" +#include "temp_sensor_sysfs.h" +#include "dfd_sysfs_common.h" + +#define TEMP_SENSOR_INFO(fmt, args...) LOG_INFO("temp_sensor: ", fmt, ##args) +#define TEMP_SENSOR_ERR(fmt, args...) LOG_ERR("temp_sensor: ", fmt, ##args) +#define TEMP_SENSOR_DBG(fmt, args...) LOG_DBG("temp_sensor: ", fmt, ##args) + +static int g_loglevel = 0; +static struct switch_drivers_s *g_drv = NULL; + +/***************************************main board temp*****************************************/ +/* + * wb_get_main_board_temp_number - Used to get main board temperature sensors number, + * + * This function returns main board temperature sensors by your switch, + * If there is no main board temperature sensors, returns 0, + * otherwise it returns a negative value on failed. + */ +static int wb_get_main_board_temp_number(void) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_temp_number); + + ret = g_drv->get_main_board_temp_number(); + return ret; +} + +/* + * wb_get_main_board_temp_alias - Used to identify the location of the temperature sensor, + * such as air_inlet, air_outlet and so on. + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_temp_alias(unsigned int temp_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_temp_alias); + + ret = g_drv->get_main_board_temp_alias(temp_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_temp_type - Used to get the model of temperature sensor, + * such as lm75, tmp411 and so on + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_temp_type(unsigned int temp_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_temp_type); + + ret = g_drv->get_main_board_temp_type(temp_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_temp_max - Used to get the maximum threshold of temperature sensor + * filled the value to buf, the value is integer with millidegree Celsius + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_temp_max(unsigned int temp_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_temp_max); + + ret = g_drv->get_main_board_temp_max(temp_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_temp_min - Used to get the minimum threshold of temperature sensor + * filled the value to buf, the value is integer with millidegree Celsius + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_temp_min(unsigned int temp_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_temp_min); + + ret = g_drv->get_main_board_temp_min(temp_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_temp_high - Used to get the highimum threshold of temperature sensor + * filled the value to buf, the value is integer with millidegree Celsius + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_temp_high(unsigned int temp_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_temp_high); + + ret = g_drv->get_main_board_temp_high(temp_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_temp_low - Used to get the lowimum threshold of temperature sensor + * filled the value to buf, the value is integer with millidegree Celsius + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_temp_low(unsigned int temp_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_temp_low); + + ret = g_drv->get_main_board_temp_low(temp_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_temp_value - Used to get the input value of temperature sensor + * filled the value to buf, the value is integer with millidegree Celsius + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_temp_value(unsigned int temp_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_temp_value); + + ret = g_drv->get_main_board_temp_value(temp_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_temp_monitor_flag - Used to get the monitor flag of temperature sensor + * filled the value to buf, the value is integer with millidegree Celsius + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_temp_monitor_flag(unsigned int temp_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_temp_monitor_flag); + + ret = g_drv->get_main_board_temp_monitor_flag(temp_index, buf, count); + return ret; +} +/***********************************end of main board temp*************************************/ + +static struct s3ip_sysfs_temp_sensor_drivers_s drivers = { + /* + * set ODM temperature sensor drivers to /sys/s3ip/temp_sensor, + * if not support the function, set corresponding hook to NULL. + */ + .get_main_board_temp_number = wb_get_main_board_temp_number, + .get_main_board_temp_alias = wb_get_main_board_temp_alias, + .get_main_board_temp_type = wb_get_main_board_temp_type, + .get_main_board_temp_max = wb_get_main_board_temp_max, + .get_main_board_temp_min = wb_get_main_board_temp_min, + .get_main_board_temp_value = wb_get_main_board_temp_value, + .get_main_board_temp_high = wb_get_main_board_temp_high, + .get_main_board_temp_low = wb_get_main_board_temp_low, + .get_main_board_temp_monitor_flag = wb_get_main_board_temp_monitor_flag, +}; + +static int __init temp_sensor_dev_drv_init(void) +{ + int ret; + + TEMP_SENSOR_INFO("temp_sensor_init...\n"); + g_drv = s3ip_switch_driver_get(); + check_p(g_drv); + + ret = s3ip_sysfs_temp_sensor_drivers_register(&drivers); + if (ret < 0) { + TEMP_SENSOR_ERR("temp sensor drivers register err, ret %d.\n", ret); + return ret; + } + TEMP_SENSOR_INFO("temp_sensor_init success.\n"); + return 0; +} + +static void __exit temp_sensor_dev_drv_exit(void) +{ + s3ip_sysfs_temp_sensor_drivers_unregister(); + TEMP_SENSOR_INFO("temp_sensor_exit success.\n"); + return; +} + +module_init(temp_sensor_dev_drv_init); +module_exit(temp_sensor_dev_drv_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4, all=0xf).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("temperature sensors device driver"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/transceiver_device_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/transceiver_device_driver.c new file mode 100644 index 000000000000..1aad05fea3f5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/transceiver_device_driver.c @@ -0,0 +1,481 @@ +/* + * An transceiver_device_driver driver for sff devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#include "device_driver_common.h" +#include "transceiver_sysfs.h" +#include "dfd_sysfs_common.h" + +#define SFF_INFO(fmt, args...) LOG_INFO("sff: ", fmt, ##args) +#define SFF_ERR(fmt, args...) LOG_ERR("sff: ", fmt, ##args) +#define SFF_DBG(fmt, args...) LOG_DBG("sff: ", fmt, ##args) + +static int g_loglevel = 0; +static struct switch_drivers_s *g_drv = NULL; + +/****************************************transceiver******************************************/ +static int wb_get_eth_number(void) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_eth_number); + + ret = g_drv->get_eth_number(); + return ret; +} + +/* + * wb_get_transceiver_power_on_status - Used to get the whole machine port power on status, + * filled the value to buf, 0: power off, 1: power on + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_transceiver_power_on_status(char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_transceiver_power_on_status); + + ret = g_drv->get_transceiver_power_on_status(buf, count); + return ret; +} + +/* + * wb_set_transceiver_power_on_status - Used to set the whole machine port power on status, + * @status: power on status, 0: power off, 1: power on + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int wb_set_transceiver_power_on_status(int status) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->set_transceiver_power_on_status); + + ret = g_drv->set_transceiver_power_on_status(status); + return ret; +} + +/* + * wb_get_transceiver_present_status - Used to get the whole machine port present status, + * filled the value to buf, 0: absent, 1: present + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_transceiver_present_status(char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_transceiver_present_status); + + ret = g_drv->get_transceiver_present_status(buf, count); + return ret; +} + +/* + * wb_get_eth_power_on_status - Used to get single port power on status, + * filled the value to buf, 0: power off, 1: power on + * @eth_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_eth_power_on_status(unsigned int eth_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_eth_power_on_status); + + ret = g_drv->get_eth_power_on_status(eth_index, buf, count); + return ret; +} + +/* + * wb_set_eth_power_on_status - Used to set single port power on status, + * @eth_index: start with 1 + * @status: power on status, 0: power off, 1: power on + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int wb_set_eth_power_on_status(unsigned int eth_index, int status) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->set_eth_power_on_status); + + ret = g_drv->set_eth_power_on_status(eth_index, status); + return ret; +} + +/* + * wb_get_eth_tx_fault_status - Used to get port tx_fault status, + * filled the value to buf, 0: normal, 1: abnormal + * @eth_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_eth_tx_fault_status(unsigned int eth_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_eth_tx_fault_status); + + ret = g_drv->get_eth_tx_fault_status(eth_index, buf, count); + return ret; +} + +/* + * wb_get_eth_tx_disable_status - Used to get port tx_disable status, + * filled the value to buf, 0: tx_enable, 1: tx_disable + * @eth_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_eth_tx_disable_status(unsigned int eth_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_eth_tx_disable_status); + + ret = g_drv->get_eth_tx_disable_status(eth_index, buf, count); + return ret; +} + +/* + * wb_set_eth_tx_disable_status - Used to set port tx_disable status, + * @eth_index: start with 1 + * @status: tx_disable status, 0: tx_enable, 1: tx_disable + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int wb_set_eth_tx_disable_status(unsigned int eth_index, int status) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->set_eth_tx_disable_status); + + ret = g_drv->set_eth_tx_disable_status(eth_index, status); + return ret; +} + +/* + * wb_get_eth_present_status - Used to get port present status, + * filled the value to buf, 1: present, 0: absent + * @eth_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_eth_present_status(unsigned int eth_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_eth_present_status); + + ret = g_drv->get_eth_present_status(eth_index, buf, count); + return ret; +} + +/* + * wb_get_eth_rx_los_status - Used to get port rx_los status, + * filled the value to buf, 0: normal, 1: abnormal + * @eth_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_eth_rx_los_status(unsigned int eth_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_eth_rx_los_status); + + ret = g_drv->get_eth_rx_los_status(eth_index, buf, count); + return ret; +} + +/* + * wb_get_eth_reset_status - Used to get port reset status, + * filled the value to buf, 0: unreset, 1: reset + * @eth_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_eth_reset_status(unsigned int eth_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_eth_reset_status); + + ret = g_drv->get_eth_reset_status(eth_index, buf, count); + return ret; +} + +/* + * wb_set_eth_reset_status - Used to set port reset status, + * @eth_index: start with 1 + * @status: reset status, 0: unreset, 1: reset + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int wb_set_eth_reset_status(unsigned int eth_index, int status) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->set_eth_reset_status); + + ret = g_drv->set_eth_reset_status(eth_index, status); + return ret; +} + +/* + * wb_get_eth_low_power_mode_status - Used to get port low power mode status, + * filled the value to buf, 0: high power mode, 1: low power mode + * @eth_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_eth_low_power_mode_status(unsigned int eth_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_eth_low_power_mode_status); + + ret = g_drv->get_eth_low_power_mode_status(eth_index, buf, count); + return ret; +} + +/* + * wb_get_eth_interrupt_status - Used to get port interruption status, + * filled the value to buf, 0: no interruption, 1: interruption + * @eth_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_eth_interrupt_status(unsigned int eth_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_eth_interrupt_status); + + ret = g_drv->get_eth_interrupt_status(eth_index, buf, count); + return ret; +} + +/* + * wb_get_eth_eeprom_size - Used to get port eeprom size + * + * This function returns the size of port eeprom, + * otherwise it returns a negative value on failed. + */ +static int wb_get_eth_eeprom_size(unsigned int eth_index) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_eth_eeprom_size); + + ret = g_drv->get_eth_eeprom_size(eth_index); + return ret; +} + +/* + * wb_read_eth_eeprom_data - Used to read port eeprom data, + * @buf: Data read buffer + * @offset: offset address to read port eeprom data + * @count: length of buf + * + * This function returns the length of the filled buffer, + * returns 0 means EOF, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_read_eth_eeprom_data(unsigned int eth_index, char *buf, loff_t offset, + size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->read_eth_eeprom_data); + + ret = g_drv->read_eth_eeprom_data(eth_index, buf, offset, count); + return ret; +} + +/* + * wb_write_eth_eeprom_data - Used to write port eeprom data + * @buf: Data write buffer + * @offset: offset address to write port eeprom data + * @count: length of buf + * + * This function returns the written length of port eeprom, + * returns 0 means EOF, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_write_eth_eeprom_data(unsigned int eth_index, char *buf, loff_t offset, + size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->write_eth_eeprom_data); + + ret = g_drv->write_eth_eeprom_data(eth_index, buf, offset, count); + return ret; +} + +static ssize_t wb_get_eth_optoe_type(unsigned int sff_index, int *optoe_type, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_eth_optoe_type); + + ret = g_drv->get_eth_optoe_type(sff_index, optoe_type, buf, count); + return ret; +} + +static ssize_t wb_set_eth_optoe_type(unsigned int sff_index, int optoe_type) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->set_eth_optoe_type); + + ret = g_drv->set_eth_optoe_type(sff_index, optoe_type); + return ret; +} + +/************************************end of transceiver***************************************/ + +static struct s3ip_sysfs_transceiver_drivers_s drivers = { + /* + * set ODM transceiver drivers to /sys/s3ip/transceiver, + * if not support the function, set corresponding hook to NULL. + */ + .get_eth_number = wb_get_eth_number, + .get_transceiver_power_on_status = wb_get_transceiver_power_on_status, + .set_transceiver_power_on_status = wb_set_transceiver_power_on_status, + .get_transceiver_present_status = wb_get_transceiver_present_status, + .get_eth_power_on_status = wb_get_eth_power_on_status, + .set_eth_power_on_status = wb_set_eth_power_on_status, + .get_eth_tx_fault_status = wb_get_eth_tx_fault_status, + .get_eth_tx_disable_status = wb_get_eth_tx_disable_status, + .set_eth_tx_disable_status = wb_set_eth_tx_disable_status, + .get_eth_present_status = wb_get_eth_present_status, + .get_eth_rx_los_status = wb_get_eth_rx_los_status, + .get_eth_reset_status = wb_get_eth_reset_status, + .set_eth_reset_status = wb_set_eth_reset_status, + .get_eth_low_power_mode_status = wb_get_eth_low_power_mode_status, + .get_eth_interrupt_status = wb_get_eth_interrupt_status, + .get_eth_eeprom_size = wb_get_eth_eeprom_size, + .read_eth_eeprom_data = wb_read_eth_eeprom_data, + .write_eth_eeprom_data = wb_write_eth_eeprom_data, + .get_eth_optoe_type = wb_get_eth_optoe_type, + .set_eth_optoe_type = wb_set_eth_optoe_type, +}; + +static int __init sff_dev_drv_init(void) +{ + int ret; + + SFF_INFO("sff_init...\n"); + g_drv = s3ip_switch_driver_get(); + check_p(g_drv); + + ret = s3ip_sysfs_sff_drivers_register(&drivers); + if (ret < 0) { + SFF_ERR("transceiver drivers register err, ret %d.\n", ret); + return ret; + } + SFF_INFO("sff_init success.\n"); + return 0; +} + +static void __exit sff_dev_drv_exit(void) +{ + s3ip_sysfs_sff_drivers_unregister(); + SFF_INFO("sff_exit success.\n"); + return; +} + +module_init(sff_dev_drv_init); +module_exit(sff_dev_drv_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4, all=0xf).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("transceiver device driver"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/vol_sensor_device_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/vol_sensor_device_driver.c new file mode 100644 index 000000000000..a2fc96551235 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/vol_sensor_device_driver.c @@ -0,0 +1,267 @@ +/* + * An vol_sensor_device_driver driver for voltage devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#include + +#include "device_driver_common.h" +#include "vol_sensor_sysfs.h" +#include "dfd_sysfs_common.h" + +#define VOL_SENSOR_INFO(fmt, args...) LOG_INFO("vol_sensor: ", fmt, ##args) +#define VOL_SENSOR_ERR(fmt, args...) LOG_ERR("vol_sensor: ", fmt, ##args) +#define VOL_SENSOR_DBG(fmt, args...) LOG_DBG("vol_sensor: ", fmt, ##args) + +static int g_loglevel = 0; +static struct switch_drivers_s *g_drv = NULL; + +/*************************************main board voltage***************************************/ +static int wb_get_main_board_vol_number(void) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_vol_number); + + ret = g_drv->get_main_board_vol_number(); + return ret; +} + +/* + * wb_get_main_board_vol_alias - Used to identify the location of the voltage sensor, + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_vol_alias(unsigned int vol_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_vol_alias); + + ret = g_drv->get_main_board_vol_alias(vol_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_vol_type - Used to get the model of voltage sensor, + * such as udc90160, tps53622 and so on + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_vol_type(unsigned int vol_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_vol_type); + + ret = g_drv->get_main_board_vol_type(vol_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_vol_max - Used to get the maximum threshold of voltage sensor + * filled the value to buf, the value is integer with mV + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_vol_max(unsigned int vol_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_vol_max); + + ret = g_drv->get_main_board_vol_max(vol_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_vol_min - Used to get the minimum threshold of voltage sensor + * filled the value to buf, the value is integer with mV + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_vol_min(unsigned int vol_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_vol_min); + + ret = g_drv->get_main_board_vol_min(vol_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_vol_range - Used to get the output error value of voltage sensor + * filled the value to buf + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_vol_range(unsigned int vol_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_vol_range); + + ret = g_drv->get_main_board_vol_range(vol_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_vol_nominal_value - Used to get the nominal value of voltage sensor + * filled the value to buf + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_vol_nominal_value(unsigned int vol_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_vol_nominal_value); + + ret = g_drv->get_main_board_vol_nominal_value(vol_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_vol_value - Used to get the input value of voltage sensor + * filled the value to buf, the value is integer with mV + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_vol_value(unsigned int vol_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_vol_value); + + ret = g_drv->get_main_board_vol_value(vol_index, buf, count); + return ret; +} + +/* + * wb_get_main_board_vol_monitor_flag - Used to get the monitor flag of voltage sensor + * filled the value to buf, the value is integer with mV + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_main_board_vol_monitor_flag(unsigned int vol_index, char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_main_board_vol_monitor_flag); + + ret = g_drv->get_main_board_vol_monitor_flag(vol_index, buf, count); + return ret; +} +/*********************************end of main board voltage************************************/ + +static struct s3ip_sysfs_vol_sensor_drivers_s drivers = { + /* + * set ODM voltage sensor drivers to /sys/s3ip/vol_sensor, + * if not support the function, set corresponding hook to NULL. + */ + .get_main_board_vol_number = wb_get_main_board_vol_number, + .get_main_board_vol_alias = wb_get_main_board_vol_alias, + .get_main_board_vol_type = wb_get_main_board_vol_type, + .get_main_board_vol_max = wb_get_main_board_vol_max, + .get_main_board_vol_min = wb_get_main_board_vol_min, + .get_main_board_vol_range = wb_get_main_board_vol_range, + .get_main_board_vol_nominal_value = wb_get_main_board_vol_nominal_value, + .get_main_board_vol_value = wb_get_main_board_vol_value, + .get_main_board_vol_monitor_flag = wb_get_main_board_vol_monitor_flag, +}; + +static int __init vol_sensor_dev_drv_init(void) +{ + int ret; + + VOL_SENSOR_INFO("vol_sensor_init...\n"); + g_drv = s3ip_switch_driver_get(); + check_p(g_drv); + + ret = s3ip_sysfs_vol_sensor_drivers_register(&drivers); + if (ret < 0) { + VOL_SENSOR_ERR("vol sensor drivers register err, ret %d.\n", ret); + return ret; + } + VOL_SENSOR_INFO("vol_sensor_init success.\n"); + return 0; +} + +static void __exit vol_sensor_dev_drv_exit(void) +{ + s3ip_sysfs_vol_sensor_drivers_unregister(); + VOL_SENSOR_INFO("vol_sensor_exit success.\n"); + return; +} + +module_init(vol_sensor_dev_drv_init); +module_exit(vol_sensor_dev_drv_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4, all=0xf).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("voltage sensors device driver"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/watchdog_device_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/watchdog_device_driver.c new file mode 100644 index 000000000000..b2075afe1081 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/device_driver/watchdog_device_driver.c @@ -0,0 +1,214 @@ +/* + * An watchdog_device_driver driver for watchdog devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#include "device_driver_common.h" +#include "watchdog_sysfs.h" +#include "dfd_sysfs_common.h" + +#define WDT_INFO(fmt, args...) LOG_INFO("watchdog: ", fmt, ##args) +#define WDT_ERR(fmt, args...) LOG_ERR("watchdog: ", fmt, ##args) +#define WDT_DBG(fmt, args...) LOG_DBG("watchdog: ", fmt, ##args) + +static int g_loglevel = 0; +static struct switch_drivers_s *g_drv = NULL; + +/****************************************watchdog*********************************************/ +/* + * wb_get_watchdog_identify - Used to get watchdog identify, such as iTCO_wdt + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_watchdog_identify(char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_watchdog_identify); + + ret = g_drv->get_watchdog_identify(buf, count); + return ret; +} + +/* + * wb_get_watchdog_timeleft - Used to get watchdog timeleft, + * filled the value to buf + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_watchdog_timeleft(char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_watchdog_timeleft); + + ret = g_drv->get_watchdog_timeleft(buf, count); + return ret; +} + +/* + * wb_get_watchdog_timeout - Used to get watchdog timeout, + * filled the value to buf + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_watchdog_timeout(char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_watchdog_timeout); + + ret = g_drv->get_watchdog_timeout(buf, count); + return ret; +} + +/* + * wb_set_watchdog_timeout - Used to set watchdog timeout, + * @value: timeout value + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int wb_set_watchdog_timeout(int value) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->set_watchdog_timeout); + + ret = g_drv->set_watchdog_timeout(value); + return ret; +} + +/* + * wb_get_watchdog_enable_status - Used to get watchdog enable status, + * filled the value to buf, 0: disable, 1: enable + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t wb_get_watchdog_enable_status(char *buf, size_t count) +{ + ssize_t ret; + + check_p(g_drv); + check_p(g_drv->get_watchdog_enable_status); + + ret = g_drv->get_watchdog_enable_status(buf, count); + return ret; +} + +/* + * wb_set_watchdog_enable_status - Used to set watchdog enable status, + * @value: enable status value, 0: disable, 1: enable + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int wb_set_watchdog_enable_status(int value) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->set_watchdog_enable_status); + + ret = g_drv->set_watchdog_enable_status(value); + return ret; +} + +/* + * wb_set_watchdog_reset - Used to feed watchdog, + * @value: any value to feed watchdog + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int wb_set_watchdog_reset(int value) +{ + int ret; + + check_p(g_drv); + check_p(g_drv->set_watchdog_reset); + + ret = g_drv->set_watchdog_reset(value); + return ret; +} + +/*************************************end of watchdog*****************************************/ + +static struct s3ip_sysfs_watchdog_drivers_s drivers = { + /* + * set ODM watchdog sensor drivers to /sys/s3ip/watchdog, + * if not support the function, set corresponding hook to NULL. + */ + .get_watchdog_identify = wb_get_watchdog_identify, + .get_watchdog_timeleft = wb_get_watchdog_timeleft, + .get_watchdog_timeout = wb_get_watchdog_timeout, + .set_watchdog_timeout = wb_set_watchdog_timeout, + .get_watchdog_enable_status = wb_get_watchdog_enable_status, + .set_watchdog_enable_status = wb_set_watchdog_enable_status, + .set_watchdog_reset = wb_set_watchdog_reset, +}; + +static int __init watchdog_dev_drv_init(void) +{ + int ret; + + WDT_INFO("watchdog_init...\n"); + g_drv = s3ip_switch_driver_get(); + check_p(g_drv); + + ret = s3ip_sysfs_watchdog_drivers_register(&drivers); + if (ret < 0) { + WDT_ERR("watchdog drivers register err, ret %d.\n", ret); + return ret; + } + WDT_INFO("watchdog create success.\n"); + return 0; +} + +static void __exit watchdog_dev_drv_exit(void) +{ + s3ip_sysfs_watchdog_drivers_unregister(); + WDT_INFO("watchdog_exit success.\n"); + return; +} + +module_init(watchdog_dev_drv_init); +module_exit(watchdog_dev_drv_exit); +module_param(g_loglevel, int, 0644); +MODULE_PARM_DESC(g_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4, all=0xf).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("watchdog device driver"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/Makefile b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/Makefile new file mode 100644 index 000000000000..98b0d0db75c4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/Makefile @@ -0,0 +1,35 @@ +PWD = $(shell pwd) + +EXTRA_CFLAGS:= -I$(M)/include +EXTRA_CFLAGS+= -Wall + +SUBDIR_CFG = cfg +wb_switch_driver-objs := switch_driver.o wb_module.o \ +wb_fan_driver.o \ +wb_eeprom_driver.o \ +wb_cpld_driver.o \ +wb_fpga_driver.o \ +wb_led_driver.o \ +wb_slot_driver.o \ +wb_sensors_driver.o \ +wb_psu_driver.o \ +wb_sff_driver.o \ +wb_watchdog_driver.o \ +wb_system_driver.o \ +$(SUBDIR_CFG)/dfd_cfg.o \ +$(SUBDIR_CFG)/dfd_cfg_adapter.o \ +$(SUBDIR_CFG)/dfd_cfg_file.o \ +$(SUBDIR_CFG)/dfd_cfg_info.o \ +$(SUBDIR_CFG)/dfd_cfg_listnode.o \ +$(SUBDIR_CFG)/dfd_frueeprom.o \ +$(SUBDIR_CFG)/dfd_tlveeprom.o \ + +obj-m := wb_switch_driver.o +all: + $(MAKE) -C $(KERNEL_SRC)/build M=$(PWD) modules + @if [ ! -d $(module_out_put_dir) ]; then mkdir -p $(module_out_put_dir) ;fi + cp -p $(PWD)/*.ko $(module_out_put_dir) +clean: + rm -f $(PWD)/*.o $(PWD)/$(SUBDIR_CFG)/*.o $(PWD)/*.ko $(PWD)/*.mod.c $(PWD)/.*.cmd $(PWD)/$(SUBDIR_CFG)/.*.cmd + rm -f $(PWD)/Module.markers $(PWD)/Module.symvers $(PWD)/modules.order + rm -rf $(PWD)/.tmp_versions \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg.c new file mode 100644 index 000000000000..0637d8566aa2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg.c @@ -0,0 +1,1169 @@ +/* + * An dfd_cfg driver for cfg devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include + +#include "wb_module.h" +#include "dfd_cfg_file.h" +#include "dfd_cfg_listnode.h" +#include "dfd_cfg_info.h" +#include "dfd_cfg_adapter.h" +#include "dfd_cfg.h" + +/* Configuration item name */ +#ifdef DFD_CFG_ITEM +#undef DFD_CFG_ITEM +#endif +#define DFD_CFG_ITEM(_id, _name, _index_min, _index_max) _name, +static char *dfd_cfg_item_name[] = { + DFD_CFG_ITEM_ALL +}; + +/* The index range of the item is specified */ +#ifdef DFD_CFG_ITEM +#undef DFD_CFG_ITEM +#endif +#define DFD_CFG_ITEM(_id, _name, _index_min, _index_max) {_index_min, _index_max}, +static index_range_t dfd_cfg_item_index_range[] = { + DFD_CFG_ITEM_ALL +}; + +/* led status register value conversion level list header */ +LIST_HEAD(dfd_lib_cfg_led_status_decode_conv_lst); + +/* Fan name Convert Air duct type chain head */ +LIST_HEAD(dfd_lib_cfg_fan_name_conv_dir_lst); + +/* Fan name Convert Air duct type chain head */ +LIST_HEAD(dfd_lib_cfg_power_name_conv_lst); + +/* Configure the root node of the necklace watch */ +static lnode_root_t dfd_ko_cfg_list_root; + +/* input key,and then get configuration string */ +char *key_to_name(uint64_t key) +{ + return dfd_cfg_item_name[key]; +} + +/* Strip out Spaces and carriage returns */ +void dfd_ko_cfg_del_space_lf_cr(char *str) +{ + int i, j; + int len; + + if (str == NULL) { + DBG_DEBUG(DBG_ERROR, "param error, str is NULL\n"); + return; + } + /* Remove all Spaces from the configuration line */ + len = strlen(str); + for (i = 0; i < len; i++) { + if (str[i] == '\r' || str[i] == '\n' || str[i] == ' ') { + for (j = i; j < len - 1; j++) { + str[j] = str[j + 1]; + } + str[j] = '\0'; + len--; + i--; + } + } +} + +void dfd_ko_cfg_del_lf_cr(char *str) +{ + int i, len; + + len = strlen(str); + for (i = 0; i < len; i++) { + if (str[i] == '\r' || str[i] == '\n') { + str[i] = '\0'; + } + } +} + +/** + * Free linked list + * @root: Root node pointer + * + * @return : void + */ +void val_convert_node_lst_free(struct list_head *root) +{ + val_convert_node_t *node, *node_next; + + if (root == NULL) { + return; + } + + /* Iterate to delete the linked list */ + list_for_each_entry_safe(node, node_next, root, lst) { + list_del(&node->lst); + kfree(node); + node = NULL; + } + + return; + +} + +/* Register value conversion node added */ +static void dfd_ko_cfg_regval_conv_lst_add(struct list_head *root, int val, char *str, + int index1, int index2) +{ + val_convert_node_t *val_convert; + + val_convert = (val_convert_node_t *)kmalloc(sizeof(val_convert_node_t), GFP_KERNEL); + if (val_convert == NULL) { + DBG_DEBUG(DBG_ERROR, "kmalloc val_convert_node_t fail\n"); + return; + } + mem_clear(val_convert, sizeof(val_convert_node_t)); + + val_convert->int_val = val; + val_convert->index1 = index1; + val_convert->index2 = index2; + if (str != NULL) { + strlcpy(val_convert->str_val, str, sizeof(val_convert->str_val)); + } + + /* After initialization, the list does not change and does not need to be locked */ + list_add_tail(&(val_convert->lst), root); +} + +/* Get an index value from an integer value */ +static int dfd_ko_cfg_get_index2_by_intval(struct list_head *root, int val, int index1, + int *index2) +{ + val_convert_node_t *val_convert; + + /* The list does not change after initialization and does not need to be locked */ + list_for_each_entry(val_convert, root, lst) { + if ((val_convert->int_val == val) && (index1 == val_convert->index1)) { + *index2 = val_convert->index2; + return 0; + } + } + + return -1; +} + +/* Gets an index value from a string value */ +static int dfd_ko_cfg_get_index_by_strval(struct list_head *root, char *str, int *index1, int *index2) +{ + val_convert_node_t *val_convert; + + /* The list does not change after initialization and does not need to be locked */ + list_for_each_entry(val_convert, root, lst) { + if (strncmp(val_convert->str_val, str, strlen(val_convert->str_val)) == 0) { + *index1 = val_convert->index1; + *index2 = val_convert->index2; + return 0; + } + } + + return -1; +} + +/* Create a message lookup table */ +static void dfd_ko_cfg_convert_list_build(dfd_cfg_item_id_t cfg_item_id, int val, char *str, + int index1, int index2) +{ + if (cfg_item_id == DFD_CFG_ITEM_LED_STATUS_DECODE) { + dfd_ko_cfg_regval_conv_lst_add(&dfd_lib_cfg_led_status_decode_conv_lst, val, str, index1, index2); + } else if (cfg_item_id == DFD_CFG_ITEM_FAN_NAME) { + dfd_ko_cfg_regval_conv_lst_add(&dfd_lib_cfg_fan_name_conv_dir_lst, val, str, index1, index2); + } else if (cfg_item_id == DFD_CFG_ITEM_POWER_NAME) { + dfd_ko_cfg_regval_conv_lst_add(&dfd_lib_cfg_power_name_conv_lst, val, str, index1, index2); + } + return; +} + +/** + * dfd_ko_cfg_get_led_status_decode2_by_regval - Reverse check the register value of the led status + * @regval: Defined led values + * @index1: led type + * @*value: Gets the register value of the led status + * @returns: 0 Succeeded, otherwise failed + */ +int dfd_ko_cfg_get_led_status_decode2_by_regval(int regval, int index1, int *value) +{ + int rv; + + if (value == NULL) { + DBG_DEBUG(DBG_ERROR, "input arguments error\n"); + return -DFD_RV_INVALID_VALUE; + } + + rv = dfd_ko_cfg_get_index2_by_intval(&dfd_lib_cfg_led_status_decode_conv_lst, regval, + index1, value); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "get led status decode by regval[0x%x] index1[%d] fail\n", + regval, index1); + return -DFD_RV_INVALID_VALUE; + } + + return 0; +} + +/** + * dfd_ko_cfg_get_fan_direction_by_name - obtain the air duct type by fan name + * @fan_name: Fan name + * @fan_direction: Duct type + * + * @returns: 0 Succeeded, otherwise failed + */ +int dfd_ko_cfg_get_fan_direction_by_name(char *fan_name, int *fan_direction) +{ + int rv; + int index1, index2; + + if ((fan_name == NULL) || (fan_direction == NULL)) { + DBG_DEBUG(DBG_ERROR, "input arguments error\n"); + return -DFD_RV_INVALID_VALUE; + } + + rv = dfd_ko_cfg_get_index_by_strval(&dfd_lib_cfg_fan_name_conv_dir_lst, fan_name, &index1, &index2); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "get fan direction by name[%s] fail\n", fan_name); + return -DFD_RV_NODE_FAIL; + } + + *fan_direction = index1; + + return 0; +} + +/** + * dfd_ko_cfg_get_fan_direction_by_name - obtain the fan type by fan name + * @fan_name: Fan name + * @fan_type: Fan type + * @sub_type: Fan sub-type + * + * @returns: 0 Succeeded, otherwise failed + */ +int dfd_ko_cfg_get_fan_type_by_name(char *fan_name, int *fan_type, int *sub_type) +{ + int rv; + int index1, index2; + + if ((fan_name == NULL) || (fan_type == NULL)) { + DBG_DEBUG(DBG_ERROR, "input arguments error\n"); + return -DFD_RV_INVALID_VALUE; + } + + rv = dfd_ko_cfg_get_index_by_strval(&dfd_lib_cfg_fan_name_conv_dir_lst, fan_name, &index1, &index2); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "get fan direction by name[%s] fail\n", fan_name); + return -DFD_RV_NODE_FAIL; + } + + *fan_type = index1; + *sub_type = index2; + + return 0; +} + +/** + * dfd_ko_cfg_get_power_type_by_name - obtain the power supply type by power supply name + * @name: PSU name + * @power_type: PSU type + * + * @returns: 0 Succeeded, otherwise failed + */ +int dfd_ko_cfg_get_power_type_by_name(char *power_name, int *power_type) +{ + int rv; + int index1, index2; + + if ((power_name == NULL) || (power_type == NULL)) { + DBG_DEBUG(DBG_ERROR, "input arguments error\n"); + return -1; + } + + rv = dfd_ko_cfg_get_index_by_strval(&dfd_lib_cfg_power_name_conv_lst, power_name, &index1, &index2); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "get power type by name[%s] fail\n", power_name); + return -1; + } + + *power_type = index1; + + return 0; +} + +/* Convert a string to a value */ +static int dfd_ko_cfg_get_value_from_char(char *value_str, int32_t *value, int line_num) +{ + int value_tmp = 0; + + if (strlen(value_str) == 0) { + DBG_DEBUG(DBG_WARN, "line%d: value str is empty\n", line_num); + *value = DFD_CFG_EMPTY_VALUE; + return 0; + } + + /* Format processing data */ + if ((strlen(value_str) > 2) && (value_str[0] == '0') + && (value_str[1] == 'x' || value_str[1] == 'X')) { + value_tmp = (int32_t)simple_strtol(value_str, NULL, 16); /* hexadecimal */ + } else { + value_tmp = (int32_t)simple_strtol(value_str, NULL, 10); /* decimalism */ + } + + *value = value_tmp; + return 0; +} + +/* Get an index value,index2=NULL indicates that there is only one level index */ +static int dfd_ko_cfg_analyse_index(char *index_str, int *index1, int *index2, int line_num) +{ + int rv; + char *index1_begin_char, *index2_begin_char; + + /* first character should be'_' */ + if (index_str[0] != '_') { + DBG_DEBUG(DBG_ERROR, "line%d: no '-' between name and index1\n", line_num); + return -1; + } + + /* Gets the first-level index value */ + index1_begin_char = index_str; + rv = dfd_ko_cfg_get_value_from_char(++index1_begin_char, index1, line_num); + if (rv < 0) { + return -1; + } + + /* No secondary index exists */ + if (index2 == NULL) { + return 0; + } + + /* Gets the secondary index value */ + index2_begin_char = strchr(index1_begin_char, '_'); + if (index2_begin_char == NULL) { + DBG_DEBUG(DBG_ERROR, "line%d: no '-' between index1 and index2\n", line_num); + return -1; + } else { + rv = dfd_ko_cfg_get_value_from_char(++index2_begin_char, index2, line_num); + if (rv < 0) { + return -1; + } + } + + return 0; +} + +/* The index value of the array is checked. index2=NULL indicates that it is not checked */ +static int dfd_ko_cfg_check_array_index(index_range_t *index_range, int *index1, int *index2, + int line_num) +{ + /* Level 1 index value check */ + if ((*index1 < 0) || (*index1 > index_range->index1_max)) { + DBG_DEBUG(DBG_ERROR, "line%d: index1[%d] invalid, max=%d\n", line_num, *index1, + index_range->index1_max); + return -1; + } + + /* The secondary index does not exist */ + if (index2 == NULL) { + return 0; + } + + /* Secondary index value check */ + if ((*index2 < 0) || (*index2 > index_range->index2_max)) { + DBG_DEBUG(DBG_ERROR, "line%d: index2[%d] invalid, max=%d\n", line_num, *index2, + index_range->index2_max); + return -1; + } + + return 0; +} + +/* Get index value */ +static int dfd_ko_cfg_get_index(char *index_str, index_range_t *index_range, int *index1, + int *index2, int line_num) +{ + int rv; + + /* No secondary index value exists */ + if (index_range->index2_max == INDEX_NOT_EXIST) { + index2 = NULL; + } + + /* Analytic index value */ + rv = dfd_ko_cfg_analyse_index(index_str, index1, index2, line_num); + if (rv < 0) { + return -1; + } + + /* Check the index value for valid values */ + rv = dfd_ko_cfg_check_array_index(index_range, index1, index2, line_num); + if (rv < 0) { + return -1; + } + + return 0; +} + +/* Add a configuration item */ +static int dfd_ko_cfg_add_int_item(uint64_t key, int value, int line_num) +{ + int rv; + int *int_cfg; + + int_cfg = lnode_find_node(&dfd_ko_cfg_list_root, key); + if (int_cfg == NULL) { + /* Node does not exist,kmalloc new node */ + int_cfg = (int *)kmalloc(sizeof(int), GFP_KERNEL); + if (int_cfg == NULL) { + DBG_DEBUG(DBG_ERROR, "line%d: kmalloc int fail\n", line_num); + return -1; + } + + /* Add to linked list */ + *int_cfg = value; + rv = lnode_insert_node(&dfd_ko_cfg_list_root, key, int_cfg); + if (rv == 0) { + DBG_DEBUG(DBG_VERBOSE, "line%d: add int item[%d] success, key=0x%08llx\n", + line_num, value, key); + } else { + kfree(int_cfg); + int_cfg = NULL; + DBG_DEBUG(DBG_ERROR, "line%d: add int item[%d] fail, key=0x%08llx rv=%d \n", + line_num, value, key, rv); + return -1; + } + } else { + /* If the node already exists, modify the configuration value */ + DBG_DEBUG(DBG_WARN, "line%d: replace int item[%d->%d], key=0x%08llx\n", + line_num, *int_cfg, value, key); + *int_cfg = value; + } + + return 0; +} + +/* Parse int type configuration */ +static int dfd_ko_cfg_analyse_int_item(dfd_cfg_item_id_t cfg_item_id, char *arg_name, + char *arg_value, char *cfg_pre, index_range_t *index_range, int line_num) +{ + int rv; + int index1 = 0, index2 = 0; + int value, key; + char *arg_name_tmp; + + /* Get index value */ + if (index_range->index1_max != INDEX_NOT_EXIST) { + arg_name_tmp = arg_name + strlen(cfg_pre); + rv = dfd_ko_cfg_get_index(arg_name_tmp, index_range, &index1, &index2, line_num); + if (rv < 0) { + return -1; + } + } + + /* Get configuration value */ + rv = dfd_ko_cfg_get_value_from_char(arg_value, &value, line_num); + if (rv < 0) { + return -1; + } + + /* Add a configuration item */ + key = DFD_CFG_KEY(cfg_item_id, index1, index2); + rv = dfd_ko_cfg_add_int_item(key, value, line_num); + if (rv < 0) { + return -1; + } + + /* Some data needs to be backtracked, and an int type backtracked linked list is created */ + dfd_ko_cfg_convert_list_build(cfg_item_id, value, NULL, index1, index2); + return 0; +} + +/* Add a configuration item */ +static int dfd_ko_cfg_add_str_item(uint64_t key, char *str, int line_num) +{ + int rv; + char *str_cfg; + + str_cfg = lnode_find_node(&dfd_ko_cfg_list_root, key); + if (str_cfg == NULL) { + /* kmalloc new node */ + str_cfg = (char *)kmalloc(DFD_CFG_STR_MAX_LEN, GFP_KERNEL); + if (str_cfg == NULL) { + DBG_DEBUG(DBG_ERROR, "line%d: kmalloc str[%lu] fail\n", line_num, strlen(str)); + return -1; + } + mem_clear(str_cfg, DFD_CFG_STR_MAX_LEN); + strlcpy(str_cfg, str, DFD_CFG_STR_MAX_LEN); + + /* Add to linked list */ + rv = lnode_insert_node(&dfd_ko_cfg_list_root, key, str_cfg); + if (rv == 0) { + DBG_DEBUG(DBG_VERBOSE, "line%d: add string item[%s] success, key=0x%08llx\n", + line_num, str_cfg, key); + } else { + kfree(str_cfg); + str_cfg = NULL; + DBG_DEBUG(DBG_ERROR, "line%d: add string item[%s] fail, key=0x%08llx rv=%d \n", + line_num, str_cfg, key, rv); + return -1; + } + } else { + DBG_DEBUG(DBG_WARN, "line%d: replace string item[%s->%s], key=0x%08llx\n", + line_num, str_cfg, str, key); + mem_clear(str_cfg, DFD_CFG_STR_MAX_LEN); + strlcpy(str_cfg, str, DFD_CFG_STR_MAX_LEN); + } + + return 0; +} + +/* Parse the str type configuration */ +static int dfd_ko_cfg_analyse_str_item(dfd_cfg_item_id_t cfg_item_id, char *arg_name, + char *arg_value, char *cfg_pre, index_range_t *index_range, int line_num) +{ + int rv; + int index1 = 0, index2 = 0; + int btree_key; + char *arg_name_tmp; + + /* Get index value */ + if (index_range->index1_max != INDEX_NOT_EXIST) { + arg_name_tmp = arg_name + strlen(cfg_pre); + rv = dfd_ko_cfg_get_index(arg_name_tmp, index_range, &index1, &index2, line_num); + if (rv < 0) { + return -1; + } + } + + /* Length check */ + if (strlen(arg_value) >= DFD_CFG_STR_MAX_LEN) { + DBG_DEBUG(DBG_ERROR, "line%d: string item[%s] is too long \n", line_num, arg_value); + return -1; + } + + /* Add a configuration item */ + btree_key = DFD_CFG_KEY(cfg_item_id, index1, index2); + rv = dfd_ko_cfg_add_str_item(btree_key, arg_value, line_num); + if (rv < 0) { + return -1; + } + + /* Part of the data need to reverse lookup, create a string type reverse lookup list */ + dfd_ko_cfg_convert_list_build(cfg_item_id, 0, arg_value, index1, index2); + return 0; +} + +/* Gets the dfd_i2c_dev_t member */ +static int dfd_ko_cfg_get_i2c_dev_member(char *member_str, dfd_i2c_dev_mem_t *member, int line_num) +{ + dfd_i2c_dev_mem_t mem_index; + + for (mem_index = DFD_I2C_DEV_MEM_BUS; mem_index < DFD_I2C_DEV_MEM_END; mem_index++) { + if (memcmp(member_str, g_dfd_i2c_dev_mem_str[mem_index], + strlen(g_dfd_i2c_dev_mem_str[mem_index])) == 0) { + *member = mem_index; + return 0; + } + } + + DBG_DEBUG(DBG_ERROR, "line%d: i2c dev member[%s] invalid\n", line_num, member_str); + return -1; +} + +/* Set the i2c_dev member value */ +static void dfd_ko_cfg_set_i2c_dev_mem_value(dfd_i2c_dev_t *i2c_dev, dfd_i2c_dev_mem_t member, + int value) +{ + switch (member) { + case DFD_I2C_DEV_MEM_BUS: + i2c_dev->bus = value; + break; + case DFD_I2C_DEV_MEM_ADDR: + i2c_dev->addr = value; + break; + default: + break; + } +} + +/* Add a configuration item */ +static int dfd_ko_cfg_add_i2c_dev_item(uint64_t key, dfd_i2c_dev_mem_t member, int value, int line_num) +{ + int rv; + dfd_i2c_dev_t *i2c_dev_cfg; + + i2c_dev_cfg = lnode_find_node(&dfd_ko_cfg_list_root, key); + if (i2c_dev_cfg == NULL) { + /* Node does not exist,kmalloc new node */ + i2c_dev_cfg = (dfd_i2c_dev_t *)kmalloc(sizeof(dfd_i2c_dev_t), GFP_KERNEL); + if (i2c_dev_cfg == NULL) { + DBG_DEBUG(DBG_ERROR, "line%d: kmalloc i2c_dev fail\n", line_num); + return -1; + } + mem_clear(i2c_dev_cfg, sizeof(dfd_i2c_dev_t)); + + /* Add to linked list */ + dfd_ko_cfg_set_i2c_dev_mem_value(i2c_dev_cfg, member, value); + rv = lnode_insert_node(&dfd_ko_cfg_list_root, key, i2c_dev_cfg); + if (rv == 0) { + DBG_DEBUG(DBG_VERBOSE, "line%d: add i2c_dev item[%s=%d] success, key=0x%08llx\n", + line_num, g_dfd_i2c_dev_mem_str[member], value, key); + } else { + kfree(i2c_dev_cfg); + i2c_dev_cfg = NULL; + DBG_DEBUG(DBG_ERROR, "line%d: add i2c_dev item[%s=%d] fail, key=0x%08llx rv=%d\n", + line_num, g_dfd_i2c_dev_mem_str[member], value, key, rv); + return -1; + } + } else { + /* If the node already exists, modify the configuration value */ + DBG_DEBUG(DBG_VERBOSE, "line%d: replace i2c_dev item[%s=%d], key=0x%08llx\n", line_num, + g_dfd_i2c_dev_mem_str[member], value, key); + dfd_ko_cfg_set_i2c_dev_mem_value(i2c_dev_cfg, member, value); + } + + return 0; +} + +/* Parse the dfd_i2c_dev_t type configuration */ +static int dfd_ko_cfg_analyse_i2c_dev_item(dfd_cfg_item_id_t cfg_item_id, char *arg_name, + char *arg_value, char *cfg_pre, index_range_t *index_range, int line_num) +{ + int rv; + int index1 = 0, index2 = 0; + int value, key; + char *arg_name_tmp; + dfd_i2c_dev_mem_t member; + + /* Parsing structure member */ + arg_name_tmp = arg_name + strlen(cfg_pre); + rv = dfd_ko_cfg_get_i2c_dev_member(arg_name_tmp, &member, line_num); + if (rv < 0) { + return -1; + } + + /* Get index value */ + if (index_range->index1_max != INDEX_NOT_EXIST) { + arg_name_tmp += strlen(g_dfd_i2c_dev_mem_str[member]); + rv = dfd_ko_cfg_get_index(arg_name_tmp, index_range, &index1, &index2, line_num); + if (rv < 0) { + return -1; + } + } + + /* Value acquisition */ + rv = dfd_ko_cfg_get_value_from_char(arg_value, &value, line_num); + if (rv < 0) { + return -1; + } + + /* Add a configuration item */ + key = DFD_CFG_KEY(cfg_item_id, index1, index2); + rv = dfd_ko_cfg_add_i2c_dev_item(key, member, value, line_num); + if (rv < 0) { + return -1; + } + + return 0; +} + +/* String to enumeration value */ +static int dfd_ko_cfg_get_enum_value_by_str(char *enum_val_str[], int enum_val_end, char *buf) +{ + int i; + int enum_val; + + enum_val = DFD_CFG_INVALID_VALUE; + for (i = 0; i < enum_val_end; i++) { + if (memcmp(buf, enum_val_str[i], strlen(enum_val_str[i])) == 0) { + enum_val = i; + break; + } + } + + return enum_val; +} + +/* Obtain the info_ctrl_t member */ +static int dfd_ko_cfg_get_info_ctrl_member(char *member_str, info_ctrl_mem_t *member, int line_num) +{ + info_ctrl_mem_t mem_index; + + for (mem_index = INFO_CTRL_MEM_MODE; mem_index < INFO_CTRL_MEM_END; mem_index++) { + if (memcmp(member_str, g_info_ctrl_mem_str[mem_index], + strlen(g_info_ctrl_mem_str[mem_index])) == 0) { + *member = mem_index; + return 0; + } + } + + DBG_DEBUG(DBG_ERROR, "line%d: info ctrl member[%s] invalid\n", line_num, member_str); + return -1; +} + +/* Set the info_ctrl member value */ +static void dfd_ko_cfg_set_info_ctrl_mem_value(info_ctrl_t *info_ctrl, info_ctrl_mem_t member, + char *buf_val, int line_num) +{ + switch (member) { + case INFO_CTRL_MEM_MODE: + info_ctrl->mode = dfd_ko_cfg_get_enum_value_by_str(g_info_ctrl_mode_str, + INFO_CTRL_MODE_END, buf_val); + break; + case INFO_CTRL_MEM_INT_CONS: + dfd_ko_cfg_get_value_from_char(buf_val, &(info_ctrl->int_cons), line_num); + break; + case INFO_CTRL_MEM_SRC: + info_ctrl->src = dfd_ko_cfg_get_enum_value_by_str(g_info_src_str, INFO_SRC_END, buf_val); + break; + case INFO_CTRL_MEM_FRMT: + info_ctrl->frmt = dfd_ko_cfg_get_enum_value_by_str(g_info_frmt_str, INFO_FRMT_END, buf_val); + break; + case INFO_CTRL_MEM_POLA: + info_ctrl->pola = dfd_ko_cfg_get_enum_value_by_str(g_info_pola_str, INFO_POLA_END, buf_val); + break; + case INFO_CTRL_MEM_FPATH: + mem_clear(info_ctrl->fpath, sizeof(info_ctrl->fpath)); + strlcpy(info_ctrl->fpath, buf_val, sizeof(info_ctrl->fpath)); + break; + case INFO_CTRL_MEM_ADDR: + dfd_ko_cfg_get_value_from_char(buf_val, &(info_ctrl->addr), line_num); + break; + case INFO_CTRL_MEM_LEN: + dfd_ko_cfg_get_value_from_char(buf_val, &(info_ctrl->len), line_num); + break; + case INFO_CTRL_MEM_BIT_OFFSET: + dfd_ko_cfg_get_value_from_char(buf_val, &(info_ctrl->bit_offset), line_num); + break; + case INFO_CTRL_MEM_STR_CONS: + mem_clear(info_ctrl->str_cons, sizeof(info_ctrl->str_cons)); + strlcpy(info_ctrl->str_cons, buf_val, sizeof(info_ctrl->str_cons)); + break; + case INFO_CTRL_MEM_INT_EXTRA1: + dfd_ko_cfg_get_value_from_char(buf_val, &(info_ctrl->int_extra1), line_num); + break; + case INFO_CTRL_MEM_INT_EXTRA2: + dfd_ko_cfg_get_value_from_char(buf_val, &(info_ctrl->int_extra2), line_num); + break; + case INFO_CTRL_MEM_INT_EXTRA3: + dfd_ko_cfg_get_value_from_char(buf_val, &(info_ctrl->int_extra3), line_num); + break; + default: + break; + } +} + +/* ADD A CONFIGURATION ITEM */ +static int dfd_ko_cfg_add_info_ctrl_item(uint64_t key, info_ctrl_mem_t member, char *buf_val, + int line_num) +{ + int rv; + info_ctrl_t *info_ctrl_cfg; + + info_ctrl_cfg = lnode_find_node(&dfd_ko_cfg_list_root, key); + if (info_ctrl_cfg == NULL) { + /* Node does not exist,kmalloc new node */ + info_ctrl_cfg = (info_ctrl_t *)kmalloc(sizeof(info_ctrl_t), GFP_KERNEL); + if (info_ctrl_cfg == NULL) { + DBG_DEBUG(DBG_ERROR, "line%d: kmalloc info_ctrl fail\n", line_num); + return -1; + } + mem_clear(info_ctrl_cfg, sizeof(info_ctrl_t)); + + /* Add to linked list */ + dfd_ko_cfg_set_info_ctrl_mem_value(info_ctrl_cfg, member, buf_val, line_num); + rv = lnode_insert_node(&dfd_ko_cfg_list_root, key, info_ctrl_cfg); + if (rv == 0) { + DBG_DEBUG(DBG_VERBOSE, "line%d: add info_ctrl item[%s=%s] success, key=0x%08llx\n", + line_num, g_info_ctrl_mem_str[member], buf_val, key); + } else { + kfree(info_ctrl_cfg); + info_ctrl_cfg = NULL; + DBG_DEBUG(DBG_ERROR, "line%d: add info_ctrl item[%s=%s] fail, key=0x%08llx rv=%d\n", + line_num, g_info_ctrl_mem_str[member], buf_val, key, rv); + return -1; + } + } else { + /* If the node already exists, modify the configuration value */ + DBG_DEBUG(DBG_VERBOSE, "line%d: replace info_ctrl item[%s=%s], key=0x%08llx\n", + line_num, g_info_ctrl_mem_str[member], buf_val, key); + dfd_ko_cfg_set_info_ctrl_mem_value(info_ctrl_cfg, member, buf_val, line_num); + } + + return 0; +} + +/* Parse the configuration of info_ctrl_t */ +static int dfd_ko_cfg_analyse_info_ctrl_item(dfd_cfg_item_id_t cfg_item_id, char *arg_name, + char *arg_value, char *cfg_pre, index_range_t *index_range, int line_num) +{ + int rv; + int index1 = 0, index2 = 0; + uint64_t key; + char *arg_name_tmp; + info_ctrl_mem_t member; + + /* Parsing structure member */ + arg_name_tmp = arg_name + strlen(cfg_pre); + rv = dfd_ko_cfg_get_info_ctrl_member(arg_name_tmp, &member, line_num); + if (rv < 0) { + return -1; + } + + /* Get index value */ + if (index_range->index1_max != INDEX_NOT_EXIST) { + arg_name_tmp += strlen(g_info_ctrl_mem_str[member]); + rv = dfd_ko_cfg_get_index(arg_name_tmp, index_range, &index1, &index2, line_num); + if (rv < 0) { + return -1; + } + } + + /* ADD A CONFIGURATION ITEM */ + key = DFD_CFG_KEY(cfg_item_id, index1, index2); + rv = dfd_ko_cfg_add_info_ctrl_item(key, member, arg_value, line_num); + if (rv < 0) { + return -1; + } + + return 0; +} + +/* Parsing configuration */ +static int dfd_ko_cfg_analyse_config(char *arg_name, char*arg_value, int line_num) +{ + int i, rv = 0; + int cfg_item_num; + + cfg_item_num = sizeof(dfd_cfg_item_name) / sizeof(dfd_cfg_item_name[0]); + for (i = 0; i < cfg_item_num; i++) { + if (memcmp(arg_name, dfd_cfg_item_name[i], strlen(dfd_cfg_item_name[i])) == 0){ + if (DFD_CFG_ITEM_IS_INT(i)) { + rv = dfd_ko_cfg_analyse_int_item(i, arg_name, arg_value, dfd_cfg_item_name[i], + &(dfd_cfg_item_index_range[i]), line_num); + } else if (DFD_CFG_ITEM_IS_STRING(i)) { + rv = dfd_ko_cfg_analyse_str_item(i, arg_name, arg_value, dfd_cfg_item_name[i], + &(dfd_cfg_item_index_range[i]), line_num); + } else if (DFD_CFG_ITEM_IS_I2C_DEV(i)) { + rv = dfd_ko_cfg_analyse_i2c_dev_item(i, arg_name, arg_value, dfd_cfg_item_name[i], + &(dfd_cfg_item_index_range[i]), line_num); + } else if (DFD_CFG_ITEM_IS_INFO_CTRL(i)) { + rv = dfd_ko_cfg_analyse_info_ctrl_item(i, arg_name, arg_value, dfd_cfg_item_name[i], + &(dfd_cfg_item_index_range[i]), line_num); + } else { + rv = -1; + } + break; + } + } + + return rv; +} + +/* Cut the configuration row with '=' */ +static int dfd_ko_cfg_cut_config_line(char *config_line, char *arg_name, char *arg_value) +{ + int i, j = 0, k = 0; + int len, name_value_flag = 0; + + len = strlen(config_line); + for (i = 0; i < len; i++) { + if (config_line[i] == '=') { + name_value_flag = 1; + continue; + } + + /* Data before and after cutting equal sign */ + if (name_value_flag == 0) { + arg_name[j++] = config_line[i]; + } else { + arg_value[k++] = config_line[i]; + } + } + + /* Failed to return if the equal sign does not exist */ + if (name_value_flag == 0) { + return -1; + } else { + return 0; + } +} + +/* Parse configuration row */ +static int dfd_ko_cfg_analyse_config_line(char *config_line, int line_num) +{ + int rv; + char arg_name[DFD_CFG_NAME_MAX_LEN] = {0}; + char arg_value[DFD_CFG_VALUE_MAX_LEN] = {0}; + + /* Remove all Spaces from the configuration line */ + dfd_ko_cfg_del_space_lf_cr(config_line); + + /* Blank line */ + if (strlen(config_line) == 0) { + DBG_DEBUG(DBG_VERBOSE, "line%d: space line\n", line_num); + return 0; + } + + /* Comment line */ + if (config_line[0] == '#') { + DBG_DEBUG(DBG_VERBOSE, "line%d: comment line[%s]\n", line_num, config_line); + return 0; + } + + /* Look for the '=' character after the line argument and record its position */ + rv = dfd_ko_cfg_cut_config_line(config_line, arg_name, arg_value); + if (rv < 0) { + DBG_DEBUG(DBG_VERBOSE, "line%d: [%s]no '=' between name and value\n", + line_num, config_line); + return -1; + } + + DBG_DEBUG(DBG_VERBOSE, "line%d: config_line[%s] name[%s] value[%s]\n", + line_num, config_line, arg_name, arg_value); + return dfd_ko_cfg_analyse_config(arg_name, arg_value, line_num); +} + +/* Parse configuration file */ +static int dfd_ko_cfg_analyse_config_file(char *fpath) +{ + int rv; + int line_num = 1; + kfile_ctrl_t kfile_ctrl; + char config_line[DFD_CFG_CMDLINE_MAX_LEN] = {0}; + + rv = kfile_open(fpath, &kfile_ctrl); + if (rv != KFILE_RV_OK) { + DBG_DEBUG(DBG_ERROR, "open config file[%s] fail, rv=%d\n", fpath, rv); + return -1; + } + + /* Parse the configuration rows line by line */ + while (kfile_gets(config_line, sizeof(config_line), &kfile_ctrl) > 0) { + rv = dfd_ko_cfg_analyse_config_line(config_line, line_num++); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "!!!!file[%s] config line[%d %s] analyse fail\n", + fpath, line_num - 1, config_line); + break; + } + + (void)mem_clear(config_line, sizeof(config_line)); + + } + kfile_close(&kfile_ctrl); + + return rv; +} + +/** + * dfd_ko_cfg_get_item - Get configuration item + * @key: node key + * + * @returns: NULL configuration item does not exist, other configuration items are successful + */ +void *dfd_ko_cfg_get_item(uint64_t key) +{ + return lnode_find_node(&dfd_ko_cfg_list_root, key); +} + +/* Print configuration item */ +static void dfd_ko_cfg_print_item(uint64_t key, const void *cfg) +{ + int item_id; + dfd_i2c_dev_t *i2c_dev; + info_ctrl_t *info_ctrl; + + if (cfg == NULL) { + DBG_DEBUG(DBG_ERROR, "input arguments error\n"); + return; + } + printk(KERN_INFO "**************************\n"); + printk(KERN_INFO "key=0x%08llx\n", key); + + item_id = DFD_CFG_ITEM_ID(key); + if (DFD_CFG_ITEM_IS_INT(item_id)) { + printk(KERN_INFO "int=%d\n", *((int *)cfg)); + } else if (DFD_CFG_ITEM_IS_I2C_DEV(item_id)) { + i2c_dev = (dfd_i2c_dev_t *)cfg; + printk(KERN_INFO ".bus=0x%02x\n", i2c_dev->bus); + printk(KERN_INFO ".addr=0x%02x\n", i2c_dev->addr); + } else if (DFD_CFG_ITEM_IS_INFO_CTRL(item_id)) { + info_ctrl = (info_ctrl_t *)cfg; + printk(KERN_INFO ".mode=%s\n", g_info_ctrl_mode_str[info_ctrl->mode]); + printk(KERN_INFO ".int_cons=%d\n", info_ctrl->int_cons); + printk(KERN_INFO ".src=%s\n", g_info_src_str[info_ctrl->src]); + printk(KERN_INFO ".frmt=%s\n", g_info_frmt_str[info_ctrl->frmt]); + printk(KERN_INFO ".pola=%s\n", g_info_pola_str[info_ctrl->pola]); + printk(KERN_INFO ".fpath=%s\n", info_ctrl->fpath); + printk(KERN_INFO ".addr=0x%02x\n", info_ctrl->addr); + printk(KERN_INFO ".len=%d\n", info_ctrl->len); + printk(KERN_INFO ".bit_offset=%d\n", info_ctrl->bit_offset); + } else { + printk(KERN_INFO "item[%d] error!\n", item_id); + } +} + +/** + * dfd_ko_cfg_show_item - Display configuration items + * @key: node key + */ +void dfd_ko_cfg_show_item(uint64_t key) +{ + void *cfg; + + cfg = lnode_find_node(&dfd_ko_cfg_list_root, key); + if (cfg == 0) { + printk(KERN_INFO "item[0x%08llx] not exist\n", key); + return; + } + + dfd_ko_cfg_print_item(key, cfg); +} + +/* x86 devices get the card type method */ +static int dfd_get_my_dev_type_by_file(void) +{ + struct file *fp; + loff_t pos; + int card_type; + char buf[DFD_PID_BUF_LEN]; + int ret; + + fp= filp_open(DFD_PUB_CARDTYPE_FILE, O_RDONLY, 0); + if (IS_ERR(fp)) { + DBG_DEBUG(DBG_VERBOSE, "open file fail!\n"); + return -1; + } + + mem_clear(buf, DFD_PID_BUF_LEN); + pos = 0; + ret = kernel_read(fp, buf, DFD_PRODUCT_ID_LENGTH + 1, &pos); + if (ret < 0) { + DBG_DEBUG(DBG_VERBOSE, "kernel_read failed, path=%s, addr=0, size=%d, ret=%d\n", + DFD_PUB_CARDTYPE_FILE, DFD_PRODUCT_ID_LENGTH + 1, ret); + filp_close(fp, NULL); + return -1; + } + + card_type = simple_strtoul(buf, NULL, 0); + DBG_DEBUG(DBG_VERBOSE, "card_type 0x%x.\n", card_type); + + filp_close(fp, NULL); + return card_type; +} + +/** + * drv_get_my_dev_type - Get device type + * + * return: Return the corresponding value + * + */ +static int drv_get_my_dev_type(void) +{ + static int type = -1; + + if (type > 0) { + return type; + } + type = dfd_get_my_dev_type_by_file(); + DBG_DEBUG(DBG_VERBOSE, "ko board type %d\n", type); + return type; +} + +static int dfd_ko_cfg_init(void) +{ + int rv; + int card_type; + char file_name[32] = {0}; + char fpath[128] = {0}; + kfile_ctrl_t kfile_ctrl; + + /* Initializes the list root node */ + rv = lnode_init_root(&dfd_ko_cfg_list_root); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "init list root fail, rv=%d\n", rv); + return -1; + } + + /* Gets the card type */ + card_type = drv_get_my_dev_type(); + if (card_type < 0) { + DBG_DEBUG(DBG_ERROR, "get my dev type fail, rv=%d\n", card_type); + return -1; + } + + /* Read the required profile name for the corresponding board type */ + snprintf(fpath, sizeof(fpath), "%s0x%x", DFD_KO_FILE_NAME_DIR, card_type); + rv = kfile_open(fpath, &kfile_ctrl); + if (rv != KFILE_RV_OK) { + DBG_DEBUG(DBG_ERROR, "open config file[%s] fail, rv=%d\n", fpath, rv); + return -1; + } + + /* Multiple profiles are supported */ + while (kfile_gets(file_name, sizeof(file_name), &kfile_ctrl) > 0) { + /* Read configuration file */ + dfd_ko_cfg_del_space_lf_cr(file_name); + snprintf(fpath, sizeof(fpath), "%s%s.cfg", DFD_KO_CFG_FILE_DIR, file_name); + DBG_DEBUG(DBG_VERBOSE, ">>>>start parsing config file[%s]\n", fpath); + + /* Description Failed to parse the configuration file */ + rv = dfd_ko_cfg_analyse_config_file(fpath); + if (rv < 0) { + break; + } + } + kfile_close(&kfile_ctrl); + + /* todo Configure data validity check */ + return 0; +} + +/** + * dfd_dev_cfg_init - Module initialization + * + * @returns: <0 Fail, or succeed + */ +int32_t dfd_dev_cfg_init(void) +{ + return dfd_ko_cfg_init(); +} + +/** + * dfd_dev_cfg_init - Module exit + * + * @returns: void + */ + +void dfd_dev_cfg_exit(void) +{ + lnode_free_list(&dfd_ko_cfg_list_root); + val_convert_node_lst_free(&dfd_lib_cfg_led_status_decode_conv_lst); + val_convert_node_lst_free(&dfd_lib_cfg_fan_name_conv_dir_lst); + val_convert_node_lst_free(&dfd_lib_cfg_power_name_conv_lst); + return; +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg_adapter.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg_adapter.c new file mode 100644 index 000000000000..c4c273059b11 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg_adapter.c @@ -0,0 +1,654 @@ +/* + * An dfd_cfg_adapter driver for cfg of adapter devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "wb_module.h" +#include "dfd_cfg_file.h" +#include "dfd_cfg.h" +#include "dfd_cfg_adapter.h" + +/* dfd_i2c_dev_t member string */ +char *g_dfd_i2c_dev_mem_str[DFD_I2C_DEV_MEM_END] = { + ".bus", + ".addr", +}; + +static dfd_i2c_dev_t* dfd_ko_get_cpld_i2c_dev(int sub_slot, int cpld_id) +{ + uint64_t key; + dfd_i2c_dev_t *i2c_dev; + + /* Read configuration value */ + key = DFD_CFG_KEY(DFD_CFG_ITEM_CPLD_I2C_DEV, sub_slot, cpld_id); + i2c_dev = dfd_ko_cfg_get_item(key); + if (i2c_dev == NULL) { + DBG_DEBUG(DBG_ERROR, "get cpld[%d] i2c dev config fail, key_name=%s\n", + cpld_id, key_to_name(DFD_CFG_ITEM_CPLD_I2C_DEV)); + return NULL; + } + + return i2c_dev; +} + +static int dfd_ko_i2c_block_read(int bus, int addr, int offset, uint8_t *buf, uint32_t size) +{ + struct file *fp; + struct i2c_client client; + int i; + int rv = 0; + char i2c_path[32]; + + mem_clear(i2c_path, 32); + snprintf(i2c_path, sizeof(i2c_path), "/dev/i2c-%d", bus); + + fp = filp_open(i2c_path, O_RDWR, S_IRUSR | S_IWUSR); + if (IS_ERR(fp)) { + DBG_DEBUG(DBG_ERROR, "i2c open fail.\n"); + return -1; + } + memcpy(&client, fp->private_data, sizeof(struct i2c_client)); + client.addr = addr; + + if (i2c_check_functionality(client.adapter, I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { + for (i = 0; i < size; i += 32) { + rv = i2c_smbus_read_i2c_block_data(&client, offset + i, WB_MIN(32, size-i), buf + i); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "i2c_block read failed, rv = %d\n", rv); + rv = -DFD_RV_DEV_FAIL; + goto out; + } + if (rv != 32) { + break; + } + } + rv = DFD_RV_OK; + } else { + rv = -DFD_RV_DEV_NOTSUPPORT; + } + +out: + filp_close(fp, NULL); + return rv; +} + +static int32_t dfd_ko_i2c_smbus_transfer(int read_write, int bus, int addr, int offset, uint8_t *buf, uint32_t size) +{ + int rv; + struct i2c_adapter *i2c_adap; + union i2c_smbus_data data; + + i2c_adap = i2c_get_adapter(bus); + if (i2c_adap == NULL) { + DBG_DEBUG(DBG_ERROR, "get i2c bus[%d] adapter fail\n", bus); + return -DFD_RV_DEV_FAIL; + } + + /* Operation i2c */ + if (read_write == I2C_SMBUS_WRITE) { + data.byte = *buf; + } else { + data.byte = 0; + } + rv = i2c_smbus_xfer(i2c_adap, addr, 0, read_write, offset, I2C_SMBUS_BYTE_DATA, &data); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "i2c dev[bus=%d addr=0x%x offset=0x%x size=%d rw=%d] transfer fail, rv=%d\n", + bus, addr, offset, size, read_write, rv); + rv = -DFD_RV_DEV_FAIL; + } else { + DBG_DEBUG(DBG_VERBOSE, "i2c dev[bus=%d addr=0x%x offset=0x%x size=%d rw=%d] transfer success\n", + bus, addr, offset, size, read_write); + rv = DFD_RV_OK; + } + + if (read_write == I2C_SMBUS_READ) { + if (rv == DFD_RV_OK) { + *buf = data.byte; + } else { + *buf = 0; + } + } + + i2c_put_adapter(i2c_adap); + return rv; +} + +static int32_t dfd_ko_i2c_read_bulk_data(int bus, int addr, int offset, uint8_t *buf, uint32_t size) +{ + int i, rv; + for (i = 0; i < DFD_KO_CPLD_I2C_RETRY_TIMES; i++) { + rv = dfd_ko_i2c_block_read(bus, addr, offset, buf, size); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "[%d] read[offset=0x%x] fail, rv %d\r\n", i, addr, rv); + msleep(DFD_KO_CPLD_I2C_RETRY_SLEEP); + } else { + DBG_DEBUG(DBG_VERBOSE, "[%d] read[offset=0x%x] success\r\n", + i, addr); + break; + } + } + return rv; +} + +static int32_t dfd_ko_i2c_read_data(int bus, int addr, int offset, uint8_t *buf, uint32_t size) +{ + int i, rv; + for (i = 0; i < DFD_KO_CPLD_I2C_RETRY_TIMES; i++) { + rv = dfd_ko_i2c_smbus_transfer(I2C_SMBUS_READ, bus, addr, offset, buf, size); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "[%d]cpld read[offset=0x%x] fail, rv %d\n", i, addr, rv); + msleep(DFD_KO_CPLD_I2C_RETRY_SLEEP); + } else { + DBG_DEBUG(DBG_VERBOSE, "[%d]cpld read[offset=0x%x] success, value=0x%x\n", + i, addr, *buf); + break; + } + } + return rv; +} + +static int32_t dfd_ko_i2c_write_data(int bus, int addr, int offset, uint8_t data, uint32_t size) +{ + int i, rv; + for (i = 0; i < DFD_KO_CPLD_I2C_RETRY_TIMES; i++) { + rv = dfd_ko_i2c_smbus_transfer(I2C_SMBUS_WRITE, bus, addr, offset, &data, size); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "[%d]cpld write[offset=0x%x] fail, rv=%d\n", i, addr, rv); + msleep(DFD_KO_CPLD_I2C_RETRY_SLEEP); + } else { + DBG_DEBUG(DBG_VERBOSE, "[%d]cpld write[offset=0x%x, data=%d] success\n", i, addr, data); + break; + } + } + + return rv; +} + +/** + * dfd_ko_cpld_i2c_read - cpld read operation + * @offset: Offset address + * @buf: data + * + * @returns: <0 Failure, other success + */ +static int32_t dfd_ko_cpld_i2c_read(int32_t addr, uint8_t *buf) +{ + int rv; + int sub_slot, cpld_id, cpld_addr; + dfd_i2c_dev_t *i2c_dev; + + if (buf == NULL) { + DBG_DEBUG(DBG_ERROR, "input arguments error\n"); + return -DFD_RV_INDEX_INVALID; + } + + /* Obtain the i2c device bus addr */ + sub_slot = DFD_KO_CPLD_GET_SLOT(addr); + cpld_id = DFD_KO_CPLD_GET_ID(addr); + cpld_addr = DFD_KO_CPLD_GET_INDEX(addr); + + i2c_dev = dfd_ko_get_cpld_i2c_dev(sub_slot, cpld_id); + if (i2c_dev == NULL) { + return -DFD_RV_DEV_NOTSUPPORT; + } + rv = dfd_ko_i2c_read_data(i2c_dev->bus, i2c_dev->addr, cpld_addr, buf, sizeof(uint8_t)); + + return rv; +} + +/** + * dfd_ko_cpld_i2c_write - cpld WRITE OPERATION + * @offset: Offset address + * @buf: data + * + * @returns: <0 Failure, other success + */ +static int32_t dfd_ko_cpld_i2c_write(int32_t addr, uint8_t data) +{ + int rv; + int sub_slot, cpld_id, cpld_addr; + dfd_i2c_dev_t *i2c_dev; + + /* Obtain the i2c device bus addr */ + sub_slot = DFD_KO_CPLD_GET_SLOT(addr); + cpld_id = DFD_KO_CPLD_GET_ID(addr); + cpld_addr = DFD_KO_CPLD_GET_INDEX(addr); + + i2c_dev = dfd_ko_get_cpld_i2c_dev(sub_slot, cpld_id); + if (i2c_dev == NULL) { + return -DFD_RV_DEV_NOTSUPPORT; + } + + rv = dfd_ko_i2c_write_data(i2c_dev->bus, i2c_dev->addr, cpld_addr, data, sizeof(uint8_t)); + + return rv; +} + +#ifdef CONFIG_X86 +/** + * dfd_ko_cpld_io_read - cpld io spatial read operation + * @offset: address + * @buf: data + * + * @returns: <0 Failure, other success + */ +static int32_t dfd_ko_cpld_io_read(int32_t addr, uint8_t *buf) +{ + uint64_t key; + int cpld_id, sub_slot, offset; + int *tmp; + uint16_t io_port; + + sub_slot = DFD_KO_CPLD_GET_SLOT(addr); + cpld_id = DFD_KO_CPLD_GET_ID(addr); + offset = DFD_KO_CPLD_GET_INDEX(addr); + + /* int Type configuration item */ + key = DFD_CFG_KEY(DFD_CFG_ITEM_CPLD_LPC_DEV, sub_slot, cpld_id); + tmp = dfd_ko_cfg_get_item(key); + if (tmp == NULL) { + DBG_DEBUG(DBG_ERROR,"get cpld io base config fail, key_name=%s\n", + key_to_name(DFD_CFG_ITEM_CPLD_LPC_DEV)); + return -DFD_RV_DEV_NOTSUPPORT; + } + + io_port = (u16)(*tmp) + offset; + *buf = inb(io_port); + DBG_DEBUG(DBG_VERBOSE, "read cpld io port addr 0x%x, data 0x%x\n", io_port, *buf); + + return DFD_RV_OK; + +} +#endif + +#ifdef CONFIG_X86 +/** + * dfd_ko_cpld_io_write - cpld io space WRITE OPERATION + * @addr: address + * @data: data + * + * @returns: <0 Failure, other success + */ +static int32_t dfd_ko_cpld_io_write(int32_t addr, uint8_t data) +{ + uint64_t key; + int cpld_id, sub_slot, offset; + int *tmp; + uint16_t io_port; + + sub_slot = DFD_KO_CPLD_GET_SLOT(addr); + cpld_id = DFD_KO_CPLD_GET_ID(addr); + offset = DFD_KO_CPLD_GET_INDEX(addr); + + /* int Type configuration item */ + key = DFD_CFG_KEY(DFD_CFG_ITEM_CPLD_LPC_DEV, sub_slot, cpld_id); + tmp = dfd_ko_cfg_get_item(key); + if (tmp == NULL) { + DBG_DEBUG(DBG_ERROR, "get cpld io base config fail, key_name=%s\n", + key_to_name(DFD_CFG_ITEM_CPLD_LPC_DEV)); + return -1; + } + + io_port = (u16)(*tmp) + offset; + DBG_DEBUG(DBG_VERBOSE, "write cpld io port addr 0x%x, data 0x%x\n", io_port, data); + outb(data, (u16)io_port); + + return DFD_RV_OK; +} +#endif + +static int dfd_cfg_get_cpld_mode(int sub_slot, int cpld_id, int *mode) +{ + uint64_t key; + char *name; + + if (mode == NULL) { + DBG_DEBUG(DBG_ERROR, "input arguments error\n"); + return -DFD_RV_TYPE_ERR; + } + + /* string type configuration item */ + key = DFD_CFG_KEY(DFD_CFG_ITEM_CPLD_MODE, sub_slot, cpld_id); + name = dfd_ko_cfg_get_item(key); + if (name == NULL) { + DBG_DEBUG(DBG_ERROR, "get cpld[%d] mode info ctrl fail, key_name=%s\n", + cpld_id, key_to_name(DFD_CFG_ITEM_CPLD_MODE)); + return -DFD_RV_DEV_NOTSUPPORT; + } + + DBG_DEBUG(DBG_VERBOSE, "cpld_id %d mode_name %s.\n", cpld_id, name); + if (!strncmp(name, DFD_KO_CPLD_MODE_I2C_STRING, strlen(DFD_KO_CPLD_MODE_I2C_STRING))) { + *mode = DFD_CPLD_MODE_I2C; + } else if (!strncmp(name, DFD_KO_CPLD_MODE_LPC_STRING, strlen(DFD_KO_CPLD_MODE_LPC_STRING))) { + *mode = DFD_CPLD_MODE_LPC; + } else { + /* The default mode is I2C */ + *mode = DFD_CPLD_MODE_I2C; + } + + DBG_DEBUG(DBG_VERBOSE, "cpld_id %d mode %d.\n", cpld_id, *mode); + return 0; +} + +/** + * dfd_ko_cpld_read - cpld read operation, read only one byte + * @offset: Offset address + * @buf: data + * + * @returns: <0 Failure, other success + */ +int32_t dfd_ko_cpld_read(int32_t addr, uint8_t *buf) +{ + int ret; + int sub_slot, cpld_id; + int cpld_mode; + + sub_slot = DFD_KO_CPLD_GET_SLOT(addr); + cpld_id = DFD_KO_CPLD_GET_ID(addr); + /* cpld mode, including I2C and LPC. Other modes are not supported */ + ret = dfd_cfg_get_cpld_mode(sub_slot, cpld_id, &cpld_mode); + if (ret) { + DBG_DEBUG(DBG_WARN, "drv_get_cpld_mode sub_slot %d cpldid %d faile, set default i2c mode.\n", sub_slot, cpld_id); + cpld_mode = DFD_CPLD_MODE_I2C; + } + + if (cpld_mode == DFD_CPLD_MODE_I2C) { + ret = dfd_ko_cpld_i2c_read(addr, buf); + } else if (cpld_mode == DFD_CPLD_MODE_LPC) { +#ifdef CONFIG_X86 + ret = dfd_ko_cpld_io_read(addr, buf); +#else + DBG_DEBUG(DBG_ERROR, "ERROR:only x86 arch support cpld_mode %d.\n", cpld_mode); + ret = -DFD_RV_DEV_NOTSUPPORT; +#endif + } else { + DBG_DEBUG(DBG_ERROR, "cpld_mode %d invalid.\n", cpld_mode); + ret = -DFD_RV_DEV_NOTSUPPORT; + } + + DBG_DEBUG(DBG_VERBOSE, "addr 0x%x val 0x%x ret %d\n", addr, *buf, ret); + return ret; +} + +/** + * dfd_ko_cpld_write - cpld WRITE OPERATION Write a byte + * @offset: Offset address + * @buf: data + * + * @returns: <0 Failure, other success + */ +int32_t dfd_ko_cpld_write(int32_t addr, uint8_t val) +{ + int ret; + int sub_slot, cpld_id, cpld_mode; + + sub_slot = DFD_KO_CPLD_GET_SLOT(addr); + cpld_id = DFD_KO_CPLD_GET_ID(addr); + + ret = dfd_cfg_get_cpld_mode(sub_slot, cpld_id, &cpld_mode); + if (ret) { + DBG_DEBUG(DBG_ERROR, "drv_get_cpld_mode sub_slot %d cpldid %d faile, set default local_bus mode.\n", sub_slot, cpld_id); + cpld_mode = DFD_CPLD_MODE_I2C; + } + + if (cpld_mode == DFD_CPLD_MODE_I2C) { + ret = dfd_ko_cpld_i2c_write(addr, val); + } else if (cpld_mode == DFD_CPLD_MODE_LPC) { +#ifdef CONFIG_X86 + ret = dfd_ko_cpld_io_write(addr, val); +#else + DBG_DEBUG(DBG_ERROR, "ERROR:only x86 arch support cpld_mode %d.\n", cpld_mode); + ret = -DFD_RV_DEV_NOTSUPPORT; +#endif + } else { + DBG_DEBUG(DBG_ERROR, "cpld_mode %d invalid.\n", cpld_mode); + ret = -DFD_RV_MODE_INVALID; + } + + DBG_DEBUG(DBG_VERBOSE, "addr 0x%x val 0x%x ret %d\n", addr, val, ret); + return ret; +} + +/** + * dfd_ko_i2c_read_tmp - I2C read operation + * @bus: I2C BUS Device address + * @offset:Register offset + * @buf:Read buffer + * @size:Read length + * @returns: <0 Failure, other success + */ +static int32_t dfd_ko_i2c_read_tmp(int bus, int addr, int offset, uint8_t *buf, uint32_t size) +{ + int i, rv; + + for (i = 0; i < size; i++) { + rv = dfd_ko_i2c_read_data(bus, addr, offset, &buf[i], sizeof(uint8_t)); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "dfd_ko_i2c_read_data[bus=%d addr=0x%x offset=0x%x]fail, rv=%d\n", + bus, addr, offset, rv); + return rv; + } + offset++; + } + + return size; +} + +/** + * dfd_ko_i2c_write - I2C WRITE OPERATION + * @bus: I2C BUS + * @addr: I2C Device address + * @offset:Register offset + * @buf: Write buffer + * @size:Write length + * @returns: <0 Failure, other success + */ +int32_t dfd_ko_i2c_write(int bus, int addr, int offset, uint8_t *buf, uint32_t size) +{ + int i, rv; + + for (i = 0; i < size; i++) { + rv = dfd_ko_i2c_write_data(bus, addr, offset, buf[i], sizeof(uint8_t)); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "dfd_ko_i2c_write[bus=%d addr=0x%x offset=0x%x]fail, rv=%d\n", + bus, addr, offset, rv); + return rv; + } + offset++; + } + + return size; + +} + +/** + * dfd_ko_read_file - File read operation + * @fpath: File path + * @addr: address + * @val: data + * @read_bytes: length + * + * @returns: <0 Failure, other success + */ +int32_t dfd_ko_read_file(char *fpath, int32_t addr, uint8_t *val, int32_t read_bytes) +{ + int32_t ret; + struct file *filp; + loff_t pos; + + struct kvec iov = { + .iov_base = val, + .iov_len = min_t(size_t, read_bytes, MAX_RW_COUNT), + }; + struct iov_iter iter; + + if ((fpath == NULL) || (val == NULL) || (addr < 0) || (read_bytes < 0)) { + DBG_DEBUG(DBG_ERROR, "input arguments error, addr=%d read_bytes=%d\n", addr, read_bytes); + return -DFD_RV_INDEX_INVALID; + } + + /* Open file */ + filp = filp_open(fpath, O_RDONLY, 0); + if (IS_ERR(filp)) { + DBG_DEBUG(DBG_ERROR, "open file[%s] fail\n", fpath); + return -DFD_RV_DEV_FAIL; + } + /* Location file */ + pos = addr; + iov_iter_kvec(&iter, ITER_DEST, &iov, 1, iov.iov_len); + ret = vfs_iter_read(filp, &iter, &pos, 0); + if (ret < 0) { + DBG_DEBUG(DBG_ERROR, "vfs_iter_read failed, path=%s, addr=%d, size=%d, ret=%d\n", fpath, addr, read_bytes, ret); + ret = -DFD_RV_DEV_FAIL; + } + filp_close(filp, NULL); + return ret; +} + +/** + * dfd_ko_other_i2c_dev_read - other_i2c read operation + * @addr: address + * @val: data + * @read_bytes: length + * + * @returns: <0 Failure, other success + */ +int32_t dfd_ko_other_i2c_dev_read(int32_t addr, uint8_t *value, int32_t read_len) +{ + uint64_t key; + int rv; + int e2p_main_id, e2p_index, e2p_addr; + dfd_i2c_dev_t *i2c_dev; + + if ((value == NULL) || (read_len <= 0)) { + DBG_DEBUG(DBG_ERROR, "input arguments error, read_len=%d\r\n", read_len); + return -1; + } + + e2p_main_id = DFD_KO_OTHER_I2C_GET_MAIN_ID(addr); + e2p_index = DFD_KO_OTHER_I2C_GET_INDEX(addr); + e2p_addr = DFD_KO_OTHER_I2C_GET_OFFSET(addr); + + key = DFD_CFG_KEY(DFD_CFG_ITEM_OTHER_I2C_DEV, e2p_main_id, e2p_index); + i2c_dev = dfd_ko_cfg_get_item(key); + if (i2c_dev == NULL) { + DBG_DEBUG(DBG_ERROR, "psu i2c dev config error, key_name: %s\r\n", + key_to_name(DFD_CFG_ITEM_OTHER_I2C_DEV)); + return -DFD_RV_NODE_FAIL; + } + + rv = dfd_ko_i2c_read_bulk_data(i2c_dev->bus, i2c_dev->addr, e2p_addr, value, read_len); + DBG_DEBUG(DBG_VERBOSE, "dfd_ko_other_i2c_dev_read, value[0] = 0x%x\n", value[0]); + DBG_DEBUG(DBG_VERBOSE, "dfd_ko_other_i2c_dev_read, value[1] = 0x%x\n", value[1]); + return rv; +} + +/** + * dfd_ko_i2c_read - I2C read operation + * @bus: I2C BUS + * @addr: I2C Device address + * @offset:Register offset + * @buf:Read buffer + * @size:Read length + * @sysfs_name:sysfs attribute name + * @returns: <0 Failure, other success + */ +int32_t dfd_ko_i2c_read(int bus, int addr, int offset, uint8_t *buf, uint32_t size, const char *sysfs_name) +{ + int rv; + char sysfs_path[DFD_SYSFS_PATH_MAX_LEN]; + + if (buf == NULL) { + DBG_DEBUG(DBG_ERROR, "params error, buf is NULL.\n"); + return -DFD_RV_INVALID_VALUE; + } + + if (sysfs_name == NULL) { /* Read in i2c mode */ + DBG_DEBUG(DBG_VERBOSE, "using i2c_smbus_xfer, bus:%d, addr:0x%x, offset:0x%x, read size:%d.\n", + bus, addr, offset, size); + rv = dfd_ko_i2c_read_tmp(bus, addr, offset, buf, size); + } else { /* Read by sysfs */ + mem_clear(sysfs_path, sizeof(sysfs_path)); + snprintf(sysfs_path, sizeof(sysfs_path), "/sys/bus/i2c/devices/%d-%04x/%s", + bus, addr, sysfs_name); + DBG_DEBUG(DBG_VERBOSE, "using sysfs, sysfs_path:%s, offset:0x%x, read size:%d.\n", + sysfs_path, offset, size); + rv = dfd_ko_read_file(sysfs_path, offset, buf, size); + } + + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "dfd_ko_i2c_read failed.\n"); + } else { + DBG_DEBUG(DBG_VERBOSE, "dfd_ko_i2c_read success.\n"); + } + + return rv; +} + +/** + * dfd_ko_write_file - file WRITE OPERATION + * @fpath: file path + * @addr: address + * @val: data + * @write_bytes: length + * + * @returns: <0 Failure, other success + */ +int32_t dfd_ko_write_file(char *fpath, int32_t addr, uint8_t *val, int32_t write_bytes) +{ + int32_t ret; + struct file *filp; + loff_t pos; + + struct kvec iov = { + .iov_base = val, + .iov_len = min_t(size_t, write_bytes, MAX_RW_COUNT), + }; + struct iov_iter iter; + + if ((fpath == NULL) || (val == NULL) || (addr < 0) || (write_bytes <= 0)) { + DBG_DEBUG(DBG_ERROR, "input arguments error, addr=%d write_bytes=%d\n", addr, write_bytes); + return -DFD_RV_INDEX_INVALID; + } + + /* Open file */ + filp = filp_open(fpath, O_RDWR, 777); + if (IS_ERR(filp)) { + DBG_DEBUG(DBG_ERROR, "open file[%s] fail\n", fpath); + return -DFD_RV_DEV_FAIL; + } + /* Location file */ + pos = addr; + iov_iter_kvec(&iter, ITER_SOURCE, &iov, 1, iov.iov_len); + ret = vfs_iter_write(filp, &iter, &pos, 0); + if (ret < 0) { + DBG_DEBUG(DBG_ERROR,"vfs_iter_write failed, path=%s, addr=%d, size=%d, ret=%d\n", fpath, addr, write_bytes, ret); + ret = -DFD_RV_DEV_FAIL; + } + vfs_fsync(filp, 1); + filp_close(filp, NULL); + return ret; +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg_file.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg_file.c new file mode 100644 index 000000000000..7164e02d90f2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg_file.c @@ -0,0 +1,305 @@ +/* + * An dfd_cfg_file driver for cfg of file devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dfd_cfg_file.h" +#include "wb_module.h" + +struct getdents_callback { + struct dir_context ctx; + const char *obj_name; /* Name to be matched */ + char *match_name; /* Matching result */ + int dir_len; /* Directory name length */ + int found; /* Configuration flag */ +}; + +/* + * Open file + * @fname: filename + * @kfile_ctrl: File control variable + * + * @returns: 0 Success, other failure + */ +int kfile_open(char *fname, kfile_ctrl_t *kfile_ctrl) +{ + int ret; + struct file *filp; + loff_t pos; + + if ((fname == NULL) || (kfile_ctrl == NULL)) { + return KFILE_RV_INPUT_ERR; + } + + /* Open file */ + filp = filp_open(fname, O_RDONLY, 0); + if (IS_ERR(filp)) { + return KFILE_RV_OPEN_FAIL; + } + + kfile_ctrl->size = filp->f_inode->i_size; + + /* Request file size memory */ + kfile_ctrl->buf = kmalloc(kfile_ctrl->size, GFP_KERNEL); + if (kfile_ctrl->buf == NULL) { + ret = KFILE_RV_MALLOC_FAIL; + goto close_fp; + } + mem_clear(kfile_ctrl->buf, kfile_ctrl->size); + /* Read file contents */ + pos = 0; + ret = kernel_read(filp, kfile_ctrl->buf, kfile_ctrl->size, &pos); + if (ret < 0) { + ret = KFILE_RV_RD_FAIL; + goto free_buf; + } + /* Set current position */ + kfile_ctrl->pos = 0; + + ret = KFILE_RV_OK; + goto close_fp; + +free_buf: + kfree(kfile_ctrl->buf); + kfile_ctrl->buf = NULL; + +close_fp: + filp_close(filp, NULL); + return ret; +} + +/* + * Close file + * @kfile_ctrl: File control variable + */ +void kfile_close(kfile_ctrl_t *kfile_ctrl) +{ + if (kfile_ctrl == NULL) { + return; + } + + /* Set the file size to 0 to free memory */ + kfile_ctrl->size = 0; + kfile_ctrl->pos = 0; + if (kfile_ctrl->buf) { + kfree(kfile_ctrl->buf); + kfile_ctrl->buf = NULL; + } +} + +/* + * Get a row + * @buf: buf Buffer area + * @buf_size: buf size + * @kfile_ctrl: File control variable + * + * @returns: >=0 Success, other failure + */ +int kfile_gets(char *buf, int buf_size, kfile_ctrl_t *kfile_ctrl) +{ + int i; + int has_cr = 0; + + if ((buf == NULL) || (buf_size <= 0) || (kfile_ctrl == NULL) || (kfile_ctrl->buf == NULL) + || (kfile_ctrl->size <= 0)) { + return KFILE_RV_INPUT_ERR; + } + + /* Clear the buf first */ + mem_clear(buf, buf_size); + for (i = 0; i < buf_size; i++) { + /* It's at the end of the file */ + if (kfile_ctrl->pos >= kfile_ctrl->size) { + break; + } + + /* The previous data is a newline character, and a line has been copied */ + if (has_cr) { + break; + } + + /* Search for a newline */ + if (IS_CR(kfile_ctrl->buf[kfile_ctrl->pos])) { + has_cr = 1; + } + + /* Copy data */ + buf[i] = kfile_ctrl->buf[kfile_ctrl->pos]; + kfile_ctrl->pos++; + } + + return i; +} + +/* + * Read data + * @buf: buf Buffer area + * @buf_size: buf size + * @kfile_ctrl: File control variable + * + * @returns: >=0 Success, other failure + */ +int kfile_read(int32_t addr, char *buf, int buf_size, kfile_ctrl_t *kfile_ctrl) +{ + int i; + + if ((buf == NULL) || (buf_size <= 0) || (kfile_ctrl == NULL) || (kfile_ctrl->buf == NULL) + || (kfile_ctrl->size <= 0)) { + return KFILE_RV_INPUT_ERR; + } + + /* Address check */ + if ((addr < 0) || (addr >= kfile_ctrl->size)) { + return KFILE_RV_ADDR_ERR; + } + + /* Clear the buf first */ + mem_clear(buf, buf_size); + + kfile_ctrl->pos = addr; + for (i = 0; i < buf_size; i++) { + /* It's at the end of the file */ + if (kfile_ctrl->pos >= kfile_ctrl->size) { + break; + } + + /* Copy data */ + buf[i] = kfile_ctrl->buf[kfile_ctrl->pos]; + kfile_ctrl->pos++; + } + + return i; +} + +static bool kfile_filldir_one(struct dir_context *ctx, const char * name, int len, + loff_t pos, u64 ino, unsigned int d_type) +{ + struct getdents_callback *buf; + bool result; + buf = container_of(ctx, struct getdents_callback, ctx); + result = 1; + if (strncmp(buf->obj_name, name, strlen(buf->obj_name)) == 0) { + if (buf->dir_len < len) { + DBG_DEBUG(DBG_ERROR, "match ok. dir name:%s, but buf_len %d small than dir len %d.\n", + name, buf->dir_len, len); + buf->found = 0; + return 0; + } + mem_clear(buf->match_name, buf->dir_len); + memcpy(buf->match_name, name, len); + buf->found = 1; + result = 0; + } + return result; +} + +/* + * Read data + * @buf: buf Buffer area + * @buf_size: buf size + * @kfile_ctrl: File control variable + * + * @returns: >=0 Success, other failure + */ +int kfile_iterate_dir(const char *dir_path, const char *obj_name, char *match_name, int len) +{ + int ret; + struct file *dir; + struct getdents_callback buffer = { + .ctx.actor = kfile_filldir_one, + }; + + if (!dir_path || !obj_name || !match_name) { + DBG_DEBUG(DBG_ERROR, "params error. \n"); + return KFILE_RV_INPUT_ERR; + } + buffer.obj_name = obj_name; + buffer.match_name = match_name; + buffer.dir_len = len; + buffer.found = 0; + /* Open folde */ + dir = filp_open(dir_path, O_RDONLY, 0); + if (IS_ERR(dir)) { + DBG_DEBUG(DBG_ERROR, "filp_open error, dir path:%s\n", dir_path); + return KFILE_RV_OPEN_FAIL; + } + ret = iterate_dir(dir, &buffer.ctx); + if (buffer.found) { + DBG_DEBUG(DBG_VERBOSE, "match ok, dir name:%s\n", match_name); + filp_close(dir, NULL); + return DFD_RV_OK; + } + filp_close(dir, NULL); + return -DFD_RV_NODE_FAIL; +} + +#if 0 +/* + * Write data + * @fname: indicates the file name + * @addr: offset address of the file to be written + * @buf: Writes data + * @buf_size: indicates the data size + * + * @returns: >=0 Success, others fail + */ +int kfile_write(char *fpath, int32_t addr, char *buf, int buf_size) +{ + int ret = KFILE_RV_OK; + struct file *filp; + int wlen; + + if ((fpath == NULL) || (buf == NULL) || (buf_size <= 0)) { + return KFILE_RV_INPUT_ERR; + } + + /* Address check */ + if (addr < 0) { + return KFILE_RV_ADDR_ERR; + } + + /* Open file */ + filp = filp_open(fpath, O_RDWR, 0); + if (IS_ERR(filp)) { + return KFILE_RV_OPEN_FAIL; + } + + filp->f_op->llseek(filp,0,0); + filp->f_pos = addr; + /* Write file content */ + wlen = filp->f_op->write(filp, buf, buf_size, &(filp->f_pos)); + if (wlen < 0) { + ret = KFILE_RV_WR_FAIL; + } + + filp->f_op->llseek(filp,0,0); + filp_close(filp, NULL); + + return ret; +} +#endif diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg_info.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg_info.c new file mode 100644 index 000000000000..615285d1c326 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg_info.c @@ -0,0 +1,929 @@ +/* + * An dfd_cfg_info driver for cfg of information devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include + +#include "wb_module.h" +#include "dfd_cfg_adapter.h" +#include "dfd_cfg.h" +#include "dfd_cfg_info.h" +#include "dfd_cfg_file.h" + +#define DFD_HWMON_NAME "hwmon" + +/* CPLD_VOLATGE_VALUE_MODE1 */ +/* high 8 bit + high 4 bit(bit4-bit7) */ +#define DFD_GET_CPLD_VOLATGE_CODE_VALUE(value) ((value >> 4)& 0xfff) +#define DFD_GET_CPLD_VOLATGE_REAL_VALUE(code_val, k) ((code_val * 16 * 33 * k) / ((65536 - 5000) * 10)) + +/* CPLD_VOLATGE_VALUE_MODE2 */ +/* high 8 bit + low 4 bit(bit0-bit3) */ +#define DFD_GET_CPLD_VOLATGE_CODE_VALUE2(value) (((value & 0xff00) >> 4) + (value & 0xf)) +#define DFD_GET_CPLD_VOLATGE_REAL_VALUE2(code_val, k) ((code_val * 33 * k) / 40950) + +typedef enum cpld_volatge_value_s { + CPLD_VOLATGE_VALUE_MODE1, + CPLD_VOLATGE_VALUE_MODE2, +} cpld_volatge_value_t; + +#define VALID_MAC_TEMP_MAX (120) +#define VALID_MAC_TEMP_MIN (-40) +#define MAC_TEMP_INVALID (-99999999) + +/* info_ctrl_t member string */ +char *g_info_ctrl_mem_str[INFO_CTRL_MEM_END] = { + ".mode", + ".int_cons", + ".src", + ".frmt", + ".pola", + ".fpath", + ".addr", + ".len", + ".bit_offset", + ".str_cons", + ".int_extra1", + ".int_extra2", + ".int_extra3", +}; + +/* info_ctrl_mode_t enumeration string */ +char *g_info_ctrl_mode_str[INFO_CTRL_MODE_END] = { + "none", + "config", + "constant", + "tlv", + "str_constant", +}; + +/* info_src_t enumeration string */ +char *g_info_src_str[INFO_SRC_END] = { + "none", + "cpld", + "fpga", + "other_i2c", + "file", +}; + +/* info_frmt_t enumeration string */ +char *g_info_frmt_str[INFO_FRMT_END] = { + "none", + "bit", + "byte", + "num_bytes", + "num_str", + "num_buf", + "buf", +}; + +/* info_pola_t enumeration string */ +char *g_info_pola_str[INFO_POLA_END] = { + "none", + "positive", + "negative", +}; + +/* Read information from the cpld */ +static int dfd_read_info_from_cpld(int32_t addr, int read_bytes, uint8_t *val) +{ + int i, rv; + + for (i = 0; i < read_bytes; i++) { + rv = dfd_ko_cpld_read(addr, &(val[i])); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "read info[addr=0x%x read_bytes=%d] from cpld fail, reading_byte=%d rv=%d\n", + addr, read_bytes, i, rv); + return rv; + } + addr++; + } + + return read_bytes; +} + +/* Write information to the cpld */ +static int dfd_write_info_to_cpld(int32_t addr, int write_bytes, uint8_t *val, uint8_t bit_mask) +{ + int rv; + uint8_t val_tmp; + + val_tmp = val[0]; + rv = dfd_ko_cpld_write(addr, val_tmp); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "write info[addr=0x%x val=0x%x] to cpld fail, rv=%d\n", addr, val_tmp, rv); + return -1; + } + + return 0; +} + +/* Read information from other_i2c */ +static int dfd_read_info_from_other_i2c(int32_t addr, int read_bytes, uint8_t *val) +{ + int rv; + + rv = dfd_ko_other_i2c_dev_read(addr, val, read_bytes); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "read info[addr=0x%x read_bytes=%d] from othre i2c fail, rv=%d\r\n", + addr, read_bytes, rv); + return rv; + } + + return read_bytes; +} + +/* Read information */ +static int dfd_read_info(info_src_t src, char *fpath, int32_t addr, int read_bytes, uint8_t *val) +{ + int rv = 0; + + /* Read data from different sources */ + switch (src) { + case INFO_SRC_CPLD: + rv = dfd_read_info_from_cpld(addr, read_bytes, val); + break; + case INFO_SRC_FPGA: + rv = -1; + DBG_DEBUG(DBG_ERROR, "not support read info from fpga\n"); + break; + case INFO_SRC_OTHER_I2C: + rv = dfd_read_info_from_other_i2c(addr, read_bytes, val); + break; + case INFO_SRC_FILE: + rv = dfd_ko_read_file(fpath, addr, val, read_bytes); + break; + default: + rv = -1; + DBG_DEBUG(DBG_ERROR, "info src[%d] error\n", src); + break; + } + + return rv; +} + +/* Write message */ +static int dfd_write_info(info_src_t src, char *fpath, int32_t addr, int write_bytes, uint8_t *val, uint8_t bit_mask) +{ + int rv = 0; + + /* Write data to separate sources */ + switch (src) { + case INFO_SRC_CPLD: + rv = dfd_write_info_to_cpld(addr, write_bytes, val, bit_mask); + break; + case INFO_SRC_FPGA: + rv = -1; + DBG_DEBUG(DBG_ERROR, "not support write info to fpga\n"); + break; + case INFO_SRC_OTHER_I2C: + rv = -1; + DBG_DEBUG(DBG_ERROR, "not support write info to other i2c\n"); + break; + case INFO_SRC_FILE: + rv = dfd_ko_write_file(fpath, addr, val, write_bytes); + break; + default: + rv = -1; + DBG_DEBUG(DBG_ERROR, "info src[%d] error\n", src); + break; + } + + return rv; +} + +static int dfd_get_info_value(info_ctrl_t *info_ctrl, int *ret, info_num_buf_to_value_f pfun) +{ + int i, rv; + int read_bytes, readed_bytes, int_tmp; + uint8_t byte_tmp, val[INFO_INT_MAX_LEN + 1] = {0}; + + if (info_ctrl->mode == INFO_CTRL_MODE_CONS) { + *ret = info_ctrl->int_cons; + return DFD_RV_OK; + } + if (info_ctrl->mode == INFO_CTRL_MODE_TLV) { + return INFO_CTRL_MODE_TLV; + } + + if (IS_INFO_FRMT_BIT(info_ctrl->frmt)) { + if (!INFO_BIT_OFFSET_VALID(info_ctrl->bit_offset)) { + DBG_DEBUG(DBG_ERROR, "info ctrl bit_offsest[%d] invalid\n", + info_ctrl->bit_offset); + return -DFD_RV_TYPE_ERR; + } + read_bytes = 1; + } else if (IS_INFO_FRMT_BYTE(info_ctrl->frmt) || IS_INFO_FRMT_NUM_STR(info_ctrl->frmt) + || IS_INFO_FRMT_NUM_BUF(info_ctrl->frmt)) { + if (!INFO_INT_LEN_VALAID(info_ctrl->len)) { + DBG_DEBUG(DBG_ERROR, "info ctrl len[%d] invalid\n", info_ctrl->len); + return -DFD_RV_TYPE_ERR; + } + read_bytes = info_ctrl->len; + } else { + DBG_DEBUG(DBG_ERROR, "info ctrl info format[%d] error\n", info_ctrl->frmt); + return -DFD_RV_TYPE_ERR; + } + + readed_bytes = dfd_read_info(info_ctrl->src, info_ctrl->fpath, info_ctrl->addr, read_bytes, &(val[0])); + if (readed_bytes <= 0) { + DBG_DEBUG(DBG_ERROR, "read int info[src=%s frmt=%s fpath=%s addr=0x%x read_bytes=%d] fail, rv=%d\n", + g_info_src_str[info_ctrl->src], g_info_frmt_str[info_ctrl->frmt], info_ctrl->fpath, + info_ctrl->addr, read_bytes, readed_bytes); + return -DFD_RV_DEV_FAIL; + } + + if (IS_INFO_FRMT_BIT(info_ctrl->frmt)) { + if (info_ctrl->pola == INFO_POLA_NEGA) { + val[0] = ~val[0]; + } + byte_tmp = (val[0] >> info_ctrl->bit_offset) & (~(0xff << info_ctrl->len)); + if (pfun) { + rv = pfun(&byte_tmp, sizeof(byte_tmp), &int_tmp); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "info ctrl bit process fail, rv=%d\n", rv); + return rv; + } + } else { + int_tmp = (int)byte_tmp; + } + } else if (IS_INFO_FRMT_BYTE(info_ctrl->frmt)) { + int_tmp = 0; + for (i = 0; i < info_ctrl->len; i++) { + if (info_ctrl->pola == INFO_POLA_NEGA) { + int_tmp |= val[info_ctrl->len - i - 1]; + } else { + int_tmp |= val[i]; + } + if (i != (info_ctrl->len - 1)) { + int_tmp <<= 8; + } + } + } else if (IS_INFO_FRMT_NUM_STR(info_ctrl->frmt)) { + val[readed_bytes] = '\0'; + int_tmp = simple_strtol((char *)(&(val[0])), NULL, 10); + } else { + if (pfun == NULL) { + DBG_DEBUG(DBG_ERROR, "info ctrl number buf process function is null\n"); + return -DFD_RV_INDEX_INVALID; + } + rv = pfun(val, readed_bytes, &int_tmp); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "info ctrl number buf process fail, rv=%d\n", rv); + return rv; + } + } + + *ret = int_tmp; + DBG_DEBUG(DBG_VERBOSE, "read int info[src=%s frmt=%s pola=%s fpath=%s addr=0x%x len=%d bit_offset=%d] success, ret=%d\n", + g_info_src_str[info_ctrl->src], g_info_frmt_str[info_ctrl->frmt], g_info_pola_str[info_ctrl->pola], + info_ctrl->fpath, info_ctrl->addr, info_ctrl->len, info_ctrl->bit_offset, *ret); + return DFD_RV_OK; +} + +/** + * dfd_info_get_int - Get int type information + * @key: Search keyword of the configuration item + * @ret: int type information + * @pfun: num buf type data conversion function + * + * @returns: 0 Success, <0 failure + */ +int dfd_info_get_int(uint64_t key, int *ret, info_num_buf_to_value_f pfun) +{ + int rv; + info_ctrl_t *info_ctrl; + + if (!DFD_CFG_ITEM_IS_INFO_CTRL(DFD_CFG_ITEM_ID(key)) || (ret == NULL)) { + DBG_DEBUG(DBG_ERROR, "input arguments error, key=0x%08llx\n", key); + return -DFD_RV_INDEX_INVALID; + } + + info_ctrl = dfd_ko_cfg_get_item(key); + if (info_ctrl == NULL) { + DBG_DEBUG(DBG_WARN, "get info ctrl fail, key=0x%08llx\n", key); + return -DFD_RV_DEV_NOTSUPPORT; + } + + DBG_DEBUG(DBG_VERBOSE, "get info ctrl value, key=0x%08llx\n", key); + rv = dfd_get_info_value(info_ctrl, ret, pfun); + return rv; +} + +/** + * dfd_info_get_buf - Get buf type information + * @key: Search keyword of the configuration item + * @buf: information buf + * @buf_len: buf length, which must be no less than info_ctrl->len + * @pfun: Data conversion function pointer + * + * @returns: <0 Success, <0 failure + */ +int dfd_info_get_buf(uint64_t key, uint8_t *buf, int buf_len, info_buf_to_buf_f pfun) +{ + int rv; + int read_bytes, buf_real_len; + uint8_t buf_tmp[INFO_BUF_MAX_LEN]; + info_ctrl_t *info_ctrl; + + /* Entry check */ + if (!DFD_CFG_ITEM_IS_INFO_CTRL(DFD_CFG_ITEM_ID(key)) || (buf == NULL)) { + DBG_DEBUG(DBG_ERROR, "input arguments error, key=0x%08llx\n", key); + return -DFD_RV_INDEX_INVALID; + } + + /* Get the configuration item read and write control variables */ + info_ctrl = dfd_ko_cfg_get_item(key); + if (info_ctrl == NULL) { + DBG_DEBUG(DBG_WARN, "get info ctrl fail, key=0x%08llx\n", key); + return -DFD_RV_DEV_NOTSUPPORT; + } + + /* Failed to return the non-configured mode */ + if (info_ctrl->mode != INFO_CTRL_MODE_CFG) { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08llx] mode[%d] invalid\n", key, info_ctrl->mode); + return -DFD_RV_TYPE_ERR; + } + + /* Parameter check */ + if (!IS_INFO_FRMT_BUF(info_ctrl->frmt) || !INFO_BUF_LEN_VALAID(info_ctrl->len) + || (buf_len <= info_ctrl->len)) { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08llx] format=%d or len=%d invlaid, buf_len=%d\n", + key, info_ctrl->frmt, info_ctrl->len, buf_len); + return -DFD_RV_TYPE_ERR; + } + + /* Read information */ + read_bytes = dfd_read_info(info_ctrl->src, info_ctrl->fpath, info_ctrl->addr, info_ctrl->len, buf_tmp); + if (read_bytes <= 0) { + DBG_DEBUG(DBG_ERROR, "read buf info[key=0x%08llx src=%s frmt=%s fpath=%s addr=0x%x len=%d] fail, rv=%d\n", + key, g_info_src_str[info_ctrl->src], g_info_frmt_str[info_ctrl->frmt], info_ctrl->fpath, + info_ctrl->addr, info_ctrl->len, read_bytes); + return -DFD_RV_DEV_FAIL; + } + + /* Data conversion processing */ + if (pfun) { + buf_real_len = buf_len; + rv = pfun(buf_tmp, read_bytes, buf, &buf_real_len); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08llx] buf process fail, rv=%d\n", key, rv); + return -DFD_RV_DEV_FAIL; + } + } else { + buf_real_len = read_bytes; + memcpy(buf, buf_tmp, read_bytes); + } + + return buf_real_len; +} + +/** + * dfd_2key_info_get_buf - Get buf type information + * @key: indicates the search keyword of the configuration item + * @buf: Message buf + * @buf_len: indicates the buf length, which must be no less than info_ctrl->len + * @pfun: Data conversion function pointer + * + * @returns: <0 fails, others succeed + */ +static int dfd_2key_info_get_buf(info_ctrl_t *info_ctrl, uint8_t *buf, int buf_len, info_hwmon_buf_f pfun) +{ + int rv; + int read_bytes, buf_real_len; + uint8_t buf_tmp[INFO_BUF_MAX_LEN]; + char fpath[INFO_FPATH_MAX_LEN]; + int coefficient, addend; + + /* Parameter check */ + if (!IS_INFO_FRMT_BUF(info_ctrl->frmt) || !INFO_BUF_LEN_VALAID(info_ctrl->len) + || (buf_len <= info_ctrl->len)) { + DBG_DEBUG(DBG_ERROR, "key_path info ctrl format=%d or len=%d invlaid, buf_len=%d\n", + info_ctrl->frmt, info_ctrl->len, buf_len); + return -DFD_RV_TYPE_ERR; + } + + mem_clear(buf_tmp, sizeof(buf_tmp)); + rv = kfile_iterate_dir(info_ctrl->fpath, DFD_HWMON_NAME, buf_tmp, INFO_BUF_MAX_LEN); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "dir patch:%s, can find name %s dir \n", + info_ctrl->fpath, DFD_HWMON_NAME); + return -DFD_RV_NO_NODE; + } + mem_clear(fpath, sizeof(fpath)); + snprintf(fpath, sizeof(fpath), "%s%s/%s", + info_ctrl->fpath, buf_tmp, info_ctrl->str_cons); + DBG_DEBUG(DBG_VERBOSE, "match ok path: %s\n", fpath); + + mem_clear(buf_tmp, sizeof(buf_tmp)); + /* Read information */ + read_bytes = dfd_read_info(info_ctrl->src, fpath, info_ctrl->addr, info_ctrl->len, buf_tmp); + if (read_bytes <= 0) { + DBG_DEBUG(DBG_ERROR, "read buf info[src: %s frmt: %s fpath: %s addr: 0x%x len: %d] fail, rv=%d\n", + g_info_src_str[info_ctrl->src], g_info_src_str[info_ctrl->frmt], fpath, + info_ctrl->addr, info_ctrl->len, read_bytes); + return -DFD_RV_DEV_FAIL; + } + + /* Data conversion processing */ + if (pfun) { + buf_real_len = buf_len; + coefficient = info_ctrl->int_extra1; + addend = info_ctrl->int_extra2; + if (coefficient != 0) { + rv = pfun(buf_tmp, read_bytes, buf, &buf_real_len, info_ctrl, coefficient, addend); + } else { + rv = pfun(buf_tmp, read_bytes, buf, &buf_real_len, info_ctrl, 1, addend); + } + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "info ctrl buf process fail, rv=%d\n", rv); + return -DFD_RV_DEV_FAIL; + } + } else { + buf_real_len = read_bytes; + memcpy(buf, buf_tmp, buf_real_len); + } + return buf_real_len; +} + +/** + * dfd_info_set_int - Set the int type information + * @key: Search keyword of the configuration item + * @val: int type information + * + * @returns: 0 succeeds, <0 fails + */ +int dfd_info_set_int(uint64_t key, int val) +{ + int rv; + int write_bytes; + uint8_t byte_tmp, bit_mask, val_tmp; + info_ctrl_t *info_ctrl; + uint8_t *val_buf; + + val_buf = &byte_tmp; + /* Entry check */ + if (!DFD_CFG_ITEM_IS_INFO_CTRL(DFD_CFG_ITEM_ID(key))) { + DBG_DEBUG(DBG_ERROR, "input arguments error, key=0x%08llx\n", key); + return -DFD_RV_INDEX_INVALID; + } + + /* Get the configuration item read and write control variables */ + info_ctrl = dfd_ko_cfg_get_item(key); + if (info_ctrl == NULL) { + DBG_DEBUG(DBG_WARN, "get info ctrl fail, key=0x%08llx\n", key); + return -DFD_RV_DEV_NOTSUPPORT; + } + + /* Non-configuration is not processed */ + if (info_ctrl->mode != INFO_CTRL_MODE_CFG) { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08llx] mode[%d] warnning\n", key, info_ctrl->mode); + return -DFD_RV_TYPE_ERR; + } + + /* Information conversion */ + if (IS_INFO_FRMT_BIT(info_ctrl->frmt)) { + /* Bit offset check */ + if (!INFO_BIT_OFFSET_VALID(info_ctrl->bit_offset)) { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08llx] bit_offsest[%d] invalid\n", + key, info_ctrl->bit_offset); + return -DFD_RV_TYPE_ERR; + } + + /* Write data value conversion */ + byte_tmp = (uint8_t)(val & 0xff); /* The minimum 8 bits of data in bit format is valid */ + byte_tmp <<= info_ctrl->bit_offset; /* The value is shifted to the corresponding bit */ + if (info_ctrl->pola == INFO_POLA_NEGA) { /* Negative polarity data is reversed */ + byte_tmp = ~byte_tmp; + } + + write_bytes = 1; + /* Information valid mask */ + bit_mask = (~(0xff << info_ctrl->len)) << info_ctrl->bit_offset; + if (bit_mask != 0xff) { + rv = dfd_read_info(info_ctrl->src, info_ctrl->fpath, info_ctrl->addr, write_bytes, + &val_tmp); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, + "read original info[src=%d][fpath=%s][addr=0x%x] fail. rv = %d\n", + info_ctrl->src, info_ctrl->fpath, info_ctrl->addr, rv); + return -DFD_RV_DEV_FAIL; + } + val_tmp = (val_tmp & (~bit_mask)) | ((uint8_t)byte_tmp & bit_mask); + byte_tmp = val_tmp; + } + } else if (IS_INFO_FRMT_BYTE(info_ctrl->frmt)) { + /* Length check */ + if (!INFO_INT_LEN_VALAID(info_ctrl->len)) { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08llx] len[%d] invalid\n", key, info_ctrl->len); + return -DFD_RV_TYPE_ERR; + } + + /* XXX There is currently no requirement to set multi-byte int data */ + write_bytes = 1; + + /* Write data value conversion */ + byte_tmp = (uint8_t)(val & 0xff); + + /* Information valid mask */ + bit_mask = 0xff; + } else if (IS_INFO_FRMT_NUM_STR(info_ctrl->frmt)) { + val_buf = info_ctrl->str_cons; + write_bytes = strlen(info_ctrl->str_cons); + if (write_bytes <= 0) { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08llx] write num_str: fpath: %s, len[%d] invalid\n", + key, info_ctrl->fpath, write_bytes); + return -DFD_RV_INVALID_VALUE; + } + bit_mask = 0xff; + DBG_DEBUG(DBG_VERBOSE, "info ctrl[key=0x%08llx], write num_str: fpath: %s, write val: %s, len: %d\n", + key, info_ctrl->fpath, val_buf, write_bytes); + } else if (IS_INFO_FRMT_NUM_BUF(info_ctrl->frmt)) { + /* Length check */ + if (!INFO_INT_LEN_VALAID(info_ctrl->len)) { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08llx] len[%d] invalid\n", key, info_ctrl->len); + return -DFD_RV_TYPE_ERR; + } + + /* num is converted before buf is set. XXX does not need to set multi-byte int data */ + write_bytes = 1; + + /* Write data value conversion */ + byte_tmp = (uint8_t)(val & 0xff); + + /* Information valid mask */ + bit_mask = 0xff; + } else { + DBG_DEBUG(DBG_ERROR, "info ctrl[key=0x%08llx] format[%d] error\n", key, info_ctrl->frmt); + return -DFD_RV_TYPE_ERR; + } + + /* Write message */ + rv = dfd_write_info(info_ctrl->src, info_ctrl->fpath, info_ctrl->addr, write_bytes, + val_buf, bit_mask); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "write int info[src=%s frmt=%s fpath=%s addr=0x%x len=%d val=%d] fail, rv=%d\n", + g_info_src_str[info_ctrl->src], g_info_frmt_str[info_ctrl->frmt], info_ctrl->fpath, + info_ctrl->addr, info_ctrl->len, val, rv); + return -DFD_RV_DEV_FAIL; + } + + DBG_DEBUG(DBG_VERBOSE, "write int info[src=%s frmt=%s pola=%s fpath=%s addr=0x%x len=%d bit_offset=%d val=%d] success\n", + g_info_src_str[info_ctrl->src], g_info_frmt_str[info_ctrl->frmt], g_info_pola_str[info_ctrl->pola], + info_ctrl->fpath, info_ctrl->addr, info_ctrl->len, info_ctrl->bit_offset, val); + return DFD_RV_OK; +} + +static long dfd_info_reg2data_linear(uint64_t key, int data) +{ + s16 exponent; + s32 mantissa; + long val; + info_ctrl_t *info_ctrl; + + /* Get the configuration item read and write control variables */ + info_ctrl = dfd_ko_cfg_get_item(key); + if (info_ctrl == NULL) { + DBG_DEBUG(DBG_WARN, "get info ctrl fail, key=0x%08llx\n", key); + return -DFD_RV_DEV_NOTSUPPORT; + } + + switch (info_ctrl->int_extra1) { + case LINEAR11: + exponent = ((s16)data) >> 11; + mantissa = ((s16)((data & 0x7ff) << 5)) >> 5; + val = mantissa; + val = val * 1000L; + break; + case LINEAR16: + break; + default: + break; + } + + if (DFD_CFG_ITEM_ID(key) == DFD_CFG_ITEM_HWMON_POWER) { + val = val * 1000L; + } + + if (exponent >= 0) { + val <<= exponent; + } else { + val >>= -exponent; + } + + return val; +} + +static long dfd_info_reg2data_tmp464(uint64_t key, int data) +{ + s16 tmp_val; + long val; + + DBG_DEBUG(DBG_VERBOSE, "reg2data_tmp464, data=%d\n", data); + + /* Positive number:data/8*0.0625 */ + if (data >= 0) { + val = data*625/80; + /* Negative number: The first bit is the sign bit and the rest is inverted +1 */ + } else { + tmp_val = ~(data & 0x7ff) + 1; + val = tmp_val*625/80; + } + + return val; +} + +static long dfd_info_reg2data_mac_th5(uint64_t key, int data) +{ + int tmp_val; + long val; + + DBG_DEBUG(DBG_VERBOSE, "reg2data_mac_th5, data=0x%d\n", data); + + tmp_val = data >> 4; + val = 476359 - (((tmp_val - 2) * 317704) / 2000); + + DBG_DEBUG(DBG_VERBOSE, "reg2data_mac_th5, val=0x%ld\n", val); + return val; +} + +static long dfd_info_reg2data_mac_th4(uint64_t key, int data) +{ + int tmp_val; + int val; + + DBG_DEBUG(DBG_VERBOSE, "reg2data_mac_th4, data=%d\n", data); + + tmp_val = data >> 4; + val = 356070 - (((tmp_val - 2) * 237340) / 2000); + + DBG_DEBUG(DBG_VERBOSE, "reg2data_mac_th4, val=%d\n", val); + return val; +} + + +static int dfd_info_get_cpld_voltage(uint64_t key, uint32_t *value) +{ + int rv; + uint32_t vol_ref_tmp, vol_ref; + uint32_t vol_curr_tmp, vol_curr; + info_ctrl_t *info_ctrl; + info_ctrl_t info_ctrl_tmp; + uint32_t vol_coefficient; + + info_ctrl = dfd_ko_cfg_get_item(key); + if (info_ctrl == NULL) { + DBG_DEBUG(DBG_WARN, "get info ctrl fail, key=0x%08llx\n", key); + return -DFD_RV_DEV_NOTSUPPORT; + } + + vol_coefficient = (uint32_t)info_ctrl->int_extra2; + + rv = dfd_get_info_value(info_ctrl, &vol_curr_tmp, NULL); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "get cpld current voltage error, addr:0x%x, rv = %d\n", info_ctrl->addr, rv); + return rv; + } + if (info_ctrl->int_extra3 == CPLD_VOLATGE_VALUE_MODE2) { + vol_curr_tmp = DFD_GET_CPLD_VOLATGE_CODE_VALUE2(vol_curr_tmp); + vol_curr = DFD_GET_CPLD_VOLATGE_REAL_VALUE2(vol_curr_tmp, info_ctrl->int_extra2); + DBG_DEBUG(DBG_VERBOSE, "vol_curr_tmp = 0x%x, vol_curr = 0x%x, is same.\n", vol_curr_tmp, vol_curr); + } else { + vol_curr_tmp = DFD_GET_CPLD_VOLATGE_CODE_VALUE(vol_curr_tmp); + if (info_ctrl->addr == info_ctrl->int_extra1) { + vol_curr = DFD_GET_CPLD_VOLATGE_REAL_VALUE(vol_curr_tmp, vol_coefficient); + DBG_DEBUG(DBG_VERBOSE, "current voltage is reference voltage, vol_curr_tmp: 0x%x, coefficient: %u, vol_curr: %u\n", + vol_curr_tmp, vol_coefficient, vol_curr); + } else { + memcpy(&info_ctrl_tmp, info_ctrl, sizeof(info_ctrl_t)); + info_ctrl_tmp.addr = info_ctrl->int_extra1; + rv = dfd_get_info_value(&info_ctrl_tmp, &vol_ref_tmp, NULL); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "get cpld reference voltage error, addr: 0x%x, rv: %d\n", info_ctrl_tmp.addr, rv); + return rv; + } + vol_ref = DFD_GET_CPLD_VOLATGE_CODE_VALUE(vol_ref_tmp); + DBG_DEBUG(DBG_VERBOSE, "vol_ref_tmp: 0x%x, vol_ref: 0x%x\n", vol_ref_tmp, vol_ref); + vol_curr = (vol_curr_tmp * vol_coefficient) / vol_ref; + DBG_DEBUG(DBG_VERBOSE, "vol_curr_tmp: 0x%x, vol_ref: 0x%x, coefficient: %u, vol_curr: %u\n", + vol_curr_tmp, vol_ref, vol_coefficient, vol_curr); + } + } + *value = vol_curr; + return DFD_RV_OK; +} + +static int dfd_info_get_cpld_temperature(uint64_t key, int *value) +{ + int rv; + int temp_reg; + info_ctrl_t *info_ctrl; + long val; + + /* Get the configuration item read and write control variables */ + info_ctrl = dfd_ko_cfg_get_item(key); + if (info_ctrl == NULL) { + DBG_DEBUG(DBG_WARN, "get info ctrl fail, key=0x%08llx\n", key); + return -DFD_RV_DEV_NOTSUPPORT; + } + + /* Read the temperature value */ + rv = dfd_info_get_int(key, &temp_reg, NULL); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "get cpld current temperature error, addr:0x%x, rv =%d\n", info_ctrl->addr, rv); + return rv; + } + DBG_DEBUG(DBG_VERBOSE, "get cpld temp:0x%08x, extra1 0x%x\n", temp_reg, info_ctrl->int_extra1); + + switch (info_ctrl->int_extra1) { + case LINEAR11: + val = dfd_info_reg2data_linear(key, temp_reg); + break; + case TMP464: + val = dfd_info_reg2data_tmp464(key, temp_reg); + break; + case MAC_TH5: + val = dfd_info_reg2data_mac_th5(key, temp_reg); + break; + case MAC_TH4: + val = dfd_info_reg2data_mac_th4(key, temp_reg); + break; + default: + val = temp_reg; + break; + } + + if ((val / 1000 < VALID_MAC_TEMP_MIN) || (val / 1000 > VALID_MAC_TEMP_MAX)) { + DBG_DEBUG(DBG_ERROR, "mac temp invalid, temp = %ld\n", val); + val = MAC_TEMP_INVALID; + } + DBG_DEBUG(DBG_VERBOSE, "calc temp:%ld \n", val); + *value = val; + + return DFD_RV_OK; +} + +static int dfd_info_get_sensor_value(uint64_t key, uint8_t *buf, int buf_len, info_hwmon_buf_f pfun) +{ + int rv, buf_real_len; + uint32_t value; + int temp_value; + uint8_t buf_tmp[INFO_BUF_MAX_LEN]; + info_ctrl_t *info_ctrl; + + info_ctrl = dfd_ko_cfg_get_item(key); + if (info_ctrl == NULL) { + DBG_DEBUG(DBG_ERROR, "get info ctrl fail, key=0x%08llx\n", key); + return -DFD_RV_DEV_NOTSUPPORT; + } + + if (DFD_CFG_ITEM_ID(key) == DFD_CFG_ITEM_HWMON_IN && info_ctrl->src == INFO_SRC_CPLD) { + rv = dfd_info_get_cpld_voltage(key, &value); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "get cpld voltage failed.key=0x%08llx, rv:%d\n", key, rv); + return -DFD_RV_DEV_NOTSUPPORT; + } + DBG_DEBUG(DBG_VERBOSE, "get cpld voltage ok, value:%u\n", value); + mem_clear(buf_tmp, sizeof(buf_tmp)); + snprintf(buf_tmp, sizeof(buf_tmp), "%u\n", value); + buf_real_len = strlen(buf_tmp); + if (buf_len <= buf_real_len) { + DBG_DEBUG(DBG_ERROR, "length not enough.buf_len:%d,need length:%d\n", buf_len, buf_real_len); + return -DFD_RV_DEV_FAIL; + } + if (pfun) { + buf_real_len = buf_len; + rv = pfun(buf_tmp, strlen(buf_tmp), buf, &buf_real_len, info_ctrl, 1, 0); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "deal date error.org value:%s, buf_len:%d, rv=%d\n", + buf_tmp, buf_len, rv); + return -DFD_RV_DEV_NOTSUPPORT; + } + } else { + memcpy(buf, buf_tmp, buf_real_len); + } + return buf_real_len; + } else if (DFD_CFG_ITEM_ID(key) == DFD_CFG_ITEM_HWMON_TEMP && info_ctrl->src == INFO_SRC_CPLD) { + rv = dfd_info_get_cpld_temperature(key, &temp_value); + if (rv < 0) { + DBG_DEBUG(DBG_ERROR, "get cpld temperature failed.key=0x%08llx, rv:%d\n", key, rv); + return -DFD_RV_DEV_NOTSUPPORT; + } + DBG_DEBUG(DBG_VERBOSE, "get cpld temperature ok, value:%d buf_len %d\n", temp_value, buf_len); + mem_clear(buf_tmp, sizeof(buf_tmp)); + snprintf(buf_tmp, sizeof(buf_tmp), "%d\n", temp_value); + buf_real_len = strlen(buf_tmp); + if (buf_len <= buf_real_len) { + DBG_DEBUG(DBG_ERROR, "length not enough.buf_len:%d,need length:%d\n", buf_len, buf_real_len); + return -DFD_RV_DEV_FAIL; + } + DBG_DEBUG(DBG_VERBOSE, "buf_real_len %d\n", buf_real_len); + memcpy(buf, buf_tmp, buf_real_len); + return buf_real_len; + } + + DBG_DEBUG(DBG_ERROR, "not support mode. key:0x%08llx\n", key); + return -DFD_RV_MODE_NOTSUPPORT; +} + +/** + * dfd_info_get_sensor - Get sensors + * @key: HWMON Configures the key + * @buf:Result storage + * @buf_len: buf Length + * + * @returns: <0 Failure, other success + */ +int dfd_info_get_sensor(uint64_t key, char *buf, int buf_len, info_hwmon_buf_f pfun) +{ + info_ctrl_t *key_info_ctrl; + int rv; + + /* Entry check */ + if (!DFD_CFG_ITEM_IS_INFO_CTRL(DFD_CFG_ITEM_ID(key)) || + (buf == NULL) || buf_len <= 0) { + DBG_DEBUG(DBG_ERROR, "input arguments error, key: 0x%08llx, buf_len: %d\n", + key, buf_len); + return -DFD_RV_INVALID_VALUE; + } + mem_clear(buf, buf_len); + /* Get the configuration item read and write control variables */ + key_info_ctrl = dfd_ko_cfg_get_item(key); + if (key_info_ctrl == NULL) { + DBG_DEBUG(DBG_VERBOSE, "can't find dfd config, key: 0x%08llx\n", key); + return -DFD_RV_DEV_NOTSUPPORT; + } + /* String type */ + if (key_info_ctrl->mode == INFO_CTRL_MODE_SRT_CONS) { + snprintf(buf, buf_len, "%s\n", key_info_ctrl->str_cons); + DBG_DEBUG(DBG_VERBOSE, "get sensor value through string config, key: 0x%08llx, value: %s\n", key, buf); + return strlen(buf); + } + /* int constant type */ + if (key_info_ctrl->mode == INFO_CTRL_MODE_CONS) { + snprintf(buf, buf_len, "%d\n", key_info_ctrl->int_cons); + DBG_DEBUG(DBG_VERBOSE, "get sensor value through int config, key: 0x%08llx, value: %d\n", key, key_info_ctrl->int_cons); + return strlen(buf); + } + + /* Read from the hwmon file */ + if (key_info_ctrl->mode == INFO_CTRL_MODE_CFG && key_info_ctrl->src == INFO_SRC_FILE) { + if (strstr(key_info_ctrl->fpath, "hwmon") != NULL) { + DBG_DEBUG(DBG_VERBOSE, "get sensor value through hwmon, key: 0x%08llx\n", key); + rv = dfd_2key_info_get_buf(key_info_ctrl, buf, buf_len, pfun); + if (rv < 0) { + DBG_DEBUG(DBG_VERBOSE, "get sensor value through hwmon failed, key: 0x%08llx, rv: %d\n", key, rv); + } + return rv; + } else { + DBG_DEBUG(DBG_VERBOSE, "get sensor value, key:0x%08llx\n", key); + rv = dfd_info_get_buf(key, buf, buf_len, NULL); + if (rv < 0) { + DBG_DEBUG(DBG_VERBOSE, "get sensor value failed, key:0x%08llx, rv:%d\n", key, rv); + } + return rv; + } + } + rv = dfd_info_get_sensor_value(key, buf, buf_len, pfun); + if ( rv < 0) { + DBG_DEBUG(DBG_ERROR, "get sensor value failed, key: 0x%08llx, rv: %d\n", key, rv); + } + return rv; +} + +/** + * @buf:Input and result store + * + */ +void dfd_info_del_no_print_string(char *buf) +{ + int i, len; + + len = strlen(buf); + /* Culling noncharacter */ + for (i = 0; i < len; i++) { + if ((buf[i] < 0x21) || (buf[i] > 0x7E)) { + buf[i] = '\0'; + break; + } + } + return; +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg_listnode.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg_listnode.c new file mode 100644 index 000000000000..888cfe8b05f2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_cfg_listnode.c @@ -0,0 +1,133 @@ +/* + * An dfd_cfg_listnode driver for cfg of listnode devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include + +#include "dfd_cfg_listnode.h" + +/** + * Find node + * @root: Root node pointer + * @key: Node index value + * + * @return : Node data pointer, NULL failed + */ +void *lnode_find_node(lnode_root_t *root, uint64_t key) +{ + lnode_node_t *lnode; + + if (root == NULL) { + return NULL; + } + + /* Traversal query */ + list_for_each_entry(lnode, &(root->root), lst) { + if (lnode->key == key) { + return lnode->data; + } + } + + return NULL; +} + +/** + * Insert node + * @root: Root node pointer + * @key: Node index value + * @data: data + * + * @return : 0-- success, other failures + */ +int lnode_insert_node(lnode_root_t *root, uint64_t key, void *data) +{ + lnode_node_t *lnode; + void *data_tmp; + + if ((root == NULL) || (data == NULL)) { + return LNODE_RV_INPUT_ERR; + } + + /* Check whether the node exists */ + data_tmp = lnode_find_node(root, key); + if (data_tmp != NULL) { + return LNODE_RV_NODE_EXIST; + } + + /* Node memory request */ + lnode = kmalloc(sizeof(lnode_node_t), GFP_KERNEL); + if (lnode == NULL) { + return LNODE_RV_NOMEM; + } + + /* Add to list */ + lnode->key = key; + lnode->data = data; + list_add_tail(&(lnode->lst), &(root->root)); + + return LNODE_RV_OK; +} + +/** + * Example Initialize the root node + * @root: Root node pointer + * + * @return : 0 Succeeded, others failed + */ +int lnode_init_root(lnode_root_t *root) +{ + if (root == NULL) { + return LNODE_RV_INPUT_ERR; + } + + INIT_LIST_HEAD(&(root->root)); + + return LNODE_RV_OK; +} + +/** + * Free linked list + * @root: Root node pointer + * + * @return : void + */ +void lnode_free_list(lnode_root_t *root) +{ + lnode_node_t *lnode, *lnode_next; + + if (root == NULL) { + return; + } + + /* Iterate to delete the linked list */ + list_for_each_entry_safe(lnode, lnode_next, &(root->root), lst) { + if (lnode->data) { + kfree(lnode->data); + lnode->data = NULL; + lnode->key = 0; + } + list_del(&lnode->lst); + kfree(lnode); + lnode = NULL; + } + + return; + +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_frueeprom.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_frueeprom.c new file mode 100644 index 000000000000..ded8eb8a8db8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_frueeprom.c @@ -0,0 +1,534 @@ +/* + * An dfd_frueeprom driver for frueeprom devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include + +#include "dfd_frueeprom.h" +#include "dfd_cfg_adapter.h" +#include "wb_module.h" + +int g_dfd_fru_dbg_level = 0; +module_param(g_dfd_fru_dbg_level, int, S_IRUGO | S_IWUSR); + +/** + * Takes the pointer to stream of bytes and length + * and returns the 8 bit checksum + * This algo is per IPMI V2.0 spec + */ +static unsigned char ipmi_calculate_crc(const unsigned char *data, size_t len) +{ + char crc = 0; + size_t byte = 0; + + for (byte = 0; byte < len; byte++) { + crc += *data++; + } + + return(-crc); +} + +/* Validates the data for crc and mandatory fields */ +static int ipmi_verify_fru_data(const uint8_t *data, const size_t len) +{ + uint8_t checksum = 0; + int rc = -DFD_RV_TYPE_ERR; + + /* Validate for first byte to always have a value of [1] */ + if (data[0] != IPMI_FRU_HDR_BYTE_ZERO) { + DBG_FRU_DEBUG(DBG_ERROR, "Invalid entry:[%d] in byte-0\n",data[0]); + return rc; + } else { + DBG_FRU_DEBUG(DBG_VERBOSE, "SUCCESS: Validated [0x%X] in entry_1 of fru_data\n",data[0]); + } + + /* See if the calculated CRC matches with the embedded one. + * CRC to be calculated on all except the last one that is CRC itself.*/ + checksum = ipmi_calculate_crc(data, len - 1); + if (checksum != data[len-1]) { + DBG_FRU_DEBUG(DBG_ERROR, "Checksum mismatch." + " Calculated:[0x%X], Embedded:[0x%X]\n", + checksum, data[len - 1]); + return rc; + } else { + DBG_FRU_DEBUG(DBG_VERBOSE, "SUCCESS: Checksum matches:[0x%X]\n",checksum); + } + + return 0; +} + +/* private method to parse type/length */ +static int ipmi_parse_type_length (const void *areabuf, + unsigned int areabuflen, + unsigned int current_area_offset, + uint8_t *number_of_data_bytes, + ipmi_fru_field_t *field) +{ + const uint8_t *areabufptr = (const uint8_t*) areabuf; + uint8_t type_length; + uint8_t type_code; + + type_length = areabufptr[current_area_offset]; + + /* ipmi workaround + * + * dell p weredge r610 + * + * my reading of the fru spec is that all non-custom fields are + * required to be listed by the vendor. however, on this + * motherboard, some areas list this, indicating that there is + * no more data to be parsed. so now, for "required" fields, i + * check to see if the type-length field is a sentinel before + * calling this function. + */ + + type_code = (type_length & IPMI_FRU_TYPE_LENGTH_TYPE_CODE_MASK) >> IPMI_FRU_TYPE_LENGTH_TYPE_CODE_SHIFT; + (*number_of_data_bytes) = type_length & IPMI_FRU_TYPE_LENGTH_NUMBER_OF_DATA_BYTES_MASK; + + /* special case: this shouldn't be a length of 0x01 (see type/length + * byte format in fru information storage definition). + */ + DBG_FRU_DEBUG(DBG_VERBOSE, "areabuflen:%d, current_area_offset:0x%x, type_code:0x%x, number_of_data_bytes:%d\n", + areabuflen, current_area_offset, type_code, *number_of_data_bytes); +#if 0 + if (type_code == IPMI_FRU_TYPE_LENGTH_TYPE_CODE_LANGUAGE_CODE + && (*number_of_data_bytes) == 0x01) { + DBG_FRU_DEBUG(DBG_ERROR, "fru type length error.value:0x%x\n", type_length); + return (-1); + } +#endif + if ((current_area_offset + 1 + (*number_of_data_bytes)) > areabuflen) { + DBG_FRU_DEBUG(DBG_ERROR, "buf length error. current_area_offset:0x%x, need length:%d, total length:0x%x\n", + current_area_offset, *number_of_data_bytes, areabuflen); + return (-1); + } + + if (field) { + mem_clear (field->type_length_field, IPMI_FRU_AREA_TYPE_LENGTH_FIELD_MAX); + memcpy (field->type_length_field, &areabufptr[current_area_offset + 1], *number_of_data_bytes); + DBG_FRU_DEBUG(DBG_VERBOSE, "fru parse ok. value:%s\n", field->type_length_field); + field->type_length_field_length = *number_of_data_bytes; + } + + return (0); +} + +static int ipmi_fru_product_info_area(const void *areabuf, + unsigned int areabuflen, ipmi_product_info_t *ipmi_product_info) +{ + const uint8_t *areabufptr = (const uint8_t*) areabuf; + unsigned int area_offset = 2; + uint8_t number_of_data_bytes; + int rv; + ipmi_fru_field_t **ipmi_fru_field_point; + int ipmi_fru_field_len, i; + + if (!areabuf || !areabuflen || !ipmi_product_info) { + DBG_FRU_DEBUG(DBG_ERROR, "Invalid Parameter.\n"); + return -DFD_RV_INVALID_VALUE; + } + + /* Verify the crc and size */ + rv = ipmi_verify_fru_data(areabuf, areabuflen); + if (rv < 0) { + DBG_FRU_DEBUG(DBG_ERROR, "Failed to validate fru product info data\n"); + return rv; + } + + ipmi_fru_field_len = (sizeof(ipmi_product_info_t) - sizeof(uint8_t *)) /(sizeof(ipmi_fru_field_t *)); + + if (ipmi_product_info->language_code) { + (*ipmi_product_info->language_code) = areabufptr[area_offset]; + } + area_offset++; + ipmi_fru_field_point = (ipmi_fru_field_t **)((uint8_t *)ipmi_product_info + sizeof(uint8_t *)); + for (i = 0; i < ipmi_fru_field_len; i++) { + if (*ipmi_fru_field_point) { + mem_clear(*ipmi_fru_field_point, sizeof(ipmi_fru_field_t)); + } + + if (((areabufptr[area_offset] == IPMI_FRU_SENTINEL_VALUE) && (i >= IPMI_FRU_PRODUCT_AREA_MIN_LEN)) + || (area_offset == areabuflen - 1)) { + rv = 0; + break; + } + + rv = ipmi_parse_type_length(areabufptr, areabuflen, area_offset, &number_of_data_bytes, *ipmi_fru_field_point); + if (rv < 0) { + DBG_FRU_DEBUG(DBG_ERROR, "[%d] _parse_type_length area_offset[%d] rv=%d \n", i, area_offset, rv); + break; + } + + area_offset += 1; /* type/length byte */ + area_offset += number_of_data_bytes; + ipmi_fru_field_point++; + } + + return (rv); +} + +static int ipmi_fru_board_info_area(const void *areabuf, + unsigned int areabuflen, ipmi_board_info_t *ipmi_board_info) +{ + const uint8_t *areabufptr = (const uint8_t*) areabuf; + unsigned int area_offset = 2; + uint8_t number_of_data_bytes; + int rv; + ipmi_fru_field_t **ipmi_fru_field_point; + int ipmi_fru_field_len, i; + + if (!areabuf || !areabuflen || !ipmi_board_info) { + DBG_FRU_DEBUG(DBG_ERROR, "Invalid Parameter.\n"); + return -DFD_RV_INVALID_VALUE; + } + + /* Verify the crc and size */ + rv = ipmi_verify_fru_data(areabuf, areabuflen); + if (rv < 0) { + DBG_FRU_DEBUG(DBG_ERROR, "Failed to validate fru product info data\n"); + return rv; + } + + ipmi_fru_field_len = (sizeof(ipmi_board_info_t) - sizeof(uint8_t *) - sizeof(uint8_t *)) /(sizeof(ipmi_fru_field_t *)); + + if (ipmi_board_info->language_code) { + (*ipmi_board_info->language_code) = areabufptr[area_offset]; + } + area_offset++; + + if (ipmi_board_info->mfg_time) { + memcpy(ipmi_board_info->mfg_time, &areabufptr[area_offset], IPMI_FRU_BOARD_INFO_MFG_TIME_LENGTH); + } + area_offset += IPMI_FRU_BOARD_INFO_MFG_TIME_LENGTH; + ipmi_fru_field_point = (ipmi_fru_field_t **)((uint8_t *)ipmi_board_info + sizeof(uint8_t *) + sizeof(uint8_t *)); + for (i = 0; i < ipmi_fru_field_len; i++) { + if (*ipmi_fru_field_point) { + mem_clear(*ipmi_fru_field_point, sizeof(ipmi_fru_field_t)); + } + + if (((areabufptr[area_offset] == IPMI_FRU_SENTINEL_VALUE) && (i >= IPMI_FRU_BOARD_AREA_MIN_LEN)) + || (area_offset == areabuflen - 1)) { + rv = 0; + break; + } + + rv = ipmi_parse_type_length(areabufptr, areabuflen, area_offset, &number_of_data_bytes, *ipmi_fru_field_point); + if (rv < 0) { + DBG_FRU_DEBUG(DBG_ERROR, "[%d] _parse_type_length area_offset[%d] rv=%d \n", i, area_offset, rv); + break; + } + + area_offset += 1; /* type/length byte */ + area_offset += number_of_data_bytes; + ipmi_fru_field_point++; + } + + return (rv); +} + +/** + * Validates the fru data per ipmi common header constructs. + * Returns with updated common_hdr and also file_size + */ +static int ipmi_validate_common_hdr(const uint8_t *fru_data, const size_t data_len) +{ + int rc = -1; + + uint8_t common_hdr[sizeof(fru_common_header_t)] = {0}; + if (data_len >= sizeof(common_hdr)) { + memcpy(common_hdr, fru_data, sizeof(common_hdr)); + } else { + DBG_FRU_DEBUG(DBG_ERROR, "Incomplete fru data file. Size:[%zd]\n", data_len); + return rc; + } + + /* Verify the crc and size */ + rc = ipmi_verify_fru_data(common_hdr, sizeof(common_hdr)); + if (rc < 0) { + DBG_FRU_DEBUG(DBG_ERROR, "Failed to validate common header\n"); + return rc; + } + + return 0; +} + +/* Header information acquisition */ +static int dfd_get_frue2prom_info(int bus, int dev_addr, fru_common_header_t *info, const char *sysfs_name) +{ + int ret; + uint8_t fru_common_header_info[sizeof(fru_common_header_t)]; + + if (info == NULL) { + DBG_FRU_DEBUG(DBG_ERROR, "Invalid parameter!\n"); + return -DFD_RV_INVALID_VALUE; + } + + ret = dfd_ko_i2c_read(bus, dev_addr, 0, (uint8_t *)info, sizeof(fru_common_header_t), sysfs_name); + if (ret < 0) { + DBG_FRU_DEBUG(DBG_ERROR, "Read eeprom head info error(bus: %d, addr: 0x%02x).\n", bus, dev_addr); + return ret; + } + + memcpy(fru_common_header_info, (uint8_t *)info, sizeof(fru_common_header_t)); + + if (ipmi_validate_common_hdr(fru_common_header_info, sizeof(fru_common_header_t)) != 0) { + return -DFD_RV_TYPE_ERR; + } + + return DFD_RV_OK; +} + +static int dfd_set_fru_product_info(ipmi_product_info_t *ipmi_product_info, ipmi_fru_field_t *vpd_info, int type) +{ + int ret; + ret = DFD_RV_OK; + if (ipmi_product_info == NULL || vpd_info == NULL) { + DBG_FRU_DEBUG(DBG_ERROR, "Invalid parameter!\n"); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear((uint8_t *)ipmi_product_info, sizeof(ipmi_product_info_t)); + switch (type) { + case DFD_DEV_INFO_TYPE_SN: + ipmi_product_info->product_serial_number = vpd_info; + break; + case DFD_DEV_INFO_TYPE_NAME: + ipmi_product_info->product_name = vpd_info; + break; + case DFD_DEV_INFO_TYPE_DEV_TYPE: + ipmi_product_info->product_type_fields = vpd_info; + break; + case DFD_DEV_INFO_TYPE_HW_INFO: + ipmi_product_info->product_version = vpd_info; + break; + case DFD_DEV_INFO_TYPE_VENDOR: + ipmi_product_info->product_manufacturer_name = vpd_info; + break; + case DFD_DEV_INFO_TYPE_PART_NUMBER: + ipmi_product_info->product_part_model_number = vpd_info; + break; + case DFD_DEV_INFO_TYPE_ASSET_TAG: + ipmi_product_info->product_asset_tag = vpd_info; + break; + default: + ret = -1; + break; + } + + return ret; +} + +static int dfd_set_fru_board_info(ipmi_board_info_t *ipmi_board_info, ipmi_fru_field_t *vpd_info, int type) +{ + int ret; + ret = DFD_RV_OK; + if (ipmi_board_info == NULL || vpd_info == NULL) { + DBG_FRU_DEBUG(DBG_ERROR, "Invalid parameter!\n"); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear((uint8_t *)ipmi_board_info, sizeof(ipmi_board_info_t)); + switch (type) { + case DFD_DEV_INFO_TYPE_SN: + ipmi_board_info->board_serial_number = vpd_info; + break; + case DFD_DEV_INFO_TYPE_NAME: + ipmi_board_info->board_product_name = vpd_info; + break; + case DFD_DEV_INFO_TYPE_HW_INFO: + ipmi_board_info->board_custom_fields = vpd_info; + break; + case DFD_DEV_INFO_TYPE_PART_NUMBER: + ipmi_board_info->board_part_number = vpd_info; + break; + case DFD_DEV_INFO_TYPE_VENDOR: + ipmi_board_info->board_manufacturer = vpd_info; + break; + default: + ret = -1; + break; + } + + return ret; +} + +/** + * dfd_get_fru_data - Obtain product area FRU information + * @bus:FRU E2 bus number + * @dev_addr:FRU E2 Device address + * @type 2: Product name, 3: product serial number 5: hardware version number 6: product ID + * @buf: Data is stored in buf + * @buf_len:buf length + * @sysfs_name:sysfs attribute name + * @returns:0 success, negative value: failed + */ +int dfd_get_fru_data(int bus, int dev_addr, int type, uint8_t *buf, uint32_t buf_len, const char *sysfs_name) +{ + fru_common_header_t info; + uint8_t *fru_data; + int ret; + uint8_t fru_len; + ipmi_product_info_t ipmi_product_info; + ipmi_fru_field_t vpd_info; + int product_offset; + int fru_len_tmp; + + if (buf == NULL || buf_len <= 0) { + DBG_FRU_DEBUG(DBG_ERROR, "Invalid parameter!\n"); + return -DFD_RV_INVALID_VALUE; + } + + DBG_FRU_DEBUG(DBG_VERBOSE, "Read fru eeprom (bus: %d, addr: 0x%02x, type:%d, buf: %p, len: %d).\n", + bus, dev_addr, type, buf, buf_len); + + ret = dfd_get_frue2prom_info(bus, dev_addr, &info, sysfs_name); + if (ret < 0) { + DBG_FRU_DEBUG(DBG_ERROR, "Read eeprom info head error(bus: %d, addr: 0x%02x, buf: %p, len: %d).\n", + bus, dev_addr, buf, buf_len); + return ret; + } + + product_offset = info.product_offset * IPMI_EIGHT_BYTES; + ret = dfd_ko_i2c_read(bus, dev_addr, product_offset + 1, &fru_len, 1, sysfs_name); + if (ret < 0) { + DBG_FRU_DEBUG(DBG_ERROR, "read eeprom info product_offset(bus: %d, addr: 0x%02x, product offset:%d).\n", + bus, dev_addr, info.product_offset); + return -DFD_RV_DEV_FAIL; + } + + fru_len_tmp = fru_len * IPMI_EIGHT_BYTES; + fru_data = (uint8_t *)kmalloc(sizeof(uint8_t) * fru_len_tmp, GFP_KERNEL); + if (fru_data == NULL) { + DBG_FRU_DEBUG(DBG_ERROR, "Allocate buffer(len:%d) error!\n", fru_len_tmp); + return -DFD_RV_NO_MEMORY; + } + + ret = dfd_ko_i2c_read(bus, dev_addr, product_offset, fru_data, fru_len_tmp, sysfs_name); + if (ret < 0) { + DBG_FRU_DEBUG(DBG_ERROR, "Get FRU data error.\n"); + kfree(fru_data); + return ret; + } + + mem_clear((uint8_t *)&vpd_info, sizeof(ipmi_fru_field_t)); + ret = dfd_set_fru_product_info(&ipmi_product_info, &vpd_info, type); + if (ret < 0) { + DBG_FRU_DEBUG(DBG_ERROR, "Not support to get info: %d.\n", type); + kfree(fru_data); + return ret; + } + + ret = ipmi_fru_product_info_area(fru_data, fru_len_tmp, &ipmi_product_info); + if (ret < 0) { + DBG_FRU_DEBUG(DBG_ERROR, "analysis FRU product info error.\n"); + kfree(fru_data); + return ret; + } + + kfree(fru_data); + + buf_len = buf_len < vpd_info.type_length_field_length ? buf_len : vpd_info.type_length_field_length; + memcpy(buf, (uint8_t *)&vpd_info, buf_len); + + return DFD_RV_OK; +} + +/** + * dfd_get_fru_board_data - Obtain the FRU information of the board area + * @bus:FRU E2 bus number + * @dev_addr:FRU E2 Device address + * @type: 2: Product name, 3: product serial number 5: hardware version number + * @buf:Data is stored in buf + * @buf_len:buf length + * @sysfs_name:sysfs attribute name + * @returns: 0 success, negative value: failed + */ +int dfd_get_fru_board_data(int bus, int dev_addr, int type, uint8_t *buf, uint32_t buf_len, const char *sysfs_name) +{ + fru_common_header_t info; + uint8_t *fru_data; + int ret; + uint8_t fru_len; + ipmi_board_info_t ipmi_board_info; + ipmi_fru_field_t vpd_info; + int board_offset; + int fru_len_tmp; + + if (buf == NULL || buf_len <= 0) { + DBG_FRU_DEBUG(DBG_ERROR, "Invalid parameter!\n"); + return -DFD_RV_INVALID_VALUE; + } + + DBG_FRU_DEBUG(DBG_VERBOSE, "Read fru eeprom (bus: %d, addr: 0x%02x, type:%d, buf: %p, len: %d).\n", + bus, dev_addr, type, buf, buf_len); + + ret = dfd_get_frue2prom_info(bus, dev_addr, &info, sysfs_name); + if (ret < 0) { + DBG_FRU_DEBUG(DBG_ERROR, "Read eeprom info head error(bus: %d, addr: 0x%02x, buf: %p, len: %d).\n", + bus, dev_addr, buf, buf_len); + return ret; + } + + board_offset = info.board_offset * IPMI_EIGHT_BYTES; + ret = dfd_ko_i2c_read(bus, dev_addr, board_offset + 1, &fru_len, 1, sysfs_name); + if (ret < 0) { + DBG_FRU_DEBUG(DBG_ERROR, "read eeprom info product_offset(bus: %d, addr: 0x%02x, product offset:%d).\n", + bus, dev_addr, info.board_offset); + return -DFD_RV_DEV_FAIL; + } + + fru_len_tmp = fru_len * IPMI_EIGHT_BYTES; + fru_data = (uint8_t *)kmalloc(sizeof(uint8_t) * fru_len_tmp, GFP_KERNEL); + if (fru_data == NULL) { + DBG_FRU_DEBUG(DBG_ERROR, "Allocate buffer(len:%d) error!\n", fru_len_tmp); + return -DFD_RV_NO_MEMORY; + } + + ret = dfd_ko_i2c_read(bus, dev_addr, board_offset, fru_data, fru_len_tmp, sysfs_name); + if (ret < 0) { + DBG_FRU_DEBUG(DBG_ERROR, "Get FRU data error.\n"); + kfree(fru_data); + return ret; + } + + mem_clear((uint8_t *)&vpd_info, sizeof(ipmi_fru_field_t)); + ret = dfd_set_fru_board_info(&ipmi_board_info, &vpd_info, type); + if (ret < 0) { + DBG_FRU_DEBUG(DBG_ERROR, "Not support to get info: %d.\n", type); + kfree(fru_data); + return ret; + } + + ret = ipmi_fru_board_info_area(fru_data, fru_len_tmp, &ipmi_board_info); + if (ret < 0) { + DBG_FRU_DEBUG(DBG_ERROR, "analysis FRU product info error.\n"); + kfree(fru_data); + return ret; + } + + kfree(fru_data); + + buf_len = buf_len < vpd_info.type_length_field_length ? buf_len : vpd_info.type_length_field_length; + memcpy(buf, (uint8_t *)&vpd_info, buf_len); + + return DFD_RV_OK; +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_tlveeprom.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_tlveeprom.c new file mode 100644 index 000000000000..3011aa2cac04 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/cfg/dfd_tlveeprom.c @@ -0,0 +1,469 @@ +/* + * An dfd_tlveeprom driver for tlveeprom devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#include "dfd_tlveeprom.h" +#include "wb_module.h" + +#define TLV_CODE_PRODUCT_NAME (0x21) +#define TLV_CODE_PART_NUMBER (0x22) +#define TLV_CODE_SERIAL_NUMBER (0x23) +#define TLV_CODE_MAC_BASE (0x24) +#define TLV_CODE_MANUF_DATE (0x25) +#define TLV_CODE_DEVICE_VERSION (0x26) +#define TLV_CODE_LABEL_REVISION (0x27) +#define TLV_CODE_PLATFORM_NAME (0x28) +#define TLV_CODE_ONIE_VERSION (0x29) +#define TLV_CODE_MAC_SIZE (0x2A) +#define TLV_CODE_MANUF_NAME (0x2B) +#define TLV_CODE_MANUF_COUNTRY (0x2C) +#define TLV_CODE_VENDOR_NAME (0x2D) +#define TLV_CODE_DIAG_VERSION (0x2E) +#define TLV_CODE_SERVICE_TAG (0x2F) +#define TLV_CODE_VENDOR_EXT (0xFD) +#define TLV_CODE_CRC_32 (0xFE) + +/* using in is_valid_tlvinfo_header */ +static uint32_t g_eeprom_size; + +/* + * List of TLV codes and names. + */ +static const struct tlv_code_desc tlv_code_list[] = { + { TLV_CODE_PRODUCT_NAME, "Product Name"}, + { TLV_CODE_PART_NUMBER, "Part Number"}, + { TLV_CODE_SERIAL_NUMBER, "Serial Number"}, + { TLV_CODE_MAC_BASE, "Base MAC Address"}, + { TLV_CODE_MANUF_DATE, "Manufacture Date"}, + { TLV_CODE_DEVICE_VERSION, "Device Version"}, + { TLV_CODE_LABEL_REVISION, "Label Revision"}, + { TLV_CODE_PLATFORM_NAME, "Platform Name"}, + { TLV_CODE_ONIE_VERSION, "ONIE Version"}, + { TLV_CODE_MAC_SIZE, "MAC Addresses"}, + { TLV_CODE_MANUF_NAME, "Manufacturer"}, + { TLV_CODE_MANUF_COUNTRY, "Country Code"}, + { TLV_CODE_VENDOR_NAME, "Vendor Name"}, + { TLV_CODE_DIAG_VERSION, "Diag Version"}, + { TLV_CODE_SERVICE_TAG, "Service Tag"}, + { TLV_CODE_VENDOR_EXT, "Vendor Extension"}, + { TLV_CODE_CRC_32, "CRC-32"}, +}; + +#define TLV_CODE_NUM (sizeof(tlv_code_list) / sizeof(tlv_code_list[0])) + +const unsigned long g_crc_table[] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, +}; + +static unsigned long crc32(unsigned long crc, const unsigned char *buf, unsigned len) +{ + unsigned i; + if (len < 1) + return 0xffffffff; + + for (i = 0; i != len; ++i) { + crc = g_crc_table[(crc ^ buf[i]) & 0xff] ^ (crc >> 8); + } + + crc = crc ^ 0xffffffff; + + return crc; +} + +/* + * is_valid_tlv + * + * Perform basic sanity checks on a TLV field. The TLV is pointed to + * by the parameter provided. + * 1. The type code is not reserved (0x00 or 0xFF) + */ +static inline bool is_valid_tlv(tlvinfo_tlv_t *tlv) +{ + return ((tlv->type != 0x00) && (tlv->type != 0xFF)); +} + +/* + * is_valid_tlvinfo_header + * + * Perform sanity checks on the first 11 bytes of the TlvInfo EEPROM + * data pointed to by the parameter: + * 1. First 8 bytes contain null-terminated ASCII string "TlvInfo" + * 2. Version byte is 1 + * 3. Total length bytes contain value which is less than or equal + * to the allowed maximum (2048-11) + * + */ +static inline bool is_valid_tlvinfo_header(tlvinfo_header_t *hdr) +{ + int max_size = g_eeprom_size; + return((strcmp(hdr->signature, TLV_INFO_ID_STRING) == 0) && + (hdr->version == TLV_INFO_VERSION) && + (be16_to_cpu(hdr->totallen) <= max_size)); +} + +/* + * decode_tlv_value + * + * Decode a single TLV value into a string. + + * The validity of EEPROM contents and the TLV field have been verified + * prior to calling this function. + */ +static void decode_tlv_value(tlvinfo_tlv_t *tlv, tlv_decode_value_t *decode_value) +{ + int i; + char *value; + uint32_t length; + + value = (char *)decode_value->value; + + switch (tlv->type) { + case TLV_CODE_PRODUCT_NAME: + case TLV_CODE_PART_NUMBER: + case TLV_CODE_SERIAL_NUMBER: + case TLV_CODE_MANUF_DATE: + case TLV_CODE_LABEL_REVISION: + case TLV_CODE_PLATFORM_NAME: + case TLV_CODE_ONIE_VERSION: + case TLV_CODE_MANUF_NAME: + case TLV_CODE_MANUF_COUNTRY: + case TLV_CODE_VENDOR_NAME: + case TLV_CODE_DIAG_VERSION: + case TLV_CODE_SERVICE_TAG: + memcpy(value, tlv->value, tlv->length); + value[tlv->length] = 0; + length = tlv->length; + break; + case TLV_CODE_MAC_BASE: + length = sprintf(value, "%02X:%02X:%02X:%02X:%02X:%02X", + tlv->value[0], tlv->value[1], tlv->value[2], + tlv->value[3], tlv->value[4], tlv->value[5]); + break; + case TLV_CODE_DEVICE_VERSION: + length = sprintf(value, "%u", tlv->value[0]); + break; + case TLV_CODE_MAC_SIZE: + length = sprintf(value, "%u", (tlv->value[0] << 8) | tlv->value[1]); + break; + case TLV_CODE_VENDOR_EXT: + value[0] = 0; + length = 0; + for (i = 0; (i < (TLV_DECODE_VALUE_MAX_LEN/5)) && (i < tlv->length); i++) { + length += sprintf(value, "%s %02X", value, tlv->value[i]); + } + break; + case TLV_CODE_CRC_32: + length = sprintf(value, "0x%02X%02X%02X%02X", tlv->value[0], + tlv->value[1], tlv->value[2], tlv->value[3]); + break; + default: + value[0] = 0; + length = 0; + for (i = 0; (i < (TLV_DECODE_VALUE_MAX_LEN/5)) && (i < tlv->length); i++) { + length += sprintf(value, "%s 0x%02X", value, tlv->value[i]); + } + break; + } + + decode_value->length = length; +} + +/* + * is_checksum_valid + * + * Validate the checksum in the provided TlvInfo EEPROM data. First, + * verify that the TlvInfo header is valid, then make sure the last + * TLV is a CRC-32 TLV. Then calculate the CRC over the EEPROM data + * and compare it to the value stored in the EEPROM CRC-32 TLV. + */ +static bool is_checksum_valid(uint8_t *eeprom) +{ + tlvinfo_header_t *eeprom_hdr; + tlvinfo_tlv_t *eeprom_crc; + unsigned int calc_crc; + unsigned int stored_crc; + + eeprom_hdr = (tlvinfo_header_t *) eeprom; + + /* Is the eeprom header valid? */ + if (!is_valid_tlvinfo_header(eeprom_hdr)) { + return false; + } + + /* Is the last TLV a CRC? */ + eeprom_crc = (tlvinfo_tlv_t *) &eeprom[sizeof(tlvinfo_header_t) + + be16_to_cpu(eeprom_hdr->totallen) - (sizeof(tlvinfo_tlv_t) + 4)]; + if ((eeprom_crc->type != TLV_CODE_CRC_32) || (eeprom_crc->length != 4)) { + return false; + } + + /* Calculate the checksum */ + calc_crc = crc32(0xffffffffL, (const unsigned char *)eeprom, sizeof(tlvinfo_header_t) + + be16_to_cpu(eeprom_hdr->totallen) - 4); + stored_crc = ((eeprom_crc->value[0] << 24) | (eeprom_crc->value[1] << 16) | + (eeprom_crc->value[2] << 8) | eeprom_crc->value[3]); + + return (calc_crc == stored_crc); +} + +/* + * tlvinfo_find_tlv + * + * This function finds the TLV with the supplied code in the EERPOM. + * An offset from the beginning of the EEPROM is returned in the + * eeprom_index parameter if the TLV is found. + */ +static bool tlvinfo_find_tlv(uint8_t *eeprom, uint8_t tcode, int *eeprom_index) +{ + tlvinfo_header_t *eeprom_hdr; + tlvinfo_tlv_t *eeprom_tlv; + int eeprom_end; + + eeprom_hdr = (tlvinfo_header_t *) eeprom; + + /* Search through the TLVs, looking for the first one which matches the + * supplied type code. */ + *eeprom_index = sizeof(tlvinfo_header_t); + eeprom_end = sizeof(tlvinfo_header_t) + be16_to_cpu(eeprom_hdr->totallen); + while (*eeprom_index < eeprom_end) { + eeprom_tlv = (tlvinfo_tlv_t *) &eeprom[*eeprom_index]; + if (!is_valid_tlv(eeprom_tlv)) { + return false; + } + + if (eeprom_tlv->type == tcode) { + return true; + } + + *eeprom_index += sizeof(tlvinfo_tlv_t) + eeprom_tlv->length; + } + + return false; +} + +/* + * tlvinfo_decode_tlv + * + * This function finds the TLV with the supplied code in the EERPOM + * and decodes the value into the buffer provided. + */ +static bool tlvinfo_decode_tlv(uint8_t *eeprom, uint8_t tcode, tlv_decode_value_t *decode_value) +{ + int eeprom_index; + tlvinfo_tlv_t *eeprom_tlv; + + /* Find the TLV and then decode it */ + if (tlvinfo_find_tlv(eeprom, tcode, &eeprom_index)) { + eeprom_tlv = (tlvinfo_tlv_t *) &eeprom[eeprom_index]; + decode_tlv_value(eeprom_tlv, decode_value); + return true; + } + + return false; +} + +/* + * parse_tlv_eeprom + * + * parse the EEPROM into memory, if it hasn't already been read. + */ +int parse_tlv_eeprom(uint8_t *eeprom, uint32_t size) +{ + unsigned int i; + bool ret; + tlvinfo_header_t *eeprom_hdr; + tlv_decode_value_t decode_value; + int j; + + eeprom_hdr = (tlvinfo_header_t *) eeprom; + g_eeprom_size = size; /* eeprom real size */ + + if (!is_valid_tlvinfo_header(eeprom_hdr)) { + DBG_DEBUG(DBG_ERROR, "Failed to check tlv header.\n"); + return -1; + } + + if (!is_checksum_valid(eeprom)) { + DBG_DEBUG(DBG_ERROR, "Failed to check tlv crc.\n"); + return -1; + } + + for (i = 0; i < TLV_CODE_NUM; i++) { + mem_clear((void *)&decode_value, sizeof(tlv_decode_value_t)); + ret = tlvinfo_decode_tlv(eeprom, tlv_code_list[i].m_code, &decode_value); + if (!ret) { + DBG_DEBUG(DBG_ERROR, "No found type: %s\n", tlv_code_list[i].m_name); + continue; + } + + DBG_DEBUG(DBG_VERBOSE, "i: %d,Found type: %s tlv[%d]:%s\n", i, tlv_code_list[i].m_name, tlv_code_list[i].m_code, + decode_value.value); + for (j = 0; j < decode_value.length; j++) { + if ((j % 16) == 0) { + DBG_DEBUG(DBG_VERBOSE, "\n"); + } + DBG_DEBUG(DBG_VERBOSE, "%02x ", decode_value.value[j]); + } + DBG_DEBUG(DBG_VERBOSE, "\n\n"); + } + return 0; +} +static int dfd_parse_tlv_eeprom(uint8_t *eeprom, uint32_t size, uint8_t main_type, tlv_decode_value_t *decode_value) +{ + bool ret; + tlvinfo_header_t *eeprom_hdr; + int j; + + eeprom_hdr = (tlvinfo_header_t *) eeprom; + g_eeprom_size = size; /* eeprom real size */ + + if (!is_valid_tlvinfo_header(eeprom_hdr)) { + DBG_DEBUG(DBG_ERROR, "Failed to check tlv header.\n"); + return -1; + } + + if (!is_checksum_valid(eeprom)) { + DBG_DEBUG(DBG_ERROR, "Failed to check tlv crc.\n"); + return -1; + } + + ret = tlvinfo_decode_tlv(eeprom, main_type, decode_value); + if (!ret) { + DBG_DEBUG(DBG_ERROR, "No found type: %d\n", main_type); + return -1; + } + + DBG_DEBUG(DBG_VERBOSE, "Found type: %d, value: %s\n", main_type,decode_value->value); + for (j = 0; j < decode_value->length; j++) { + if ((j % 16) == 0) { + DBG_DEBUG(DBG_VERBOSE, "\n"); + } + DBG_DEBUG(DBG_VERBOSE, "%02x ", decode_value->value[j]); + } + DBG_DEBUG(DBG_VERBOSE, "\n\n"); + + return 0; +} +#if 0 +/* Parsing extends the custom TLV format */ +static int tlvinfo_find_wb_ext_tlv(tlv_decode_value_t *ext_tlv_value, uint8_t ext_type, + uint8_t *buf, uint32_t *buf_len) +{ + tlvinfo_tlv_t *eeprom_tlv; + int eeprom_end, eeprom_index; + + /* Search through the TLVs, looking for the first one which matches the + * supplied type code.*/ + DBG_DEBUG(DBG_VERBOSE, "ext_tlv_value->length: %d.\n", ext_tlv_value->length); + for (eeprom_index = 0; eeprom_index < ext_tlv_value->length; eeprom_index++) { + if ((eeprom_index % 16) == 0) { + DBG_DEBUG(DBG_VERBOSE, "\n"); + } + DBG_DEBUG(DBG_VERBOSE, "%02x ", ext_tlv_value->value[eeprom_index]); + } + + DBG_DEBUG(DBG_VERBOSE, "\n"); + + eeprom_index = 0; + eeprom_end = ext_tlv_value->length; + while (eeprom_index < eeprom_end) { + eeprom_tlv = (tlvinfo_tlv_t *) &(ext_tlv_value->value[eeprom_index]); + if (!is_valid_tlv(eeprom_tlv)) { + DBG_DEBUG(DBG_ERROR, "tlv is not valid, eeprom_tlv->type 0x%x.\n", eeprom_tlv->type); + return -1; + } + + DBG_DEBUG(DBG_VERBOSE, "eeprom_tlv->length %d.\n", eeprom_tlv->length); + if (eeprom_tlv->type == ext_type) { + if (*buf_len >= eeprom_tlv->length) { + memcpy(buf, eeprom_tlv->value, eeprom_tlv->length); + DBG_DEBUG(DBG_VERBOSE, "eeprom_tlv->length %d.\n", eeprom_tlv->length); + *buf_len = eeprom_tlv->length; + return 0; + } + DBG_DEBUG(DBG_VERBOSE, "buf_len %d small than info_len %d.\n", *buf_len, eeprom_tlv->length); + return -1; + } + + eeprom_index += sizeof(tlvinfo_tlv_t) + eeprom_tlv->length; + } + + DBG_DEBUG(DBG_VERBOSE, "ext_type %d: tlv is not found.\n", ext_type); + return -1; +} +#endif +/* Obtain EEPROM information */ +int dfd_tlvinfo_get_e2prom_info(uint8_t *eeprom, uint32_t size, dfd_tlv_type_t *tlv_type, uint8_t* buf, uint32_t *buf_len) +{ + tlv_decode_value_t decode_value; + int ret; + + if (eeprom == NULL || tlv_type == NULL || buf == NULL) { + DBG_DEBUG(DBG_ERROR, "Input para invalid.\n"); + return -1; + } + + mem_clear((void *)&decode_value, sizeof(tlv_decode_value_t)); + ret = dfd_parse_tlv_eeprom(eeprom, size, tlv_type->main_type, &decode_value); + if (ret) { + DBG_DEBUG(DBG_ERROR, "dfd_parse_tlv_eeprom failed ret %d.\n", ret); + return ret; + } + + if (*buf_len >= decode_value.length) { + memcpy(buf, decode_value.value, decode_value.length); + *buf_len = decode_value.length; + return 0; + } + DBG_DEBUG(DBG_ERROR, "buf_len %d small than info_len %d.\n", *buf_len, decode_value.length); + return -1; +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_cfg.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_cfg.h new file mode 100644 index 000000000000..1cc8143d1f30 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_cfg.h @@ -0,0 +1,247 @@ +/* + * A header definition for dfd_cfg driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __DFD_CFG_H__ +#define __DFD_CFG_H__ + +#include + +#define DFD_KO_FILE_NAME_DIR "/etc/s3ip_sysfs_cfg/file_name/" /* Library configuration file name directory */ +#define DFD_KO_CFG_FILE_DIR "/etc/s3ip_sysfs_cfg/cfg_file/" /* Library configuration file directory */ +#define DFD_PUB_CARDTYPE_FILE "/sys/module/platform_common/parameters/dfd_my_type" + +#define DFD_CFG_CMDLINE_MAX_LEN (256) /* The maximum length of the command line is specified */ +#define DFD_CFG_NAME_MAX_LEN (256) /* The maximum length of a name is specified */ +#define DFD_CFG_VALUE_MAX_LEN (256) /* The maximum length of the configuration value */ +#define DFD_CFG_STR_MAX_LEN (64) /* The maximum length of a character string is specified */ +#define DFD_CFG_CPLD_NUM_MAX (16) /* Maximum number of cpld */ +#define DFD_PRODUCT_ID_LENGTH (8) +#define DFD_PID_BUF_LEN (32) +#define DFD_TEMP_NAME_BUF_LEN (32) + +#define DFD_CFG_EMPTY_VALUE (-1) /* Null configuration value */ +#define DFD_CFG_INVALID_VALUE (0) /* Configuring an illegal value */ + +/* Set the key value of the binary tree */ +#define DFD_CFG_KEY(item, index1, index2) \ + (((((uint64_t)item) & 0xffff) << 24) | (((index1) & 0xffff) << 8) | ((index2) & 0xff)) +#define DFD_CFG_ITEM_ID(key) (((key) >> 24) & 0xffff) +#define DFD_CFG_INDEX1(key) (((key) >> 8) & 0xffff) +#define DFD_CFG_INDEX2(key) ((key)& 0xff) + +/* Index range */ +#define INDEX_NOT_EXIST (-1) +#define INDEX1_MAX (0xffff) +#define INDEX2_MAX (0xff) + +#define DFD_CFG_ITEM_ALL \ + DFD_CFG_ITEM(DFD_CFG_ITEM_NONE, "none", INDEX_NOT_EXIST, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_DEV_NUM, "dev_num", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_BMC_SYSTEM_CMD_NUM, "bmc_system_cmd_num", INDEX1_MAX, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_FAN_THRESHOLD, "fan_threshold", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_LED_STATUS_DECODE, "led_status_decode", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_SYSTEM_STATUS_DECODE, "system_status_decode", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_CPLD_LPC_DEV, "cpld_lpc_dev", INDEX1_MAX, DFD_CFG_CPLD_NUM_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_FAN_TYPE_NUM, "fan_type_num", INDEX1_MAX, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_EEPROM_SIZE, "eeprom_size", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_DECODE_POWER_FAN_DIR, "decode_power_fan_dir", INDEX1_MAX, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_WATCHDOG_ID, "watchdog_id", INDEX1_MAX, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_POWER_RSUPPLY, "power_rate_supply", INDEX1_MAX, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_FAN_DIRECTION, "fan_direction", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_HWMON_TEMP_MONITOR_DC, "dc_monitor_flag_hwmon_temp", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_HWMON_IN_MONITOR_FLAG_DC, "dc_monitor_flag_hwmon_in", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_HWMON_CURR_MONITOR_FLAG_DC, "dc_monitor_flag_hwmon_curr", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_INT_END, "end_int", INDEX_NOT_EXIST, INDEX_NOT_EXIST) \ + \ + DFD_CFG_ITEM(DFD_CFG_ITEM_CPLD_MODE, "mode_cpld", INDEX1_MAX, DFD_CFG_CPLD_NUM_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_CPLD_NAME, "cpld_name", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_CPLD_TYPE, "cpld_type", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_FPGA_NAME, "fpga_name", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_FPGA_TYPE, "fpga_type", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_FPGA_MODEL_DECODE, "fpga_model_decode", INDEX1_MAX, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_FAN_E2_MODE, "fan_e2_mode", INDEX_NOT_EXIST, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_PSU_FRU_MODE, "psu_fru_mode", INDEX_NOT_EXIST, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_FAN_SYSFS_NAME, "fan_sysfs_name", INDEX_NOT_EXIST, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_POWER_NAME, "power_name", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_FAN_NAME, "fan_name", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_DECODE_POWER_NAME, "decode_power_name", INDEX1_MAX, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_FAN_SPEED_CAL, "fan_speed_cal", INDEX1_MAX, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_DECODE_FAN_NAME, "decode_fan_name", INDEX1_MAX, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_EEPROM_PATH, "eeprom_path", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_WATCHDOG_NAME, "watchdog_name", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_PSU_SYSFS_NAME, "psu_sysfs_name", INDEX_NOT_EXIST, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_SLOT_SYSFS_NAME, "slot_sysfs_name", INDEX_NOT_EXIST, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_EEPROM_ALIAS, "eeprom_alias", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_EEPROM_TAG, "eeprom_tag", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_EEPROM_TYPE, "eeprom_type", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_PSU_BLACKBOX_INFO, "psu_blackbox_info", INDEX1_MAX, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_PSU_PMBUS_INFO, "psu_pmbus_info", INDEX1_MAX, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_PSU_CLEAR_BLACKBOX, "psu_clear_blackbox", INDEX1_MAX, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_STRING_END, "end_string", INDEX_NOT_EXIST, INDEX_NOT_EXIST) \ + \ + DFD_CFG_ITEM(DFD_CFG_ITEM_CPLD_I2C_DEV, "cpld_i2c_dev", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_OTHER_I2C_DEV, "other_i2c_dev", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_I2C_DEV_END, "end_i2c_dev", INDEX_NOT_EXIST, INDEX_NOT_EXIST) \ + \ + DFD_CFG_ITEM(DFD_CFG_ITEM_FAN_ROLL_STATUS, "fan_roll_status", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_FAN_SPEED, "fan_speed", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_FAN_RATIO, "fan_ratio", INDEX1_MAX, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_LED_STATUS, "led_status", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_CPLD_VERSION, "cpld_version", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_CPLD_HW_VERSION, "cpld_hw_version", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_CPLD_TEST_REG, "cpld_test_reg", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_DEV_PRESENT_STATUS, "dev_present_status", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_PSU_STATUS, "psu_status", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_HWMON_TEMP, "hwmon_temp", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_HWMON_TEMP_MONITOR_FLAG, "monitor_flag_hwmon_temp", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_HWMON_IN, "hwmon_in", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_HWMON_IN_MONITOR_FLAG, "monitor_flag_hwmon_in", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_HWMON_CURR, "hwmon_curr", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_HWMON_CURR_MONITOR_FLAG, "monitor_flag_hwmon_curr", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_HWMON_PSU, "hwmon_psu", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_SFF_OPTOE_TYPE, "sff_optoe_type", INDEX1_MAX, INDEX_NOT_EXIST) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_HWMON_POWER, "hwmon_power", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_SFF_CPLD_REG, "sff_cpld_reg", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_FPGA_VERSION, "fpga_version", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_FPGA_TEST_REG, "fpga_test_reg", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_FPGA_MODEL_REG, "fpga_model_reg", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_PSU_PMBUS_REG, "psu_pmbus_reg", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_WATCHDOG_DEV, "watchdog_dev", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_BMC_SYSTEM, "bmc_system", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_PRE_CHECK_BMC_SYSTEM, "pre_check_bmc_system", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_CHECK_VAL_BMC_SYSTEM, "check_val_bmc_system", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_PSU_FRU_PMBUS, "psu_fru_pmbus", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_POWER_STATUS, "power_status", INDEX1_MAX, INDEX2_MAX) \ + DFD_CFG_ITEM(DFD_CFG_ITEM_INFO_CTRL_END, "end_info_ctrl", INDEX_NOT_EXIST, INDEX_NOT_EXIST) \ + +/* Configuration item id enumeration definition */ +#ifdef DFD_CFG_ITEM +#undef DFD_CFG_ITEM +#endif +#define DFD_CFG_ITEM(_id, _name, _index_min, _index_max) _id, +typedef enum dfd_cfg_item_id_s { + DFD_CFG_ITEM_ALL +} dfd_cfg_item_id_t; + +#define DFD_CFG_ITEM_IS_INT(item_id) \ + (((item_id) > DFD_CFG_ITEM_NONE) && ((item_id) < DFD_CFG_ITEM_INT_END)) + +#define DFD_CFG_ITEM_IS_STRING(item_id) \ + (((item_id) > DFD_CFG_ITEM_INT_END) && ((item_id) < DFD_CFG_ITEM_STRING_END)) + +#define DFD_CFG_ITEM_IS_I2C_DEV(item_id) \ + (((item_id) > DFD_CFG_ITEM_STRING_END) && ((item_id) < DFD_CFG_ITEM_I2C_DEV_END)) + +#define DFD_CFG_ITEM_IS_INFO_CTRL(item_id) \ + (((item_id) > DFD_CFG_ITEM_I2C_DEV_END) && ((item_id) < DFD_CFG_ITEM_INFO_CTRL_END)) + +/* Index value range structure */ +typedef struct index_range_s { + int index1_max; /* The primary index indicates the maximum value */ + int index2_max; /* Indicates the maximum value of the secondary index */ +} index_range_t; + +/* Register value conversion node */ +typedef struct val_convert_node_s { + struct list_head lst; + int int_val; /* Integer value */ + char str_val[DFD_CFG_STR_MAX_LEN]; /* String value */ + int index1; /* Index value 1 */ + int index2; /* Index value 2 */ +} val_convert_node_t; + +/** + * dfd_ko_cfg_get_item - Get configuration item + * @key: Node key + * + * @returns: The NULL configuration item does not exist, and other configuration items are successful + */ +void *dfd_ko_cfg_get_item(uint64_t key); + +/** + * dfd_ko_cfg_show_item - Display configuration items + * @key: Node key + */ +void dfd_ko_cfg_show_item(uint64_t key); + +/** + * dfd_dev_cfg_init - Module initialization + * + * @returns: <0 Failed, otherwise succeeded + */ +int32_t dfd_dev_cfg_init(void); + +/** + * dfd_dev_cfg_exit - Module exit + * + * @returns: void + */ +void dfd_dev_cfg_exit(void); + +/* Strip out Spaces and carriage returns */ +void dfd_ko_cfg_del_space_lf_cr(char *str); + +void dfd_ko_cfg_del_lf_cr(char *str); + +/** + * dfd_ko_cfg_get_fan_direction_by_name - obtain the air duct type by fan name + * @fan_name: Fan name + * @fan_direction: Duct type + * + * @returns: 0 Succeeded, otherwise failed + */ +int dfd_ko_cfg_get_fan_direction_by_name(char *fan_name, int *fan_direction); + +/** + * dfd_ko_cfg_get_power_type_by_name - obtain the power supply type by power supply name + * @power_name: Power supply name + * @power_type: Power supply type + * @returns: 0 Succeeded, otherwise failed + */ +int dfd_ko_cfg_get_power_type_by_name(char *power_name, int *power_type); + +/** + * dfd_ko_cfg_get_led_status_decode2_by_regval - Reverse check the register value of the led status + * @regval: Defined led values + * @index1: led type + * @value: Gets the register value of the led status + * @returns: 0 Succeeded, otherwise failed + */ +int dfd_ko_cfg_get_led_status_decode2_by_regval(int regval, int index1, int *value); + +/** + * dfd_ko_cfg_get_fan_direction_by_name - obtain the fan type by fan name + * @fan_name: Fan name + * @fan_type: Fan type + * @sub_type: Fan sub-type + * + * @returns: 0 Succeeded, otherwise failed + */ + int dfd_ko_cfg_get_fan_type_by_name(char *fan_name, int *fan_type, int *sub_type); + + /** + * key_to_name - convert to name by key + * @key: Fan name + * + * @returns: name + */ +char *key_to_name(uint64_t key); + +#endif /* __DFD_CFG_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_cfg_adapter.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_cfg_adapter.h new file mode 100644 index 000000000000..f70c46328e58 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_cfg_adapter.h @@ -0,0 +1,136 @@ +/* + * A header definition for dfd_cfg_adapter driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __DFD_CFG_ADAPTER_H__ +#define __DFD_CFG_ADAPTER_H__ + +#define DFD_KO_CPLD_I2C_RETRY_SLEEP (10) /* ms */ +#define DFD_KO_CPLD_I2C_RETRY_TIMES (50 / DFD_KO_CPLD_I2C_RETRY_SLEEP) + +#define DFD_KO_CPLD_GET_SLOT(addr) ((addr >> 24) & 0xff) +#define DFD_KO_CPLD_GET_ID(addr) ((addr >> 16) & 0xff) +#define DFD_KO_CPLD_GET_INDEX(addr) (addr & 0xffff) +#define DFD_KO_CPLD_MODE_I2C_STRING "i2c" +#define DFD_KO_CPLD_MODE_LPC_STRING "lpc" + +#define DFD_KO_OTHER_I2C_GET_MAIN_ID(addr) ((addr >> 24) & 0xff) +#define DFD_KO_OTHER_I2C_GET_INDEX(addr) ((addr >> 16) & 0xff) +#define DFD_KO_OTHER_I2C_GET_OFFSET(addr) (addr & 0xffff) +#define DFD_SYSFS_PATH_MAX_LEN (64) + +typedef struct dfd_i2c_dev_s { + int bus; /* bus number */ + int addr; /* Bus address */ +} dfd_i2c_dev_t; + +/* dfd_i2c_dev_t member macro */ +typedef enum dfd_i2c_dev_mem_s { + DFD_I2C_DEV_MEM_BUS, + DFD_I2C_DEV_MEM_ADDR, + DFD_I2C_DEV_MEM_END +} dfd_i2c_dev_mem_t; + +typedef enum cpld_mode_e { + DFD_CPLD_MODE_I2C, /* I2C bus */ + DFD_CPLD_MODE_LPC, /*LPC bus*/ +} cpld_mode_t; + +/* i2c access mode */ +typedef enum i2c_mode_e { + DFD_I2C_MODE_NORMAL_I2C, /* I2C bus */ + DFD_I2C_MODE_SMBUS, /* SMBUS bus */ +} i2c_mode_t; + +/* Global variable */ +extern char *g_dfd_i2c_dev_mem_str[DFD_I2C_DEV_MEM_END]; /* dfd_i2c_dev_t member string */ + +/** + * dfd_ko_cpld_read - cpld read operation + * @addr: Offset address + * @buf: data + * + * @returns: <0 Failed, others succeeded + */ +int32_t dfd_ko_cpld_read(int32_t addr, uint8_t *buf); + +/** + * dfd_ko_cpld_write - cpld write operation + * @addr: address + * @data: data + * + * @returns: <0 Failed, others succeeded + */ +int32_t dfd_ko_cpld_write(int32_t addr, uint8_t val); + +/** + * dfd_ko_i2c_read - I2C read operation + * @bus: I2C bus + * @addr: I2C device address + * @offset:register offset + * @buf:Read buffer + * @size:Read length + * @sysfs_name:sysfs attribute name + * @returns: <0 Failed, others succeeded + */ +int32_t dfd_ko_i2c_read(int bus, int addr, int offset, uint8_t *buf, uint32_t size, const char *sysfs_name); + +/** + * dfd_ko_i2c_write - I2C write operation + * @bus: I2C bus + * @addr: I2C device address + * @offset:register offset + * @buf:write buffer + * @size: write length + * @returns: <0 Failed, others succeeded + */ +int32_t dfd_ko_i2c_write(int bus, int addr, int offset, uint8_t *buf, uint32_t size); + +/** + * dfd_ko_read_file - File read operation + * @fpath: File path + * @addr: address + * @val: data + * @read_bytes: length + * + * @returns: <0 Failed, others succeeded + */ +int32_t dfd_ko_read_file(char *fpath, int32_t addr, uint8_t *val, int32_t read_bytes); + +/** + * dfd_ko_write_file - File write operation + * @fpath: File path + * @addr: address + * @val: data + * @write_bytes: length + * + * @returns: <0 Failed, others succeeded + */ +int32_t dfd_ko_write_file(char *fpath, int32_t addr, uint8_t *val, int32_t write_bytes); + +/** + * dfd_ko_other_i2c_dev_read - other_i2c read operation + * @addr: address + * @val: data + * @read_len: length + * + * @returns: <0 Failed, others succeeded + */ +int32_t dfd_ko_other_i2c_dev_read(int32_t addr, uint8_t *value, int32_t read_len); +#endif /* __DFD_CFG_ADAPTER_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_cfg_file.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_cfg_file.h new file mode 100644 index 000000000000..4eba8aabbd49 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_cfg_file.h @@ -0,0 +1,101 @@ +/* + * A header definition for dfd_cfg_file driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __DFD_CFG_FILE_H__ +#define __DFD_CFG_FILE_H__ + +#include + +/* Returned value */ +#define KFILE_RV_OK (0) +#define KFILE_RV_INPUT_ERR (-1) /* Entry error */ +#define KFILE_RV_STAT_FAIL (-2) /* Failed to obtain file properties. Procedure */ +#define KFILE_RV_OPEN_FAIL (-3) /* Failed to open file */ +#define KFILE_RV_MALLOC_FAIL (-4) /* Failed to allocate memory */ +#define KFILE_RV_RD_FAIL (-5) /* Read failure */ +#define KFILE_RV_ADDR_ERR (-6) /* Address error */ +#define KFILE_RV_WR_FAIL (-7) /* Address error */ + +/* Whether it is a newline character */ +#define IS_CR(c) ((c) == '\n') + +/* File operation control structure */ +typedef struct kfile_ctrl_s { + int32_t size; /* File size */ + int32_t pos; /* Current position */ + char *buf; /* File cache */ +} kfile_ctrl_t; + +/* + * Open file + * @fname: filename + * @kfile_ctrl: File control variable + * + * @returns: 0 Succeeded, others failed + */ +int kfile_open(char *fname, kfile_ctrl_t *kfile_ctrl); + +/* + * Close file + * @kfile_ctrl: File control variable + */ +void kfile_close(kfile_ctrl_t *kfile_ctrl); + +/* + * Close file + * @kfile_ctrl: File control variable + * + * @returns: >=0 Succeeded. Others failed + */ +int kfile_gets(char *buf, int buf_size, kfile_ctrl_t *kfile_ctrl); + +/* + * Read data + * @buf: buf Buffer area + * @buf_size: buf size + * @kfile_ctrl: File control variable + * + * @returns: >=0 Succeeded. Others failed + */ +int kfile_read(int32_t addr, char *buf, int buf_size, kfile_ctrl_t *kfile_ctrl); + +/* + * Read data + * @buf: buf Buffer area + * @buf_size: buf size + * @kfile_ctrl: File control variable + * + * @returns: >=0 Succeeded. Others failed + */ +int kfile_iterate_dir(const char *dir_path, const char *obj_name, char *match_name, int len); + +#if 0 +/* + * Write data + * @fname: filename + * @addr: Offset address of the file written to + * @buf: Write data + * @buf_size: Data size + * + * @returns: >=0 Succeeded. Others failed + */ +int kfile_write(char *fpath, int32_t addr, char *buf, int buf_size); +#endif +#endif /* __DFD_CFG_FILE_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_cfg_info.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_cfg_info.h new file mode 100644 index 000000000000..2e5dd2f3d645 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_cfg_info.h @@ -0,0 +1,192 @@ +/* + * A header definition for dfd_cfg_info driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __DFD_CFG_INFO_H__ +#define __DFD_CFG_INFO_H__ + +#include + +/* num buf format data to convert to a numeric function pointer */ +typedef int (*info_num_buf_to_value_f)(uint8_t *num_buf, int buf_len, int *num_val); + +/* num buf format data to convert to a numeric function pointer */ +typedef int (*info_buf_to_buf_f)(uint8_t *buf, int buf_len, uint8_t *buf_new, int *buf_len_new); + +/* Information format judgment macro */ +#define IS_INFO_FRMT_BIT(frmt) ((frmt) == INFO_FRMT_BIT) +#define IS_INFO_FRMT_BYTE(frmt) (((frmt) == INFO_FRMT_BYTE) || ((frmt) == INFO_FRMT_NUM_BYTES)) +#define IS_INFO_FRMT_NUM_STR(frmt) ((frmt) == INFO_FRMT_NUM_STR) +#define IS_INFO_FRMT_NUM_BUF(frmt) ((frmt) == INFO_FRMT_NUM_BUF) +#define IS_INFO_FRMT_BUF(frmt) ((frmt) == INFO_FRMT_BUF) + +/* INT Validity judgment of information length */ +#define INFO_INT_MAX_LEN (32) +#define INFO_INT_LEN_VALAID(len) (((len) > 0) && ((len) < INFO_INT_MAX_LEN)) + +/* buf Validity judgment of information length */ +#define INFO_BUF_MAX_LEN (128) +#define INFO_BUF_LEN_VALAID(len) (((len) > 0) && ((len) < INFO_BUF_MAX_LEN)) + +/* Determine the validity of information bit offset */ +#define INFO_BIT_OFFSET_VALID(bit_offset) (((bit_offset) >= 0) && ((bit_offset) < 8)) + +/* Information control mode */ +typedef enum info_ctrl_mode_e { + INFO_CTRL_MODE_NONE, + INFO_CTRL_MODE_CFG, /* Configuration mode */ + INFO_CTRL_MODE_CONS, /* macromode */ + INFO_CTRL_MODE_TLV, /* TLV mode */ + INFO_CTRL_MODE_SRT_CONS, /* String constant*/ + INFO_CTRL_MODE_END +} info_ctrl_mode_t; + +/* Information format */ +typedef enum info_frmt_e { + INFO_FRMT_NONE, + INFO_FRMT_BIT, /* Single or multiple bits, not more than 8 bits */ + INFO_FRMT_BYTE, /* Single byte */ + INFO_FRMT_NUM_BYTES, /* Multiple byte values, up to sizeof(int) */ + INFO_FRMT_NUM_STR, /* String value */ + INFO_FRMT_NUM_BUF, /* String value */ + INFO_FRMT_BUF, /* Multiple bytes */ + INFO_FRMT_END +} info_frmt_t; + +/* Information source */ +typedef enum info_src_e { + INFO_SRC_NONE, + INFO_SRC_CPLD, /* CPLD equipment */ + INFO_SRC_FPGA, /* FPGA equipment */ + INFO_SRC_OTHER_I2C, /* other i2c equipment */ + INFO_SRC_FILE, /* file */ + INFO_SRC_END +} info_src_t; + +/* Polarity of information */ +typedef enum info_pola_e { + INFO_POLA_NONE, + INFO_POLA_POSI, /* Positive polarity bit value 1 Valid value high bytes saved in the source low address space */ + INFO_POLA_NEGA, /* Negative polarity bit value 0 Effective value high bytes saved in the source high address space */ + INFO_POLA_END +} info_pola_t; + +/* Information control structure */ +#define INFO_FPATH_MAX_LEN (128) /* Maximum length of the file source path */ +#define INFO_STR_CONS_MAX_LEN (64) /* Maximum length of a string constant */ +typedef struct info_ctrl_s { + info_ctrl_mode_t mode; /* mode */ + int32_t int_cons; /* Only the int type is supported */ + info_src_t src; /* source */ + info_frmt_t frmt; /* format */ + info_pola_t pola; /* polarity */ + char fpath[INFO_FPATH_MAX_LEN]; /* File path, only the file source information */ + int32_t addr; /* address */ + int32_t len; /* Length, bit length, or byte length */ + int32_t bit_offset; /* Offset number of bits in the address */ + char str_cons[INFO_STR_CONS_MAX_LEN]; /* String constant */ + int32_t int_extra1; /* int type reserved */ + int32_t int_extra2; + int32_t int_extra3; /* cpld voltage mode */ +} info_ctrl_t; + +/* info_ctrl_t member macro */ +typedef enum info_ctrl_mem_s { + INFO_CTRL_MEM_MODE, + INFO_CTRL_MEM_INT_CONS, + INFO_CTRL_MEM_SRC, + INFO_CTRL_MEM_FRMT, + INFO_CTRL_MEM_POLA, + INFO_CTRL_MEM_FPATH, + INFO_CTRL_MEM_ADDR, + INFO_CTRL_MEM_LEN, + INFO_CTRL_MEM_BIT_OFFSET, + INFO_CTRL_MEM_STR_CONS, + INFO_CTRL_MEM_INT_EXTRA1, + INFO_CTRL_MEM_INT_EXTRA2, + INFO_CTRL_MEM_INT_EXTRA3, + INFO_CTRL_MEM_END +} info_ctrl_mem_t; + +/* sensor data format */ +typedef enum sensor_format_mem_s { + LINEAR11 = 1, + LINEAR16 = 2, + TMP464 = 3, + MAC_TH5 = 4, + MAC_TH4 = 5, +} sensor_format_mem_t; + +/* hwmon data format conversion */ +typedef int (*info_hwmon_buf_f)(uint8_t *buf, int buf_len, uint8_t *buf_new, int *buf_len_new, + info_ctrl_t *info_ctrl, int coefficient, int addend); + +/* Global variable */ +extern char *g_info_ctrl_mem_str[INFO_CTRL_MEM_END]; /* info_ctrl_t member string */ +extern char *g_info_src_str[INFO_SRC_END]; /* info_src_t enumeration string */ +extern char *g_info_frmt_str[INFO_FRMT_END]; /* info_frmt_t enumeration string */ +extern char *g_info_pola_str[INFO_POLA_END]; /* info_pola_t enumeration string */ +extern char *g_info_ctrl_mode_str[INFO_CTRL_MODE_END];/* info_ctrl_mode_t enumeration string */ + +/** + * dfd_info_get_int - Get int type information + * @key: Search keyword of the configuration item + * @ret: int type information + * @pfun: num Data conversion function of type buf + * + * @returns: 0 succeeds, <0 fails + */ +int dfd_info_get_int(uint64_t key, int *ret, info_num_buf_to_value_f pfun); + +/** + * dfd_info_get_buf - Get buf type information + * @key: Search keyword of the configuration item + * @buf: Information buf + * @buf_len: buf length, which must be no less than info_ctrl->len + * @pfun: Data conversion function pointer + * + * @returns: 0 succeeds, <0 fails + */ +int dfd_info_get_buf(uint64_t key, uint8_t *buf, int buf_len, info_buf_to_buf_f pfun); + +/** + * dfd_info_set_int - Set the int type information + * @key: Search keyword of the configuration item + * @val: int type information + * + * @returns: 0 succeeds, <0 fails + */ +int dfd_info_set_int(uint64_t key, int val); + +/** + * dfd_info_get_sensor - Get sensors + * @key: HWMON Configures the key + * @buf: Result storage + * @buf_len: buf length + * + * @returns: <0 Failed, others succeeded + */ +int dfd_info_get_sensor(uint64_t key, char *buf, int buf_len, info_hwmon_buf_f pfun); + +/** + * @buf:Input and result store + * + */ +void dfd_info_del_no_print_string(char *buf); +#endif /* __DFD_CFG_INFO_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_cfg_listnode.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_cfg_listnode.h new file mode 100644 index 000000000000..8b2b12ad512a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_cfg_listnode.h @@ -0,0 +1,80 @@ +/* + * A header definition for dfd_cfg_listnode driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __DFD_CFG_LISTNODE_H__ +#define __DFD_CFG_LISTNODE_H__ + +#include + +/* Returned value */ +#define LNODE_RV_OK (0) +#define LNODE_RV_INPUT_ERR (-1) /* Entry error */ +#define LNODE_RV_NODE_EXIST (-2) /* Node already exists */ +#define LNODE_RV_NOMEM (-3) /* Node already exists */ + +/* Root node public structure */ +typedef struct lnode_root_s { + struct list_head root; +} lnode_root_t; + +/* Node structure */ +typedef struct lnode_node_s { + struct list_head lst; + + uint64_t key; /* Node search index value */ + void *data; /* The actual data pointer */ +} lnode_node_t; + +/** + * Find node + * @root: Root node pointer + * @key: Node index value + * + * @return : Node data pointer,NULL failed + */ +void *lnode_find_node(lnode_root_t *root, uint64_t key); + +/** + * Insert node + * @root: Root node pointer + * @key: Node index value + * @data: data + * + * @return : 0-- success, other failures + */ +int lnode_insert_node(lnode_root_t *root, uint64_t key, void *data); + +/** + * Example Initialize the root node + * @root: Root node pointer + * + * @return : 0-- success, other failures + */ +int lnode_init_root(lnode_root_t *root); + +/** + * Free linked list + * @root: Root node pointer + * + * @return : void + */ +void lnode_free_list(lnode_root_t *root); + +#endif /* __DFD_CFG_LISTNODE_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_frueeprom.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_frueeprom.h new file mode 100644 index 000000000000..a95943c5a90d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_frueeprom.h @@ -0,0 +1,107 @@ +/* + * A header definition for dfd_cfg_frueeprom driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _DFD_FRUEEPROM_H_ +#define _DFD_FRUEEPROM_H_ + +/* Per IPMI v2.0 FRU specification */ +typedef struct fru_common_header_s { + uint8_t fixed; + uint8_t internal_offset; + uint8_t chassis_offset; + uint8_t board_offset; + uint8_t product_offset; + uint8_t multi_offset; + uint8_t pad; + uint8_t crc; +} __attribute__((packed)) fru_common_header_t; + +/* first byte in header is 1h per IPMI V2 spec. */ + +#define IPMI_FRU_HDR_BYTE_ZERO 1 +#define IPMI_EIGHT_BYTES 8 +#define IPMI_FRU_PRODUCT_AREA_MIN_LEN (7) +#define IPMI_FRU_BOARD_AREA_MIN_LEN (5) + +#define IPMI_FRU_AREA_TYPE_LENGTH_FIELD_MAX 512 +#define IPMI_FRU_BOARD_INFO_MFG_TIME_LENGTH 3 +#define IPMI_FRU_SENTINEL_VALUE 0xC1 +#define IPMI_FRU_TYPE_LENGTH_TYPE_CODE_MASK 0xC0 +#define IPMI_FRU_TYPE_LENGTH_TYPE_CODE_SHIFT 0x06 +#define IPMI_FRU_TYPE_LENGTH_NUMBER_OF_DATA_BYTES_MASK 0x3F +#define IPMI_FRU_TYPE_LENGTH_TYPE_CODE_LANGUAGE_CODE 0x03 + +struct ipmi_fru_field { + uint8_t type_length_field[IPMI_FRU_AREA_TYPE_LENGTH_FIELD_MAX]; + /* store length of data stored in buffer */ + unsigned int type_length_field_length; +}; + +typedef struct ipmi_fru_field ipmi_fru_field_t; + +typedef struct ipmi_product_info_s { + uint8_t *language_code; + ipmi_fru_field_t *product_manufacturer_name; + ipmi_fru_field_t *product_name; + ipmi_fru_field_t *product_part_model_number; + ipmi_fru_field_t *product_version; + ipmi_fru_field_t *product_serial_number; + ipmi_fru_field_t *product_asset_tag; + ipmi_fru_field_t *product_fru_file_id; + ipmi_fru_field_t *product_custom_fields; + ipmi_fru_field_t *product_type_fields; +} ipmi_product_info_t; + +typedef struct ipmi_board_info_s { + uint8_t *language_code; + uint8_t *mfg_time; + ipmi_fru_field_t *board_manufacturer; + ipmi_fru_field_t *board_product_name; + ipmi_fru_field_t *board_serial_number; + ipmi_fru_field_t *board_part_number; + ipmi_fru_field_t *board_fru_file_id; + ipmi_fru_field_t *board_custom_fields; /*hw version */ +} ipmi_board_info_t; + +/** + * dfd_get_fru_data - Obtain product area FRU information + * @bus:FRU E2 bus number + * @dev_addr:FRU E2 Device address + * @type: 2: Product name, 3: product serial number 5: hardware version number 6: product ID + * @buf:Data is stored in buf + * @buf_len:buf length + * @sysfs_name:sysfs attribute name + * @returns: 0 success, negative value: failed + */ +int dfd_get_fru_data(int bus, int dev_addr, int type, uint8_t *buf, uint32_t buf_len, const char *sysfs_name); + +/** + * dfd_get_fru_board_data - Obtain the FRU information of the board area + * @bus:FRU E2 bus number + * @dev_addr:FRU E2 Device address + * @type: 2: Product name, 3: product serial number 5: hardware version number + * @buf:Data is stored in buf + * @buf_len:buf length + * @sysfs_name:sysfs attribute name + * @returns: 0 success, negative value: failed + */ +int dfd_get_fru_board_data(int bus, int dev_addr, int type, uint8_t *buf, uint32_t buf_len, const char *sysfs_name); + +#endif /* endif _DFD_FRUEEPROM_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_sysfs_common.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_sysfs_common.h new file mode 100644 index 000000000000..994bb2387ddb --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_sysfs_common.h @@ -0,0 +1,251 @@ +/* + * A header definition for dfd_sysfs_common driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _DFD_SYSFS_COMMON_H_ +#define _DFD_SYSFS_COMMON_H_ + +struct switch_drivers_s { + /* temperature sensors */ + int (*get_main_board_temp_number)(void); + ssize_t (*get_main_board_temp_alias)(unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_main_board_temp_type)(unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_main_board_temp_max)(unsigned int temp_index, char *buf, size_t count); + int (*set_main_board_temp_max)(unsigned int temp_index, const char *buf, size_t count); + ssize_t (*get_main_board_temp_min)(unsigned int temp_index, char *buf, size_t count); + int (*set_main_board_temp_min)(unsigned int temp_index, const char *buf, size_t count); + ssize_t (*get_main_board_temp_value)(unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_main_board_temp_high)(unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_main_board_temp_low)(unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_main_board_temp_monitor_flag)(unsigned int temp_index, char *buf, size_t count); + /* voltage sensors */ + int (*get_main_board_vol_number)(void); + ssize_t (*get_main_board_vol_alias)(unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_main_board_vol_type)(unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_main_board_vol_max)(unsigned int vol_index, char *buf, size_t count); + int (*set_main_board_vol_max)(unsigned int vol_index, const char *buf, size_t count); + ssize_t (*get_main_board_vol_min)(unsigned int vol_index, char *buf, size_t count); + int (*set_main_board_vol_min)(unsigned int vol_index, const char *buf, size_t count); + ssize_t (*get_main_board_vol_range)(unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_main_board_vol_nominal_value)(unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_main_board_vol_value)(unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_main_board_vol_monitor_flag)(unsigned int vol_index, char *buf, size_t count); + /* current sensors */ + int (*get_main_board_curr_number)(void); + ssize_t (*get_main_board_curr_alias)(unsigned int curr_index, char *buf, size_t count); + ssize_t (*get_main_board_curr_type)(unsigned int curr_index, char *buf, size_t count); + ssize_t (*get_main_board_curr_max)(unsigned int curr_index, char *buf, size_t count); + int (*set_main_board_curr_max)(unsigned int curr_index, const char *buf, size_t count); + ssize_t (*get_main_board_curr_min)(unsigned int curr_index, char *buf, size_t count); + int (*set_main_board_curr_min)(unsigned int curr_index, const char *buf, size_t count); + ssize_t (*get_main_board_curr_value)(unsigned int curr_index, char *buf, size_t count); + ssize_t (*get_main_board_curr_monitor_flag)(unsigned int curr_index, char *buf, size_t count); + /* syseeprom */ + int (*get_syseeprom_size)(void); + ssize_t (*read_syseeprom_data)(char *buf, loff_t offset, size_t count); + ssize_t (*write_syseeprom_data)(char *buf, loff_t offset, size_t count); + /* fan */ + int (*get_fan_number)(void); + int (*get_fan_motor_number)(unsigned int fan_index); + ssize_t (*get_fan_model_name)(unsigned int fan_index, char *buf, size_t count); + ssize_t (*get_fan_vendor)(unsigned int fan_index, char *buf, size_t count); + ssize_t (*get_fan_serial_number)(unsigned int fan_index, char *buf, size_t count); + ssize_t (*get_fan_part_number)(unsigned int fan_index, char *buf, size_t count); + ssize_t (*get_fan_hardware_version)(unsigned int fan_index, char *buf, size_t count); + ssize_t (*get_fan_status)(unsigned int fan_index, char *buf, size_t count); + ssize_t (*get_fan_present)(unsigned int fan_index, char *buf, size_t count); + ssize_t (*get_fan_led_status)(unsigned int fan_index, char *buf, size_t count); + int (*set_fan_led_status)(unsigned int fan_index, int status); + ssize_t (*get_fan_direction)(unsigned int fan_index, char *buf, size_t count); + ssize_t (*get_fan_motor_status)(unsigned int fan_index, unsigned int motor_index, char *buf, size_t count); + ssize_t (*get_fan_motor_speed)(unsigned int fan_index, unsigned int motor_index, char *buf, size_t count); + ssize_t (*get_fan_motor_speed_tolerance)(unsigned int fan_index, unsigned int motor_index, char *buf, size_t count); + ssize_t (*get_fan_motor_speed_target)(unsigned int fan_index, unsigned int motor_index, char *buf, size_t count); + ssize_t (*get_fan_motor_speed_max)(unsigned int fan_index, unsigned int motor_index, char *buf, size_t count); + ssize_t (*get_fan_motor_speed_min)(unsigned int fan_index, unsigned int motor_index, char *buf, size_t count); + ssize_t (*get_fan_ratio)(unsigned int fan_index, char *buf, size_t count); + int (*set_fan_ratio)(unsigned int fan_index, int ratio); + /* PSU */ + int (*get_psu_number)(void); + int (*get_psu_temp_number)(unsigned int psu_index); + ssize_t (*get_psu_model_name)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_vendor)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_date)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_status)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_hw_status)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_alarm)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_serial_number)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_part_number)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_hardware_version)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_type)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_in_curr)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_in_vol)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_in_power)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_out_curr)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_out_vol)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_out_power)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_out_max_power)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_present_status)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_in_status)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_out_status)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_status_pmbus)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_fan_speed)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_fan_ratio)(unsigned int psu_index, char *buf, size_t count); + int (*set_psu_fan_ratio)(unsigned int psu_index, int ratio); + ssize_t (*get_psu_fan_direction)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_led_status)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_fan_speed_cal)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_temp_alias)(unsigned int psu_index, unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_psu_temp_type)(unsigned int psu_index, unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_psu_temp_max)(unsigned int psu_index, unsigned int temp_index, char *buf, size_t count); + int (*set_psu_temp_max)(unsigned int psu_index, unsigned int temp_index, const char *buf, size_t count); + ssize_t (*get_psu_temp_min)(unsigned int psu_index, unsigned int temp_index, char *buf, size_t count); + int (*set_psu_temp_min)(unsigned int psu_index, unsigned int temp_index, const char *buf, size_t count); + ssize_t (*get_psu_temp_value)(unsigned int psu_index, unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_psu_attr_threshold)(unsigned int psu_index, unsigned int type, char *buf, size_t count); + int (*get_psu_eeprom_size)(unsigned int psu_index); + ssize_t (*read_psu_eeprom_data)(unsigned int psu_index, char *buf, loff_t offset, size_t count); + ssize_t (*get_psu_blackbox_info)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_pmbus_info)(unsigned int psu_index, char *buf, size_t count); + int (*clear_psu_blackbox)(unsigned int psu_index, uint8_t value); + /* transceiver */ + int (*get_eth_number)(void); + ssize_t (*get_transceiver_power_on_status)(char *buf, size_t count); + int (*set_transceiver_power_on_status)(int status); + ssize_t (*get_transceiver_present_status)(char *buf, size_t count); + ssize_t (*get_eth_power_on_status)(unsigned int eth_index, char *buf, size_t count); + int (*set_eth_power_on_status)(unsigned int eth_index, int status); + ssize_t (*get_eth_tx_fault_status)(unsigned int eth_index, char *buf, size_t count); + ssize_t (*get_eth_tx_disable_status)(unsigned int eth_index, char *buf, size_t count); + int (*set_eth_tx_disable_status)(unsigned int eth_index, int status); + ssize_t (*get_eth_present_status)(unsigned int eth_index, char *buf, size_t count); + ssize_t (*get_eth_rx_los_status)(unsigned int eth_index, char *buf, size_t count); + ssize_t (*get_eth_reset_status)(unsigned int eth_index, char *buf, size_t count); + int (*set_eth_reset_status)(unsigned int eth_index, int status); + ssize_t (*get_eth_low_power_mode_status)(unsigned int eth_index, char *buf, size_t count); + ssize_t (*get_eth_interrupt_status)(unsigned int eth_index, char *buf, size_t count); + int (*get_eth_eeprom_size)(unsigned int eth_index); + ssize_t (*read_eth_eeprom_data)(unsigned int eth_index, char *buf, loff_t offset, size_t count); + ssize_t (*write_eth_eeprom_data)(unsigned int eth_index, char *buf, loff_t offset, size_t count); + ssize_t (*get_eth_optoe_type)(unsigned int sff_index, int *optoe_type, char *buf, size_t count); + int (*set_eth_optoe_type)(unsigned int sff_index, int optoe_type); + /* sysled */ + ssize_t (*get_sys_led_status)(char *buf, size_t count); + int (*set_sys_led_status)(int status); + ssize_t (*get_bmc_led_status)(char *buf, size_t count); + int (*set_bmc_led_status)(int status); + ssize_t (*get_sys_fan_led_status)(char *buf, size_t count); + int (*set_sys_fan_led_status)(int status); + ssize_t (*get_sys_psu_led_status)(char *buf, size_t count); + int (*set_sys_psu_led_status)(int status); + ssize_t (*get_id_led_status)(char *buf, size_t count); + int (*set_id_led_status)(int status); + /* FPGA */ + int (*get_main_board_fpga_number)(void); + ssize_t (*get_main_board_fpga_alias)(unsigned int fpga_index, char *buf, size_t count); + ssize_t (*get_main_board_fpga_type)(unsigned int fpga_index, char *buf, size_t count); + ssize_t (*get_main_board_fpga_firmware_version)(unsigned int fpga_index, char *buf, size_t count); + ssize_t (*get_main_board_fpga_board_version)(unsigned int fpga_index, char *buf, size_t count); + ssize_t (*get_main_board_fpga_test_reg)(unsigned int fpga_index, char *buf, size_t count); + int (*set_main_board_fpga_test_reg)(unsigned int fpga_index, unsigned int value); + /* CPLD */ + int (*get_main_board_cpld_number)(void); + ssize_t (*get_main_board_cpld_alias)(unsigned int cpld_index, char *buf, size_t count); + ssize_t (*get_main_board_cpld_type)(unsigned int cpld_index, char *buf, size_t count); + ssize_t (*get_main_board_cpld_firmware_version)(unsigned int cpld_index, char *buf, size_t count); + ssize_t (*get_main_board_cpld_board_version)(unsigned int cpld_index, char *buf, size_t count); + ssize_t (*get_main_board_cpld_test_reg)(unsigned int cpld_index, char *buf, size_t count); + int (*set_main_board_cpld_test_reg)(unsigned int cpld_index, unsigned int value); + /* watchdog */ + ssize_t (*get_watchdog_identify)(char *buf, size_t count); + ssize_t (*get_watchdog_timeleft)(char *buf, size_t count); + ssize_t (*get_watchdog_timeout)(char *buf, size_t count); + int (*set_watchdog_timeout)(int value); + ssize_t (*get_watchdog_enable_status)(char *buf, size_t count); + int (*set_watchdog_enable_status)(int value); + int (*set_watchdog_reset)(int value); + /* slot */ + int (*get_slot_number)(void); + int (*get_slot_temp_number)(unsigned int slot_index); + int (*get_slot_vol_number)(unsigned int slot_index); + int (*get_slot_curr_number)(unsigned int slot_index); + int (*get_slot_cpld_number)(unsigned int slot_index); + int (*get_slot_fpga_number)(unsigned int slot_index); + ssize_t (*get_slot_model_name)(unsigned int slot_index, char *buf, size_t count); + ssize_t (*get_slot_vendor)(unsigned int slot_index, char *buf, size_t count); + ssize_t (*get_slot_serial_number)(unsigned int slot_index, char *buf, size_t count); + ssize_t (*get_slot_part_number)(unsigned int slot_index, char *buf, size_t count); + ssize_t (*get_slot_hardware_version)(unsigned int slot_index, char *buf, size_t count); + ssize_t (*get_slot_status)(unsigned int slot_index, char *buf, size_t count); + ssize_t (*get_slot_led_status)(unsigned int slot_index, char *buf, size_t count); + int (*set_slot_led_status)(unsigned int slot_index, int status); + ssize_t (*get_slot_power_status)(unsigned int slot_index, char *buf, size_t count); + int (*set_slot_power_status)(unsigned int slot_index, int status); + ssize_t (*get_slot_temp_alias)(unsigned int slot_index, unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_slot_temp_type)(unsigned int slot_index, unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_slot_temp_max)(unsigned int slot_index, unsigned int temp_index, char *buf, size_t count); + int (*set_slot_temp_max)(unsigned int slot_index, unsigned int temp_index, const char *buf, size_t count); + ssize_t (*get_slot_temp_min)(unsigned int slot_index, unsigned int temp_index, char *buf, size_t count); + int (*set_slot_temp_min)(unsigned int slot_index, unsigned int temp_index, const char *buf, size_t count); + ssize_t (*get_slot_temp_value)(unsigned int slot_index, unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_slot_vol_alias)(unsigned int slot_index, unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_slot_vol_type)(unsigned int slot_index, unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_slot_vol_max)(unsigned int slot_index, unsigned int vol_index, char *buf, size_t count); + int (*set_slot_vol_max)(unsigned int slot_index, unsigned int vol_index, const char *buf, size_t count); + ssize_t (*get_slot_vol_min)(unsigned int slot_index, unsigned int vol_index, char *buf, size_t count); + int (*set_slot_vol_min)(unsigned int slot_index, unsigned int vol_index, const char *buf, size_t count); + ssize_t (*get_slot_vol_range)(unsigned int slot_index, unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_slot_vol_nominal_value)(unsigned int slot_index, unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_slot_vol_value)(unsigned int slot_index, unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_slot_curr_alias)(unsigned int slot_index, unsigned int curr_index, char *buf, size_t count); + ssize_t (*get_slot_curr_type)(unsigned int slot_index, unsigned int curr_index, char *buf, size_t count); + ssize_t (*get_slot_curr_max)(unsigned int slot_index, unsigned int curr_index, char *buf, size_t count); + int (*set_slot_curr_max)(unsigned int slot_index, unsigned int curr_index, const char *buf, size_t count); + ssize_t (*get_slot_curr_min)(unsigned int slot_index, unsigned int curr_index, char *buf, size_t count); + int (*set_slot_curr_min)(unsigned int slot_index, unsigned int curr_index, const char *buf, size_t count); + ssize_t (*get_slot_curr_value)(unsigned int slot_index, unsigned int curr_index, char *buf, size_t count); + ssize_t (*get_slot_fpga_alias)(unsigned int slot_index, unsigned int fpga_index, char *buf, size_t count); + ssize_t (*get_slot_fpga_type)(unsigned int slot_index, unsigned int fpga_index, char *buf, size_t count); + ssize_t (*get_slot_fpga_firmware_version)(unsigned int slot_index, unsigned int fpga_index, char *buf, size_t count); + ssize_t (*get_slot_fpga_board_version)(unsigned int slot_index, unsigned int fpga_index, char *buf, size_t count); + ssize_t (*get_slot_fpga_test_reg)(unsigned int slot_index, unsigned int fpga_index, char *buf, size_t count); + int (*set_slot_fpga_test_reg)(unsigned int slot_index, unsigned int fpga_index, unsigned int value); + ssize_t (*get_slot_cpld_alias)(unsigned int slot_index, unsigned int cpld_index, char *buf, size_t count); + ssize_t (*get_slot_cpld_type)(unsigned int slot_index, unsigned int cpld_index, char *buf, size_t count); + ssize_t (*get_slot_cpld_firmware_version)(unsigned int slot_index, unsigned int cpld_index, char *buf, size_t count); + ssize_t (*get_slot_cpld_board_version)(unsigned int slot_index, unsigned int cpld_index, char *buf, size_t count); + ssize_t (*get_slot_cpld_test_reg)(unsigned int slot_index, unsigned int cpld_index, char *buf, size_t count); + int (*set_slot_cpld_test_reg)(unsigned int slot_index, unsigned int cpld_index, unsigned int value); + /* system */ + ssize_t (*get_system_value)(unsigned int type, int *value, char *buf, size_t count); + ssize_t (*set_system_value)(unsigned int type, int value); + ssize_t (*get_system_port_power_status)(unsigned int type, char *buf, size_t count); + /* eeprom */ + int (*get_eeprom_number)(void); + int (*get_eeprom_size)(unsigned int e2_index); + ssize_t (*get_eeprom_alias)(unsigned int e2_index, char *buf, size_t count); + ssize_t (*get_eeprom_tag)(unsigned int e2_index, char *buf, size_t count); + ssize_t (*get_eeprom_type)(unsigned int e2_index, char *buf, size_t count); + ssize_t (*read_eeprom_data)(unsigned int e2_index, char *buf, loff_t offset, size_t count); + ssize_t (*write_eeprom_data)(unsigned int e2_index, char *buf, loff_t offset, size_t count); +}; + +extern struct switch_drivers_s * s3ip_switch_driver_get(void); + +#endif /*_DFD_SYSFS_COMMON_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_tlveeprom.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_tlveeprom.h new file mode 100644 index 000000000000..75e0f06bd305 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/dfd_tlveeprom.h @@ -0,0 +1,91 @@ +/* + * A header definition for dfd_tlveeprom driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _DFD_TLVEEPROM_H_ +#define _DFD_TLVEEPROM_H_ + +#ifndef be16_to_cpu +#define be16_to_cpu(x) ntohs(x) +#endif + +#ifndef cpu_to_be16 +#define cpu_to_be16(x) htons(x) +#endif + +#define TLV_CODE_NAME_LEN 64 + +/* + * Struct for displaying the TLV codes and names. + */ +struct tlv_code_desc { + uint8_t m_code; + char m_name[TLV_CODE_NAME_LEN]; +}; + +/* ONIE TLV Type Type and extended TLV type definition */ +typedef struct dfd_tlv_type_s { + uint8_t main_type; /* ONIE standard TLV TYPE */ + uint8_t ext_type; /* Extended TLV TYPE type */ +} dfd_tlv_type_t; + +/* Header Field Constants */ +#define TLV_INFO_ID_STRING "TlvInfo" +#define TLV_INFO_VERSION 0x01 + +struct __attribute__ ((__packed__)) tlvinfo_header_s { + char signature[8]; /* 0x00 - 0x07 EEPROM Tag "TlvInfo" */ + uint8_t version; /* 0x08 Structure version */ + uint16_t totallen; /* 0x09 - 0x0A Length of all data which follows */ +}; +typedef struct tlvinfo_header_s tlvinfo_header_t; + +/* + * TlvInfo TLV: Layout of a TLV field + */ +struct __attribute__ ((__packed__)) tlvinfo_tlv_s { + uint8_t type; + uint8_t length; + uint8_t value[0]; +}; +typedef struct tlvinfo_tlv_s tlvinfo_tlv_t; + +#define TLV_VALUE_MAX_LEN 255 +/* + * The max decode value is currently for the 'raw' type or the 'vendor + * extension' type, both of which have the same decode format. The + * max decode string size is computed as follows: + * + * strlen(" 0xFF") * TLV_VALUE_MAX_LEN + 1 + * + */ +#define TLV_DECODE_VALUE_MAX_LEN ((5 * TLV_VALUE_MAX_LEN) + 1) + +typedef struct tlv_decode_value_s { + uint8_t value[TLV_DECODE_VALUE_MAX_LEN]; + uint32_t length; +} tlv_decode_value_t; + +typedef enum dfd_tlvinfo_ext_tlv_type_e { + DFD_TLVINFO_EXT_TLV_TYPE_DEV_TYPE = 1, +} dfd_tlvinfo_ext_tlv_type_t; + +int dfd_tlvinfo_get_e2prom_info(uint8_t *eeprom, uint32_t size, dfd_tlv_type_t *tlv_type, uint8_t* buf, uint32_t *buf_len); + +#endif /* endif _DFD_TLVEEPROM_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/switch_driver.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/switch_driver.h new file mode 100644 index 000000000000..7ab38f42d367 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/switch_driver.h @@ -0,0 +1,101 @@ +/* + * A header definition for switch_driver driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _SWITCH_DRIVER_H_ +#define _SWITCH_DRIVER_H_ + +#define SWITCH_DEV_NO_SUPPORT "NA" +#define SWITCH_DEV_ERROR "ACCESS FAILED" +#define WB_SYSFS_RV_UNSUPPORT (999) + +typedef enum dbg_level_e { + DBG_VERBOSE = 0x01, + DBG_WARN = 0x02, + DBG_ERROR = 0x04, +} dbg_level_t; + +typedef enum fan_status_e { + FAN_STATUS_ABSENT = 0, + FAN_STATUS_OK = 1, + FAN_STATUS_NOT_OK = 2, +} fan_status_t; + +typedef enum led_status_e { + LED_STATUS_DARK = 0, + LED_STATUS_GREEN = 1, + LED_STATUS_YELLOW = 2, + LED_STATUS_RED = 3, + LED_STATUS_BLUE = 4, + LED_STATUS_GREEN_FLASH = 5, + LED_STATUS_YELLOW_FLASH = 6, + LED_STATUS_RED_FLASH = 7, +} led_status_t; + +typedef enum air_flow_direction_e { + F2B = 0, /* air enters from the front of the cabinet, and exhausts from the back */ + B2F = 1, /* air enters from the back of the cabinet, and exhausts from the front */ +} air_flow_direction_t; + +typedef enum psu_input_type_e { + POWER_DC = 0, + POWER_AC = 1, +} psu_input_type_t; + +typedef enum psu_status_e { + PSU_STATUS_ABSENT = 0, /* psu absent */ + PSU_STATUS_PRESENT = 1, /* psu present and status ok */ + PSU_STATUS_WARN = 2, /* psu present and status warn (pmbus 0x79 bit11 value 0)*/ + PSU_STATUS_FAIL = 3, /* psu present and status fail (pmbus 0x79 bit11 value 1)*/ +} psu_status_t; + +typedef enum psu_status_word_e { + PSU_VOUT_FAULT = 0x8000, + PSU_IOUT_FAULT = 0x4000, + PSU_INPUT_FAULT = 0x2000, + PSU_MFR_FAULT = 0x1000, + PSU_PG_FAULT = 0x0800, + PSU_FAN_FAULT = 0x0400, + PSU_OFF_FAULT = 0x0040, + PSU_TEMP_FAULT = 0x0004, +} psu_status_word_t; + +typedef enum psu_io_status_e { + PSU_IO_STATUS_ABNORMAL = 0, + PSU_IO_STATUS_NORMAL = 1, +} psu_io_status_t; + +typedef enum dev_status_e { + DEV_ABSENT = 0, /* dev absent */ + DEV_PRESENT = 1, /* dev present */ +} dev_status_t; + +extern int g_switch_dbg_level; + +#define SWITCH_DEBUG(level, fmt, arg...) do { \ + if (g_switch_dbg_level & level) { \ + if (level >= DBG_ERROR) { \ + printk(KERN_ERR "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } else { \ + printk(KERN_INFO "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } \ + } \ +} while (0) + +#endif /* _SWITCH_DRIVER_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_cpld_driver.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_cpld_driver.h new file mode 100644 index 000000000000..7698a3f0ef60 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_cpld_driver.h @@ -0,0 +1,100 @@ +/* + * A header definition for wb_cpld_driver driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _WB_CPLD_DRIVER_H_ +#define _WB_CPLD_DRIVER_H_ + +/** + * dfd_get_cpld_name - Obtain the CPLD name + * @main_dev_id: Motherboard :0 Subcard :5 + * @index:The number of the CPLD starts from 0 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success: Returns the length of buf + * :Failed: A negative value is returned + */ +ssize_t dfd_get_cpld_name(uint8_t main_dev_id, unsigned int cpld_index, char *buf, size_t count); + +/** + * dfd_get_cpld_type - Obtain the CPLD model + * @main_dev_id: Motherboard :0 Subcard :5 + * @index:The number of the CPLD starts from 0 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success: Returns the length of buf + * :Failed: A negative value is returned + */ +ssize_t dfd_get_cpld_type(uint8_t main_dev_id, unsigned int cpld_index, char *buf, size_t count); + +/** + * dfd_get_cpld_fw_version - Obtain the CPLD firmware version + * @main_dev_id: Motherboard :0 Subcard :5 + * @index:The number of the CPLD starts from 0 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success: Returns the length of buf + * :Failed: A negative value is returned + */ +ssize_t dfd_get_cpld_fw_version(uint8_t main_dev_id, unsigned int cpld_index, char *buf, size_t count); + +/** + * dfd_get_cpld_hw_version - Obtain the hardware version of the CPLD + * @main_dev_id: Motherboard :0 Subcard :5 + * @index:The number of the CPLD starts from 0 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success: Returns the length of buf + * :Failed: A negative value is returned + */ +ssize_t dfd_get_cpld_hw_version(uint8_t main_dev_id, unsigned int cpld_index, char *buf, size_t count); + +/** + * dfd_set_cpld_testreg - Set the CPLD test register value + * @main_dev_id: Motherboard :0 Subcard :5 + * @cpld_index:The number of the CPLD starts from 0 + * @value: Writes the value of the test register + * return: Success:0 + * :Failed: A negative value is returned + */ +int dfd_set_cpld_testreg(uint8_t main_dev_id, unsigned int cpld_index, int value); + +/** + * dfd_get_cpld_testreg - Read the CPLD test register value + * @main_dev_id: Motherboard :0 Subcard :5 + * @cpld_index:The number of the CPLD starts from 0 + * @value: Read the test register value + * return: Success:0 + * :Failed: A negative value is returned + */ +int dfd_get_cpld_testreg(uint8_t main_dev_id, unsigned int cpld_index, int *value); + +/** + * dfd_get_cpld_testreg_str - Read the CPLD test register value + * @main_dev_id: Motherboard :0 Subcard :5 + * @cpld_index: The number of the CPLD starts from 0 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success: Returns the length of buf + * :Failed: A negative value is returned + */ +ssize_t dfd_get_cpld_testreg_str(uint8_t main_dev_id, unsigned int cpld_index, + char *buf, size_t count); + +#endif /* _WB_CPLD_DRIVER_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_eeprom_driver.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_eeprom_driver.h new file mode 100644 index 000000000000..e86ee210be78 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_eeprom_driver.h @@ -0,0 +1,59 @@ +/* + * A header definition for wb_eeprom_driver driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _WB_EEPROM_DRIVER_H_ +#define _WB_EEPROM_DRIVER_H_ + +/** + * dfd_get_eeprom_size - Gets the data size of the eeprom + * @e2_type: This section describes the E2 type, including system, PSU, fan, and module E2 + * @index: E2 number + * return: Succeeded: The data size of the eeprom is returned + * : Failed: A negative value is returned + */ +int dfd_get_eeprom_size(int e2_type, int index); + +/** + * dfd_read_eeprom_data - Read eeprom data + * @e2_type: This section describes the E2 type, including system, PSU, fan, and module E2 + * @index: E2 number + * @buf: eeprom data received buf + * @offset: The offset address of the read + * @count: Read length + * return: Success: Returns the length of fill buf + * : Failed: A negative value is returned + */ +ssize_t dfd_read_eeprom_data(int e2_type, int index, char *buf, loff_t offset, size_t count); + +/** + * dfd_write_eeprom_data - Write eeprom data + * @e2_type: This section describes the E2 type, including system, PSU, fan, and module E2 + * @index: E2 number + * @buf: eeprom data buf + * @offset: The offset address of the write + * @count: Write length + * return: Success: The length of the written data is returned + * : Failed: A negative value is returned + */ +ssize_t dfd_write_eeprom_data(int e2_type, int index, char *buf, loff_t offset, size_t count); +ssize_t dfd_get_eeprom_alias(int e2_type, unsigned int e2_index, char *buf, size_t count); +ssize_t dfd_get_eeprom_tag(int e2_type, unsigned int e2_index, char *buf, size_t count); +ssize_t dfd_get_eeprom_type(int e2_type, unsigned int e2_index, char *buf, size_t count); +#endif /* _WB_EEPROM_DRIVER_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_fan_driver.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_fan_driver.h new file mode 100644 index 000000000000..b1e66cb0530c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_fan_driver.h @@ -0,0 +1,191 @@ +/* + * A header definition for wb_fan_driver driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _WB_FAN_DRIVER_H_ +#define _WB_FAN_DRIVER_H_ + +/** + * dfd_get_fan_status_str - Obtaining fan status + * @index: Number of the fan, starting from 1 + * return: Success: Length of the status string + * : Negative value - Read failed + */ +ssize_t dfd_get_fan_status_str(unsigned int fan_index, char *buf, size_t count); + +/** + * dfd_get_fan_present_str - Obtaining fan present status + * @index: Number of the fan, starting from 1 + * return: Success: Length of the status string + * : Negative value - Read failed + */ +ssize_t dfd_get_fan_present_str(unsigned int fan_index, char *buf, size_t count); + +/** + * dfd_get_fan_info - Obtaining Fan Information + * @index: Number of the fan, starting from 1 + * @cmd: Fan information type, fan name :2, fan serial number :3, fan hardware version :5 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ + +/** + * dfd_get_fan_motor_status_str - Obtain the fan motor status + * @fan_index: Number of the fan, starting from 1 + * @motor_index: Motor number, starting with 1 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success :0 + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fan_motor_status_str(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count); + +ssize_t dfd_get_fan_info(unsigned int fan_index, uint8_t cmd, char *buf, size_t count); + +/** + * dfd_get_fan_speed - Obtain the fan speed + * @fan_index: Number of the fan, starting from 1 + * @motor_index: Motor number, starting with 1 + * @speed: Speed value + * return: Success :0 + * : Failed: A negative value is returned + */ +int dfd_get_fan_speed(unsigned int fan_index, unsigned int motor_index,unsigned int *speed); + +/** + * dfd_get_fan_speed_str - Obtain the fan speed + * @fan_index: Number of the fan, starting from 1 + * @motor_index: Motor number, starting with 1 + * @buf: Receive buf + * @count: Receive buf length + * return: Success :0 + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fan_speed_str(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count); + +/** + * dfd_set_fan_pwm - Set the fan speed duty cycle + * @fan_index: Number of the fan, starting from 1 + * @pwm: Duty cycle + * return: Success :0 + * : Failed: A negative value is returned + */ +int dfd_set_fan_pwm(unsigned int fan_index, int pwm); + +/** + * dfd_get_fan_pwm - Obtain the fan speed duty cycle + * @fan_index: Number of the fan, starting from 1 + * @pwm: Duty cycle + * return: Success :0 + * : Failed: A negative value is returned + */ +int dfd_get_fan_pwm(unsigned int fan_index, int *pwm); + +/** + * dfd_get_fan_pwm_str - Obtain the fan speed duty cycle + * @fan_index: Number of the fan, starting from 1 + * @buf: Receive buf + * @count: Receive buf length + * return: Success :0 + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fan_pwm_str(unsigned int fan_index, char *buf, size_t count); + +/** + * dfd_get_fan_motor_speed_tolerance_str - Obtain the fan speed tolerance + * @fan_index: Number of the fan, starting from 1 + * @motor_index: Motor number, starting with 1 + * @buf: Receive buf + * @count: Receive buf length + * return: Success :0 + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fan_motor_speed_tolerance_str(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count); + +/** + * dfd_get_fan_speed_target - Obtain the standard fan speed + * @fan_index + * @motor_index + * @value Standard speed value + * @returns: Success :0 + * : Failed: A negative value is returned + */ +int dfd_get_fan_speed_target(unsigned int fan_index, unsigned int motor_index, int *value); + +/** + * dfd_get_fan_motor_speed_target_str - Obtain the standard fan speed + * @fan_index: Number of the fan, starting from 1 + * @motor_index: Motor number, starting with 1 + * @buf: Receive buf + * @count: Receive buf length + * return: Success :0 + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fan_motor_speed_target_str(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count); + +/** + * dfd_get_fan_direction_str - Obtain the fan air duct type + * @fan_index: Number of the fan, starting from 1 + * @buf :Duct type receives buf + * @count :Duct type receives buf length + * @returns: Succeeded: Air duct type String length + * Failed: A negative value is returned + */ +ssize_t dfd_get_fan_direction_str(unsigned int fan_index, char *buf, size_t count); + +/** + * dfd_get_fan_motor_speed_max_str - Obtain the standard fan speed + * @fan_index: Number of the fan, starting from 1 + * @motor_index: Motor number, starting with 1 + * @buf: Receive buff + * @count: Receive buf length + * return: Success :0 + * :Failed: A negative value is returned + */ +ssize_t dfd_get_fan_motor_speed_max_str(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count); + +/** + * dfd_get_fan_motor_speed_min_str - Obtain the standard fan speed + * @fan_index: Number of the fan, starting from 1 + * @motor_index: Motor number, starting with 1 + * @buf: Receive buf + * @count: Receive buf length + * return: Success :0 + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fan_motor_speed_min_str(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count); + +/** + * dfd_get_fan_present_status - Obtain the fan status + * @index: Number of the fan, starting from 1 + * return: 0:ABSENT + * 1:PRESENT + * : Negative value - Read failed + */ +int dfd_get_fan_present_status(unsigned int fan_index); + +#endif /* _WB_FAN_DRIVER_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_fpga_driver.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_fpga_driver.h new file mode 100644 index 000000000000..05863c4737af --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_fpga_driver.h @@ -0,0 +1,100 @@ +/* + * A header definition for wb_fpga_driver driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _WB_FPGA_DRIVER_H_ +#define _WB_FPGA_DRIVER_H_ + +/** + * dfd_get_fpga_name -Get the FPGA name + * @main_dev_id: Motherboard :0 Subcard :5 + * @index:Number of the FPGA, starting from 1 + * @buf: Receive buf + * @count: Receive buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fpga_name(uint8_t main_dev_id, unsigned int fpga_index, char *buf, size_t count); + +/** + * dfd_get_fpga_type - Get FPGA model + * @main_dev_id: Motherboard :0 Subcard :5 + * @index:Number of the FPGA, starting from 1 + * @buf: Receive buf + * @count: Receive buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fpga_type(uint8_t main_dev_id, unsigned int fpga_index, char *buf, size_t count); + +/** + * dfd_get_fpga_fw_version - Obtain the FPGA firmware version + * @main_dev_id: Motherboard :0 Subcard :5 + * @index:Number of the FPGA, starting from 1 + * @buf: Receive buf + * @count: Receive buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fpga_fw_version(uint8_t main_dev_id, unsigned int fpga_index, char *buf, size_t count); + +/** + * dfd_get_fpga_hw_version - Obtain the hardware version of the FPGA + * @main_dev_id: Motherboard :0 Subcard :5 + * @index:Number of the FPGA, starting from 1 + * @buf: Receive buf + * @count: Receive buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fpga_hw_version(uint8_t main_dev_id, unsigned int fpga_index, char *buf, size_t count); + +/** + * dfd_set_fpga_testreg - Sets the value of the FPGA test register + * @main_dev_id: Motherboard :0 Subcard :5 + * @fpga_index:Number of the FPGA, starting from 1 + * @value: Writes the value of the test register + * return: Success :0 + * : Failed: A negative value is returned + */ +int dfd_set_fpga_testreg(uint8_t main_dev_id, unsigned int fpga_index, int value); + +/** + * dfd_get_fpga_testreg - Read the FPGA test register value + * @main_dev_id: Motherboard :0 Subcard :5 + * @fpga_index: Number of the FPGA, starting from 1 + * @value: Read the test register value + * return: Success :0 + * : Failed: A negative value is returned + */ +int dfd_get_fpga_testreg(uint8_t main_dev_id, unsigned int fpga_index, int *value); + +/** + * dfd_get_fpga_testreg_str - Read the FPGA test register value + * @main_dev_id: Motherboard :0 Subcard :5 + * @fpga_index:Number of the FPGA, starting from 1 + * @buf: Receive buf + * @count: Receive buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fpga_testreg_str(uint8_t main_dev_id, unsigned int fpga_index, + char *buf, size_t count); + +#endif /* _WB_FPGA_DRIVER_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_led_driver.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_led_driver.h new file mode 100644 index 000000000000..bac7b23d9836 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_led_driver.h @@ -0,0 +1,45 @@ +/* + * A header definition for wb_led_driver driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _WB_LED_DRIVER_H_ +#define _WB_LED_DRIVER_H_ + +/** + * dfd_get_led_status - Get LED and other status + * @led_id: led lamp type + * @led_index: led light offset + * @buf: LED light status receives buf + * @count: Accept the buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_led_status(uint16_t led_id, uint8_t led_index, char *buf, size_t count); + +/** + * dfd_set_led_status - Set LED light status + * @led_id: led lamp type + * @led_index: led light offset + * @value: LED light status value + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_set_led_status(uint16_t led_id, uint8_t led_index, int value); + +#endif /* _WB_LED_DRIVER_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_module.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_module.h new file mode 100644 index 000000000000..6bce2817cb13 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_module.h @@ -0,0 +1,360 @@ +/* + * A header definition for wb_module driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _WB_MODULE_H_ +#define _WB_MODULE_H_ + +#include "switch_driver.h" + +#define mem_clear(data, size) memset((data), 0, (size)) +typedef enum dfd_rv_s { + DFD_RV_OK = 0, + DFD_RV_INIT_ERR = 1, + DFD_RV_SLOT_INVALID = 2, + DFD_RV_MODE_INVALID = 3, + DFD_RV_MODE_NOTSUPPORT = 4, + DFD_RV_TYPE_ERR = 5, + DFD_RV_DEV_NOTSUPPORT = 6, + DFD_RV_DEV_FAIL = 7, + DFD_RV_INDEX_INVALID = 8, + DFD_RV_NO_INTF = 9, + DFD_RV_NO_NODE = 10, + DFD_RV_NODE_FAIL = 11, + DFD_RV_INVALID_VALUE = 12, + DFD_RV_NO_MEMORY = 13, + DFD_RV_CHECK_FAIL = 14, +} dfd_rv_t; + +typedef enum status_mem_e { + STATUS_ABSENT = 0, + STATUS_OK = 1, + STATUS_NOT_OK = 2, + STATUS_MEM_END = 3, +} status_mem_t; + +/* psu PMBUS */ +typedef enum psu_sensors_type_e { + PSU_SENSOR_NONE = 0, + PSU_IN_VOL = 1, + PSU_IN_CURR = 2, + PSU_IN_POWER = 3, + PSU_OUT_VOL = 4, + PSU_OUT_CURR = 5, + PSU_OUT_POWER = 6, + PSU_FAN_SPEED = 7, + PSU_OUT_MAX_POWERE = 8, + PSU_OUT_STATUS = 9, + PSU_IN_STATUS = 10, + PSU_IN_TYPE = 11, + PSU_FAN_RATIO = 12, + PSU_IN_VOL_MAX = 13, + PSU_IN_CURR_MAX = 14, + PSU_IN_VOL_MIN = 15, + PSU_IN_CURR_MIN = 16, + PSU_OUT_VOL_MAX = 17, + PSU_OUT_CURR_MAX = 18, + PSU_OUT_VOL_MIN = 19, + PSU_OUT_CURR_MIN = 20, + PSU_FAN_SPEED_MAX = 21, + PSU_FAN_SPEED_MIN = 22, + PSU_IN_POWER_MAX = 23, + PSU_IN_POWER_MIN = 24, + PSU_OUT_POWER_MAX = 25, + PSU_OUT_POWER_MIN = 26, + PSU_HW_STATUS = 27, +} psu_sensors_type_t; + +/* Watchdog type */ +typedef enum wb_wdt_type_e { + WB_WDT_TYPE_NAME = 0, /* watchdog identify */ + WB_WDT_TYPE_STATE = 1, /* watchdog state */ + WB_WDT_TYPE_TIMELEFT = 2, /* watchdog timeleft */ + WB_WDT_TYPE_TIMEOUT = 3, /* watchdog timeout */ + WB_WDT_TYPE_ENABLE = 4, /* watchdog enable */ +} wb_wdt_type_t; + +/* Port Power Status */ +typedef enum wb_port_power_status_e { + WB_PORT_POWER_OFF = 0, /* port power off */ + WB_PORT_POWER_ON = 1, /* port power on */ +} wb_port_power_status_t; + +/* sensor monitor or not */ +typedef enum wb_sensor_monitor_flag_e { + WB_SENSOR_MONITOR_NO = 0, /* sensor not monitor */ + WB_SENSOR_MONITOR_YES = 1, /* sensor monitor */ +} wb_sensor_monitor_flag_t; + +typedef enum dfd_dev_info_type_e { + DFD_DEV_INFO_TYPE_MAC = 1, + DFD_DEV_INFO_TYPE_NAME = 2, + DFD_DEV_INFO_TYPE_SN = 3, + DFD_DEV_INFO_TYPE_PWR_CONS = 4, + DFD_DEV_INFO_TYPE_HW_INFO = 5, + DFD_DEV_INFO_TYPE_DEV_TYPE = 6, + DFD_DEV_INFO_TYPE_PART_NAME = 7, + DFD_DEV_INFO_TYPE_PART_NUMBER = 8, /* part number */ + DFD_DEV_INFO_TYPE_FAN_DIRECTION = 9, + DFD_DEV_INFO_TYPE_MAX_OUTPUT_POWRER = 10, /* max_output_power */ + DFD_DEV_INFO_TYPE_SPEED_CAL = 11, + DFD_DEV_INFO_TYPE_ASSET_TAG = 12, + DFD_DEV_INFO_TYPE_VENDOR = 13, +} dfd_dev_tlv_type_t; + +/* Master device type */ +typedef enum wb_main_dev_type_e { + WB_MAIN_DEV_MAINBOARD = 0, /* Main board */ + WB_MAIN_DEV_FAN = 1, /* FAN */ + WB_MAIN_DEV_PSU = 2, /* PSU */ + WB_MAIN_DEV_SFF = 3, /* Optical module */ + WB_MAIN_DEV_CPLD = 4, /* CPLD */ + WB_MAIN_DEV_SLOT = 5, /* Daughter card */ +} wb_main_dev_type_t; + +/* Subdevice type */ +typedef enum wb_minor_dev_type_e { + WB_MINOR_DEV_NONE = 0, /* None */ + WB_MINOR_DEV_TEMP = 1, /* temperature*/ + WB_MINOR_DEV_IN = 2, /* voltage */ + WB_MINOR_DEV_CURR = 3, /* current */ + WB_MINOR_DEV_POWER = 4, /* power */ + WB_MINOR_DEV_MOTOR = 5, /* motor */ + WB_MINOR_DEV_PSU = 6, /* Power supply type */ + WB_MINOR_DEV_FAN = 7, /* Fan model */ + WB_MINOR_DEV_CPLD = 8, /* CPLD */ + WB_MINOR_DEV_FPGA = 9, /* FPGA */ + WB_MINOR_DEV_EEPROM = 10, /* EEPROM */ +} wb_minor_dev_type_t; + +/* SENSORS attribute type */ +typedef enum wb_sensor_type_e { + WB_SENSOR_INPUT = 0, /* Sensor value */ + WB_SENSOR_ALIAS = 1, /* Sensor nickname */ + WB_SENSOR_TYPE = 2, /* Sensor type*/ + WB_SENSOR_MAX = 3, /* Sensor maximum */ + WB_SENSOR_MAX_HYST = 4, /* Sensor hysteresis value */ + WB_SENSOR_MIN = 5, /* Sensor minimum */ + WB_SENSOR_CRIT = 6, /* Sensor crit value */ + WB_SENSOR_RANGE = 7, /* Sensor error value */ + WB_SENSOR_NOMINAL_VAL = 8, /* Nominal value of the sensor */ + WB_SENSOR_HIGH = 9, /* Sensor height */ + WB_SENSOR_LOW = 10, /* Sensor low */ +} wb_sensor_type_t; + +/* sff cpld attribute type */ +typedef enum wb_sff_cpld_attr_e { + WB_SFF_POWER_ON = 0x01, + WB_SFF_TX_FAULT, + WB_SFF_TX_DIS, + WB_SFF_PRESENT_RESERVED, + WB_SFF_RX_LOS, + WB_SFF_RESET, + WB_SFF_LPMODE, + WB_SFF_MODULE_PRESENT, + WB_SFF_INTERRUPT, +} wb_sff_cpld_attr_t; + +/* LED attribute type */ +typedef enum wb_led_e { + WB_SYS_LED_FRONT = 0, /* Front panel SYS light */ + WB_SYS_LED_REAR = 1, /* SYS light on rear panel */ + WB_BMC_LED_FRONT = 2, /* BMC indicator on the front panel */ + WB_BMC_LED_REAR = 3, /* BMC indicator on the rear panel */ + WB_FAN_LED_FRONT = 4, /* Front panel fan light */ + WB_FAN_LED_REAR = 5, /* Rear panel fan light */ + WB_PSU_LED_FRONT = 6, /* Front panel power light */ + WB_PSU_LED_REAR = 7, /* Rear panel power light */ + WB_ID_LED_FRONT = 8, /* Front panel positioning light */ + WB_ID_LED_REAR = 9, /* Rear panel positioning light */ + WB_FAN_LED_MODULE = 10, /* Fan module indicator */ + WB_PSU_LED_MODULE = 11, /* Power module indicator */ + WB_SLOT_LED_MODULE = 12, /* Sub-card status indicator */ +} wb_led_t; + +extern int g_dfd_dbg_level; +extern int g_dfd_fan_dbg_level; +extern int g_dfd_fru_dbg_level; +extern int g_dfd_eeprom_dbg_level; +extern int g_dfd_cpld_dbg_level; +extern int g_dfd_fpga_dbg_level; +extern int g_dfd_sysled_dbg_level; +extern int g_dfd_slot_dbg_level; +extern int g_dfd_sensor_dbg_level; +extern int g_dfd_psu_dbg_level; +extern int g_dfd_sff_dbg_level; +extern int g_dfd_watchdog_dbg_level; +extern int g_dfd_custom_dbg_level; + +#define WB_MIN(a, b) ((a) < (b) ? (a) : (b)) +#define WB_MAX(a, b) ((a) > (b) ? (a) : (b)) + +#define DBG_DEBUG(level, fmt, arg...) do { \ + if (g_dfd_dbg_level & level) { \ + if (level >= DBG_ERROR) { \ + printk(KERN_ERR "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } else { \ + printk(KERN_INFO "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } \ + } \ +} while (0) + +#define DFD_FAN_DEBUG(level, fmt, arg...) do { \ + if (g_dfd_fan_dbg_level & level) { \ + if (level >= DBG_ERROR) { \ + printk(KERN_ERR "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } else { \ + printk(KERN_INFO "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } \ + } \ +} while (0) + +#define DBG_FRU_DEBUG(level, fmt, arg...) do { \ + if (g_dfd_fru_dbg_level & level) { \ + if (level >= DBG_ERROR) { \ + printk(KERN_ERR "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } else { \ + printk(KERN_INFO "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } \ + } \ +} while (0) + +#define DBG_EEPROM_DEBUG(level, fmt, arg...) do { \ + if (g_dfd_eeprom_dbg_level & level) { \ + if (level >= DBG_ERROR) { \ + printk(KERN_ERR "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } else { \ + printk(KERN_INFO "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } \ + } \ +} while (0) + +#define DBG_CPLD_DEBUG(level, fmt, arg...) do { \ + if (g_dfd_cpld_dbg_level & level) { \ + if (level >= DBG_ERROR) { \ + printk(KERN_ERR "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } else { \ + printk(KERN_INFO "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } \ + } \ +} while (0) + +#define DBG_FPGA_DEBUG(level, fmt, arg...) do { \ + if (g_dfd_fpga_dbg_level & level) { \ + if (level >= DBG_ERROR) { \ + printk(KERN_ERR "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } else { \ + printk(KERN_INFO "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } \ + } \ +} while (0) + +#define DBG_SYSLED_DEBUG(level, fmt, arg...) do { \ + if (g_dfd_sysled_dbg_level & level) { \ + if (level >= DBG_ERROR) { \ + printk(KERN_ERR "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } else { \ + printk(KERN_INFO "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } \ + } \ +} while (0) + +#define DFD_SLOT_DEBUG(level, fmt, arg...) do { \ + if (g_dfd_slot_dbg_level & level) { \ + if (level >= DBG_ERROR) { \ + printk(KERN_ERR "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } else { \ + printk(KERN_INFO "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } \ + } \ +} while (0) + +#define DFD_SENSOR_DEBUG(level, fmt, arg...) do { \ + if (g_dfd_sensor_dbg_level & level) { \ + if (level >= DBG_ERROR) { \ + printk(KERN_ERR "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } else { \ + printk(KERN_INFO "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } \ + } \ +} while (0) + +#define DFD_PSU_DEBUG(level, fmt, arg...) do { \ + if (g_dfd_psu_dbg_level & level) { \ + if (level >= DBG_ERROR) { \ + printk(KERN_ERR "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } else { \ + printk(KERN_INFO "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } \ + } \ +} while (0) + +#define DFD_SFF_DEBUG(level, fmt, arg...) do { \ + if (g_dfd_sff_dbg_level & level) { \ + if (level >= DBG_ERROR) { \ + printk(KERN_ERR "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } else { \ + printk(KERN_INFO "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } \ + } \ +} while (0) + +#define DFD_WDT_DEBUG(level, fmt, arg...) do { \ + if (g_dfd_watchdog_dbg_level & level) { \ + if (level >= DBG_ERROR) { \ + printk(KERN_ERR "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } else { \ + printk(KERN_INFO "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } \ + } \ +} while (0) + +#define DFD_SYSTEM_DEBUG(level, fmt, arg...) do { \ + if (g_dfd_custom_dbg_level & level) { \ + if (level >= DBG_ERROR) { \ + printk(KERN_ERR "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } else { \ + printk(KERN_INFO "[DBG-%d]:<%s, %d>:"fmt, level, __FUNCTION__, __LINE__, ##arg); \ + } \ + } \ +} while (0) + +/** + * wb_dev_cfg_init - dfd module initialization + * + * @returns: <0 Failed, otherwise succeeded + */ +int32_t wb_dev_cfg_init(void); + +/** + * wb_dev_cfg_exit - dfd module exit + * + * @returns: void + */ + +void wb_dev_cfg_exit(void); + +/** + * dfd_get_dev_number - Get the number of devices + * @main_dev_id:Master device number + * @minor_dev_id:Secondary device number + * @returns: <0 failed, otherwise number of devices is returned + */ +int dfd_get_dev_number(unsigned int main_dev_id, unsigned int minor_dev_id); +#endif /* _WB_MODULE_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_psu_driver.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_psu_driver.h new file mode 100644 index 000000000000..5de93f46bd11 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_psu_driver.h @@ -0,0 +1,114 @@ +/* + * A header definition for wb_psu_driver driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _WB_PSU_DRIVER_H_ +#define _WB_PSU_DRIVER_H_ + +/** + * dfd_get_psu_info - Get Power Information + * @index: Number of the power supply, starting from 1 + * @cmd: Power supply information Type, power supply name :2, power supply serial number :3, power supply hardware version :5 + * @buf: Receive buf + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_psu_info(unsigned int psu_index, uint8_t cmd, char *buf, size_t count); + +/** + * dfd_get_psu_present_status_str - Get Power status + * @index: Number of the power supply, starting from 1 + * return: Success: Length of the status string + * : Negative value - Read failed + */ +ssize_t dfd_get_psu_present_status_str(unsigned int psu_index, char *buf, size_t count); + +/** + * dfd_get_psu_out_status_str - Get the output power status + * @index: Number of the power supply, starting from 1 + * return: Success: Length of the status string + * : Negative value - Read failed + */ +ssize_t dfd_get_psu_out_status_str(unsigned int psu_index, char *buf, size_t count); + +/** + * dfd_get_psu_status_pmbus_str - Gets the value on the pmbus register of the power supply + * @index: Number of the power supply, starting from 1 + * return: Success: Length of the status string + * : Negative value - Read failed + */ +ssize_t dfd_get_psu_status_pmbus_str(unsigned int psu_index, char *buf, size_t count); + +/** + * dfd_get_psu_in_status_str - Get the input power status + * @index: Number of the power supply, starting from 1 + * return: Success: Length of the status string + * : Negative value - Read failed + */ +ssize_t dfd_get_psu_in_status_str(unsigned int psu_index, char *buf, size_t count); + +/** + * dfd_get_psu_input_type - Get the power input type + * @index: Number of the power supply, starting from 1 + * @buf: Receive buf + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_psu_input_type(unsigned int psu_index, char *buf, size_t count); + +/** + * dfd_get_psu_alarm_status - Get power PMBUS WORD STATUS status + * @index: Number of the power supply, starting from 1 + * return: Success:return psu output status + * : Failed: A negative value is returned + */ +ssize_t dfd_get_psu_alarm_status(unsigned int psu_index, char *buf, size_t count); + +/** + * dfd_get_psu_fan_ratio_str - Gets the target fan rotation rate + * @index: Number of the power supply, starting from 1 + * return: Success: Length of the status string + * : Negative value - Read failed + */ +ssize_t dfd_get_psu_fan_ratio_str(unsigned int psu_index, char *buf, size_t count); +ssize_t dfd_set_psu_fan_ratio_str(unsigned int psu_index, int pwm); +/** + * dfd_get_psu_pmbus_status - Get power Status Word + * @index: Number of the power supply, starting from 1 + * return: Success: Length of the status string + * : Negative value - Read failed + */ +ssize_t dfd_get_psu_pmbus_status(unsigned int psu_index, char *buf, size_t count); +/** + * dfd_get_psu_present_status - Obtain the power supply status + * @index: Number of the power supply, starting from 1 + * return: 0:Not in the position + * 1:position + * : Negative value - Read failed + */ +int dfd_get_psu_present_status(unsigned int psu_index); + +ssize_t dfd_get_psu_threshold_str(unsigned int psu_index, unsigned int type, char *buf, size_t count); + +ssize_t dfd_get_psu_hw_status_str(unsigned int psu_index, char *buf, size_t count); + +ssize_t dfd_get_psu_blackbox(unsigned int psu_index, char *buf, size_t count); +ssize_t dfd_get_psu_pmbus(unsigned int psu_index, char *buf, size_t count); +int dfd_clear_psu_blackbox(unsigned int psu_index, uint8_t value); +#endif /* _WB_PSU_DRIVER_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_sensors_driver.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_sensors_driver.h new file mode 100644 index 000000000000..d33ee3217e37 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_sensors_driver.h @@ -0,0 +1,82 @@ +/* + * A header definition for wb_sensors_driver driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _WB_SENSORS_DRIVER_H_ +#define _WB_SENSORS_DRIVER_H_ + +/** + * dfd_get_temp_info - Get temperature information + * @main_dev_id: Motherboard :0 Power supply :2 subcard :5 + * @dev_index: If no device index exists, the value is 0, and 1 indicates slot1/psu1 + * @temp_index: Temperature index, starting at 1 + * @temp_type: Read type,1:alias 2:type 3:max 4:max_hyst 5:min 6:input + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_temp_info(uint8_t main_dev_id, uint8_t dev_index, uint8_t temp_index, + uint8_t temp_attr, char *buf, size_t count); + +/** + * dfd_get_voltage_info - Get voltage information + * @main_dev_id: Motherboard :0 Subcard :5 + * @dev_index: If no device index exists, the value is 0, and 1 indicates slot1 + * @in_index: Voltage index, starting at 1 + * @in_type:Voltage type,1:alias 2:type 3:max 4:max_hyst 5:min 6:input + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_voltage_info(uint8_t main_dev_id, uint8_t dev_index, uint8_t in_index, + uint8_t in_attr, char *buf, size_t count); + +/** + * dfd_get_current_info - Get current information + * @main_dev_id: Motherboard :0 Subcard :5 + * @dev_index: If no device index exists, the value is 0, and 1 indicates slot1 + * @in_index: Current index, starting at 1 + * @in_type: Current type,1:alias 2:type 3:max 4:max_hyst 5:min 6:input + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_current_info(uint8_t main_dev_id, uint8_t dev_index, uint8_t curr_index, + uint8_t curr_attr, char *buf, size_t count); + +/** + * dfd_get_psu_sensor_info - Obtain PMBUS information about the power supply + * @psu_index: Power index, starting at 1 + * @sensor_type: Type of the obtained pmbus information + * @buf: pmbus results are stored in buf + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_psu_sensor_info(uint8_t psu_index, uint8_t sensor_type, char *buf, size_t count); + + +/** + * dfd_get_main_board_monitor_flag - Get Monitor flag info + * @main_dev_id: Motherboard :0 Power supply :2 subcard :5 + * @dev_index: If no device index exists, the value is 0, and 1 indicates slot1 + * @sensor_type: Type of the obtained pmbus information + * @in_type: Voltage type,1:alias 2:type 3:max 4:max_hyst 5:min 6:input + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +int dfd_get_main_board_monitor_flag(uint8_t main_dev_id, uint8_t dev_index, uint8_t sensor_type, + uint8_t sensor_index, char *buf, size_t count); +#endif /* _WB_SENSORS_DRIVER_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_sff_driver.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_sff_driver.h new file mode 100644 index 000000000000..e26e12805de6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_sff_driver.h @@ -0,0 +1,63 @@ +/* + * A header definition for wb_sff_driver driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _WB_SFF_DRIVER_H_ +#define _WB_SFF_DRIVER_H_ + +/** + * dfd_set_sff_cpld_info - Example Set the CPLD register status of the optical module + * @sff_index: Optical module number, starting from 1 + * @cpld_reg_type: Optical module CPLD register type + * @value: Writes the value to the register + * return: Success :0 + * : Failed: A negative value is returned + */ +int dfd_set_sff_cpld_info(unsigned int sff_index, int cpld_reg_type, int value); + +/** + * dfd_get_sff_cpld_info - Obtain the CPLD register status of the optical module + * @sff_index: Optical module number, starting from 1 + * @cpld_reg_type: Optical module CPLD register type + * @buf: Optical module E2 receives information from buf + * @count: buf length + * return: Success: Returns the length of fill buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_sff_cpld_info(unsigned int sff_index, int cpld_reg_type, char *buf, size_t count); + +/** + * dfd_get_single_eth_optoe_type - get sff optoe type + * @sff_index: Optical module number, starting from 1 + * @optoe_type: Optical module type + * return: Success: Returns the length of fill buf + * : Failed: A negative value is returned + */ +int dfd_get_single_eth_optoe_type(unsigned int sff_index, int *optoe_type); + +/** + * dfd_set_single_eth_optoe_type - set sff optoe type + * @sff_index: Optical module number, starting from 1 + * @optoe_type: Optical module type + * return: Success: Returns the length of fill buf + * : Failed: A negative value is returned + */ +int dfd_set_single_eth_optoe_type(unsigned int sff_index, int optoe_type); + +#endif /* _WB_SFF_DRIVER_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_slot_driver.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_slot_driver.h new file mode 100644 index 000000000000..7978fa5b7698 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_slot_driver.h @@ -0,0 +1,64 @@ +/* + * A header definition for wb_slot_driver driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _WB_SLOT_DRIVER_H_ +#define _WB_SLOT_DRIVER_H_ + +/** + * dfd_get_slot_status_str - Gets the subcard status + * @slot_index: Number of the sub-card, starting from 1 + * @buf: Receive buf + * @count: Receive buf length + * return: Success: Length of the status string + * : Negative value - Read failed + */ +ssize_t dfd_get_slot_status_str(unsigned int slot_index, char *buf, size_t count); + +/** + * dfd_get_slot_info - Obtain the subcard information + * @slot_index: Number of the sub-card, starting from 1 + * @cmd: Card information type, sub-card name :2, sub-card serial number :3, sub-card hardware version number :5 + * @buf: Receive buf + * @count: Receive buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_slot_info(unsigned int slot_index, uint8_t cmd, char *buf, size_t count); + +/** + * dfd_get_slot_power_status_str - get power status of slot + * @slot_index: Number of the sub-card, starting from 1 + * @buf: Receive buf + * @count: Receive buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_slot_power_status_str(unsigned int slot_index, char *buf, size_t count); + +/** + * dfd_set_slot_power_status_str - set power status of slot + * @slot_index: Number of the sub-card, starting from 1 + * @value: Power status of slot + * return: Success: 0 is returned + * : Failed: A negative value is returned + */ +int dfd_set_slot_power_status_str(unsigned int slot_index, int value); + +#endif /* _WB_SLOT_DRIVER_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_system_driver.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_system_driver.h new file mode 100644 index 000000000000..2298c5bb11b1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_system_driver.h @@ -0,0 +1,33 @@ +/* + * A header definition for wb_system_driver driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _SYSTEM_DRIVER_H_ +#define _SYSTEM_DRIVER_H_ + +typedef enum module_pwr_status_e { + MODULE_POWER_OFF = 0, + MODULE_POWER_ON, +} module_pwr_status_t; + +ssize_t dfd_system_get_system_value(unsigned int type, int *value); +ssize_t dfd_system_set_system_value(unsigned int type, int value); +ssize_t dfd_system_get_port_power_status(unsigned int type, char *buf, size_t count); + +#endif /* _SYSTEM_DRIVER_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_watchdog_driver.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_watchdog_driver.h new file mode 100644 index 000000000000..c59bd64e692a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/include/wb_watchdog_driver.h @@ -0,0 +1,37 @@ +/* + * A header definition for wb_watchdog_driver driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _WB_WATCHDOG_DRIVER_H_ +#define _WB_WATCHDOG_DRIVER_H_ + +/** + * dfd_get_watchdog_info - Get watchdog information + * @type: Watchdog information type + * @buf: Receive buf + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_watchdog_info(uint8_t type, char *buf, size_t count); + +ssize_t dfd_watchdog_get_status_str(char *buf, size_t count); +ssize_t dfd_watchdog_get_status(char *buf, size_t count); +ssize_t dfd_watchdog_set_status(int value); + +#endif /* _WB_WATCHDOG_DRIVER_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/switch_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/switch_driver.c new file mode 100644 index 000000000000..5628aadab430 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/switch_driver.c @@ -0,0 +1,4577 @@ +/* + * An switch_driver driver for switch devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include + +#include "dfd_sysfs_common.h" +#include "switch_driver.h" +#include "wb_module.h" +#include "wb_fan_driver.h" +#include "wb_eeprom_driver.h" +#include "wb_cpld_driver.h" +#include "wb_fpga_driver.h" +#include "wb_led_driver.h" +#include "wb_slot_driver.h" +#include "wb_sensors_driver.h" +#include "wb_psu_driver.h" +#include "wb_sff_driver.h" +#include "wb_watchdog_driver.h" +#include "wb_system_driver.h" +#include "dfd_cfg.h" + +int g_switch_dbg_level = 0; + +/* change the following parameter by your switch. */ +#define MAIN_BOARD_TEMP_SENSOR_NUMBER (10) +#define MAIN_BOARD_VOL_SENSOR_NUMBER (10) +#define MAIN_BOARD_CURR_SENSOR_NUMBER (0) +#define SYSEEPROM_SIZE (256) +#define FAN_NUMBER (6) +#define FAN_MOTOR_NUMBER (2) +#define PSU_NUMBER (2) +#define PSU_TEMP_SENSOR_NUMBER (3) +#define ETH_NUMBER (32) +#define ETH_EEPROM_SIZE (0x8180) +#define MAIN_BOARD_FPGA_NUMBER (1) +#define MAIN_BOARD_CPLD_NUMBER (5) +#define SLOT_NUMBER (0) +#define SLOT_TEMP_NUMBER (0) +#define SLOT_VOL_NUMBER (0) +#define SLOT_CURR_NUMBER (0) +#define SLOT_FPGA_NUMBER (0) +#define SLOT_CPLD_NUMBER (0) + +/***************************************main board temp*****************************************/ +/* + * dfd_get_main_board_temp_number - Used to get main board temperature sensors number, + * + * This function returns main board temperature sensors by your switch, + * If there is no main board temperature sensors, returns 0, + * otherwise it returns a negative value on failed. + */ +static int dfd_get_main_board_temp_number(void) +{ + int ret; + + ret = dfd_get_dev_number(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_TEMP); + return ret; +} + +/* + * dfd_get_main_board_temp_alias - Used to identify the location of the temperature sensor, + * such as air_inlet, air_outlet and so on. + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_temp_alias(unsigned int temp_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_temp_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, temp_index, WB_SENSOR_ALIAS, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_temp_type - Used to get the model of temperature sensor, + * such as lm75, tmp411 and so on + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_temp_type(unsigned int temp_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_temp_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, temp_index, WB_SENSOR_TYPE, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_temp_max - Used to get the maximum threshold of temperature sensor + * filled the value to buf, the value is integer with millidegree Celsius + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_temp_max(unsigned int temp_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_temp_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, temp_index, WB_SENSOR_MAX, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_temp_min - Used to get the minimum threshold of temperature sensor + * filled the value to buf, the value is integer with millidegree Celsius + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_temp_min(unsigned int temp_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_temp_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, temp_index, WB_SENSOR_MIN, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_temp_high - Used to get the high threshold of temperature sensor + * filled the value to buf, the value is integer with millidegree Celsius + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_temp_high(unsigned int temp_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_temp_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, temp_index, WB_SENSOR_HIGH, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_temp_low - Used to get the low threshold of temperature sensor + * filled the value to buf, the value is integer with millidegree Celsius + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_temp_low(unsigned int temp_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_temp_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, temp_index, WB_SENSOR_LOW, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_temp_value - Used to get the input value of temperature sensor + * filled the value to buf, the value is integer with millidegree Celsius + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_temp_value(unsigned int temp_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_temp_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, temp_index, WB_SENSOR_INPUT, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_temp_monitor_flag - Used to get monitor flag of temperature sensor + * filled the value to buf, the value is integer + * @index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_temp_monitor_flag(unsigned int index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_main_board_monitor_flag(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, WB_MINOR_DEV_TEMP, index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} +/***********************************end of main board temp*************************************/ + +/*************************************main board voltage***************************************/ +static int dfd_get_main_board_vol_number(void) +{ + int ret; + + ret = dfd_get_dev_number(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_IN); + return ret; +} + +/* + * dfd_get_main_board_vol_alias - Used to identify the location of the voltage sensor, + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_vol_alias(unsigned int vol_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_voltage_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, vol_index, WB_SENSOR_ALIAS, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_vol_type - Used to get the model of voltage sensor, + * such as udc90160, tps53622 and so on + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_vol_type(unsigned int vol_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_voltage_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, vol_index, WB_SENSOR_TYPE, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_vol_max - Used to get the maximum threshold of voltage sensor + * filled the value to buf, the value is integer with mV + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_vol_max(unsigned int vol_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_voltage_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, vol_index, WB_SENSOR_MAX, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_vol_min - Used to get the minimum threshold of voltage sensor + * filled the value to buf, the value is integer with mV + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_vol_min(unsigned int vol_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_voltage_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, vol_index, WB_SENSOR_MIN, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_vol_range - Used to get the output error value of voltage sensor + * filled the value to buf + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_vol_range(unsigned int vol_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_voltage_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, vol_index, + WB_SENSOR_RANGE, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_vol_nominal_value - Used to get the nominal value of voltage sensor + * filled the value to buf + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_vol_nominal_value(unsigned int vol_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_voltage_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, vol_index, + WB_SENSOR_NOMINAL_VAL, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_vol_value - Used to get the input value of voltage sensor + * filled the value to buf, the value is integer with mV + * @vol_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_vol_value(unsigned int vol_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_voltage_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, vol_index, WB_SENSOR_INPUT, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_vol_monitor_flag - Used to get monitor flag of voltage sensor + * filled the value to buf, the value is integer + * @temp_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_vol_monitor_flag(unsigned int temp_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_main_board_monitor_flag(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, WB_MINOR_DEV_IN, temp_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} +/*********************************end of main board voltage************************************/ +/*************************************main board current***************************************/ +static int dfd_get_main_board_curr_number(void) +{ + int ret; + + ret = dfd_get_dev_number(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_CURR); + return ret; +} + +/* + * dfd_get_main_board_curr_alias - Used to identify the location of the current sensor, + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_curr_alias(unsigned int curr_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_current_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, curr_index, WB_SENSOR_ALIAS, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_curr_type - Used to get the model of current sensor, + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_curr_type(unsigned int curr_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_current_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, curr_index, WB_SENSOR_TYPE, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_curr_max - Used to get the maximum threshold of current sensor + * filled the value to buf, the value is integer with mA + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_curr_max(unsigned int curr_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_current_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, curr_index, WB_SENSOR_MAX, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_curr_min - Used to get the minimum threshold of current sensor + * filled the value to buf, the value is integer with mA + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_curr_min(unsigned int curr_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_current_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, curr_index, WB_SENSOR_MIN, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_curr_value - Used to get the input value of current sensor + * filled the value to buf, the value is integer with mA + * @curr_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_curr_value(unsigned int curr_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_current_info(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, curr_index, WB_SENSOR_INPUT, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_curr_monitor_flag - Used to get monitor flag of current sensor + * filled the value to buf, the value is integer + * @index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_curr_monitor_flag(unsigned int index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_main_board_monitor_flag(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_NONE, WB_MINOR_DEV_CURR, index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} +/*********************************end of main board current************************************/ + +/*****************************************syseeprom*******************************************/ +/* + * dfd_get_syseeprom_size - Used to get syseeprom size + * + * This function returns the size of syseeprom by your switch, + * otherwise it returns a negative value on failed. + */ +static int dfd_get_syseeprom_size(void) +{ + int ret; + + ret = dfd_get_eeprom_size(WB_MAIN_DEV_MAINBOARD, 0); + return ret; +} + +/* + * dfd_read_syseeprom_data - Used to read syseeprom data, + * @buf: Data read buffer + * @offset: offset address to read syseeprom data + * @count: length of buf + * + * This function returns the length of the filled buffer, + * returns 0 means EOF, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_read_syseeprom_data(char *buf, loff_t offset, size_t count) +{ + ssize_t ret; + + ret = dfd_read_eeprom_data(WB_MAIN_DEV_MAINBOARD, 0, buf, offset, count); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + +/* + * dfd_write_syseeprom_data - Used to write syseeprom data + * @buf: Data write buffer + * @offset: offset address to write syseeprom data + * @count: length of buf + * + * This function returns the written length of syseeprom, + * returns 0 means EOF, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_write_syseeprom_data(char *buf, loff_t offset, size_t count) +{ + ssize_t ret; + + ret = dfd_write_eeprom_data(WB_MAIN_DEV_MAINBOARD, 0, buf, offset, count); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} +/*************************************end of syseeprom****************************************/ + +/********************************************fan**********************************************/ +static int dfd_get_fan_number(void) +{ + int ret; + + ret = dfd_get_dev_number(WB_MAIN_DEV_FAN, WB_MINOR_DEV_NONE); + return ret; +} + +/* + * dfd_get_fan_status - Used to get fan status, + * filled the value to buf, fan status define see enum status_e + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_fan_status(unsigned int fan_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_fan_status_str(fan_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_fan_present - Used to get fan present status, + * filled the value to buf, fan status define see enum status_e + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_fan_present(unsigned int fan_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_fan_present_str(fan_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +static int dfd_get_fan_motor_number(unsigned int fan_index) +{ + int ret; + + ret = dfd_get_dev_number(WB_MAIN_DEV_FAN, WB_MINOR_DEV_MOTOR); + return ret; +} + +/* + * dfd_get_fan_model_name - Used to get fan model name, + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_fan_model_name(unsigned int fan_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_fan_present_status(fan_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_fan_info(fan_index, DFD_DEV_INFO_TYPE_NAME, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_fan_vendor - Used to get fan vendor, + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_fan_vendor(unsigned int fan_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_fan_present_status(fan_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_fan_info(fan_index, DFD_DEV_INFO_TYPE_VENDOR, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_fan_serial_number - Used to get fan serial number, + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_fan_serial_number(unsigned int fan_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_fan_present_status(fan_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_fan_info(fan_index, DFD_DEV_INFO_TYPE_SN, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_fan_part_number - Used to get fan part number, + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_fan_part_number(unsigned int fan_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_fan_present_status(fan_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_fan_info(fan_index, DFD_DEV_INFO_TYPE_PART_NUMBER, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_fan_hardware_version - Used to get fan hardware version, + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_fan_hardware_version(unsigned int fan_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_fan_present_status(fan_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_fan_info(fan_index, DFD_DEV_INFO_TYPE_HW_INFO, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_fan_led_status - Used to get fan led status + * filled the value to buf, led status value define see enum fan_status_e + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_fan_led_status(unsigned int fan_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_led_status(WB_FAN_LED_MODULE, fan_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_set_fan_led_status - Used to set fan led status + * @fan_index: start with 1 + * @status: led status, led status value define see enum led_status_e + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int dfd_set_fan_led_status(unsigned int fan_index, int status) +{ + int ret; + + ret = dfd_set_led_status(WB_FAN_LED_MODULE, fan_index, status); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + +/* + * dfd_get_fan_direction - Used to get fan air flow direction, + * filled the value to buf, air flow direction define see enum air_flow_direction_e + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_fan_direction(unsigned int fan_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_fan_present_status(fan_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_fan_direction_str(fan_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_fan_motor_status - Used to get fan motor status + * filled the value to buf + * @fan_index: start with 1 + * @motor_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_fan_motor_status(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_fan_motor_status_str(fan_index, motor_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_fan_motor_speed - Used to get fan motor speed + * filled the value to buf + * @fan_index: start with 1 + * @motor_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_fan_motor_speed(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_fan_speed_str(fan_index, motor_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_fan_motor_speed_tolerance - Used to get fan motor speed tolerance + * filled the value to buf + * @fan_index: start with 1 + * @motor_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_fan_motor_speed_tolerance(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_fan_present_status(fan_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_fan_motor_speed_tolerance_str(fan_index, motor_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_fan_motor_speed_target - Used to get fan motor speed target + * filled the value to buf + * @fan_index: start with 1 + * @motor_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_fan_motor_speed_target(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_fan_present_status(fan_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_fan_motor_speed_target_str(fan_index, motor_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_fan_motor_speed_max - Used to get the maximum threshold of fan motor + * filled the value to buf + * @fan_index: start with 1 + * @motor_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_fan_motor_speed_max(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_fan_present_status(fan_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_fan_motor_speed_max_str(fan_index, motor_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_fan_motor_speed_min - Used to get the minimum threshold of fan motor + * filled the value to buf + * @fan_index: start with 1 + * @motor_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_fan_motor_speed_min(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_fan_present_status(fan_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_fan_motor_speed_min_str(fan_index, motor_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_fan_ratio - Used to get the ratio of fan + * filled the value to buf + * @fan_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_fan_ratio(unsigned int fan_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_fan_pwm_str(fan_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_set_fan_ratio - Used to set the ratio of fan + * @fan_index: start with 1 + * @ratio: motor speed ratio, from 0 to 100 + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int dfd_set_fan_ratio(unsigned int fan_index, int ratio) +{ + int ret; + + /* add vendor codes here */ + ret = dfd_set_fan_pwm(fan_index, ratio); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} +/****************************************end of fan*******************************************/ +/********************************************psu**********************************************/ +static int dfd_get_psu_number(void) +{ + int ret; + + ret = dfd_get_dev_number(WB_MAIN_DEV_PSU, WB_MINOR_DEV_NONE); + return ret; +} + +/* + * dfd_get_psu_present_status - Used to get psu present status + * filled the value to buf, psu present status define see enum psu_status_e + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_psu_present(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_psu_present_status_str(psu_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +static int dfd_get_psu_temp_number(unsigned int psu_index) +{ + int ret; + + ret = dfd_get_dev_number(WB_MAIN_DEV_PSU, WB_MINOR_DEV_TEMP); + return ret; +} + +/* Similar to dfd_get_psu_model_name */ +static ssize_t dfd_get_psu_model_name(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_info(psu_index, DFD_DEV_INFO_TYPE_PART_NAME, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +static ssize_t dfd_get_psu_vendor(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_info(psu_index, DFD_DEV_INFO_TYPE_VENDOR, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +static ssize_t dfd_get_psu_date(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_info(psu_index, DFD_DEV_INFO_TYPE_ASSET_TAG, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +static ssize_t dfd_get_psu_status(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status_word; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + status = status | 0x01; + return (ssize_t)snprintf(buf, count, "0x%x\n", status); + } + + ret = dfd_get_psu_pmbus_status(psu_index, buf, count); + if (ret < 0) { + SWITCH_DEBUG(DBG_ERROR, "get psu pmbus status error, ret: %ld, psu_index: %u\n", ret, psu_index); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } else { + ret = kstrtoint(buf, 0, &status_word); + if (ret) { + SWITCH_DEBUG(DBG_ERROR, "invalid value: %s \n", buf); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + + status = 0; + mem_clear(buf, count); + if (status_word < 0) { + return status_word; + } else { + status = (status_word & PSU_OFF_FAULT) ? (status | 0x02) : status; + status = (status_word & PSU_FAN_FAULT) ? (status | 0x04) : status; + status = (status_word & PSU_VOUT_FAULT) ? (status | 0x08) : status; + status = (status_word & PSU_IOUT_FAULT) ? (status | 0x10) : status; + status = (status_word & PSU_INPUT_FAULT) ? (status | 0x20) : status; + status = (status_word & PSU_TEMP_FAULT) ? (status | 0x40) : status; + } + return (ssize_t)snprintf(buf, count, "0x%x\n", status); +} + +static ssize_t dfd_get_psu_alarm(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_alarm_status(psu_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to wb_get_fan_serial_number */ +static ssize_t dfd_get_psu_serial_number(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_info(psu_index, DFD_DEV_INFO_TYPE_SN, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to wb_get_fan_part_number */ +static ssize_t dfd_get_psu_part_number(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_info(psu_index, DFD_DEV_INFO_TYPE_PART_NUMBER, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to wb_get_fan_hardware_version */ +static ssize_t dfd_get_psu_hardware_version(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_info(psu_index, DFD_DEV_INFO_TYPE_HW_INFO, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_psu_type - Used to get the input type of psu + * filled the value to buf, input type value define see enum psu_input_type_e + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_psu_type(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_input_type(psu_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_psu_in_curr - Used to get the input current of psu + * filled the value to buf, the value is integer with mA + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_psu_in_curr(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_sensor_info(psu_index, PSU_IN_CURR, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_psu_in_vol - Used to get the input voltage of psu + * filled the value to buf, the value is integer with mV + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_psu_in_vol(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_sensor_info(psu_index, PSU_IN_VOL, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_psu_in_power - Used to get the input power of psu + * filled the value to buf, the value is integer with uW + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_psu_in_power(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_sensor_info(psu_index, PSU_IN_POWER, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_psu_out_curr - Used to get the output current of psu + * filled the value to buf, the value is integer with mA + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_psu_out_curr(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_sensor_info(psu_index, PSU_OUT_CURR, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_psu_out_vol - Used to get the output voltage of psu + * filled the value to buf, the value is integer with mV + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_psu_out_vol(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_sensor_info(psu_index, PSU_OUT_VOL, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_psu_out_power - Used to get the output power of psu + * filled the value to buf, the value is integer with uW + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_psu_out_power(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_sensor_info(psu_index, PSU_OUT_POWER, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_psu_out_max_power - Used to get the output max power of psu + * filled the value to buf, the value is integer with uW + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_psu_out_max_power(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_info(psu_index, DFD_DEV_INFO_TYPE_MAX_OUTPUT_POWRER, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_psu_in_status - Used to get psu input status + * filled the value to buf, psu input status define see enum psu_io_status_e + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_psu_in_status(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_in_status_str(psu_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_psu_out_status - Used to get psu output status + * filled the value to buf, psu output status define see enum psu_io_status_e + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_psu_out_status(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_out_status_str(psu_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +static ssize_t dfd_get_psu_hw_status(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_psu_hw_status_str(psu_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +static ssize_t dfd_get_psu_attr_threshold(unsigned int psu_index, unsigned int type, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_psu_threshold_str(psu_index, type, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +static ssize_t dfd_get_psu_status_pmbus(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_status_pmbus_str(psu_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_psu_fan_speed - Used to get psu fan speed + * filled the value to buf + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_psu_fan_speed(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_sensor_info(psu_index, PSU_FAN_SPEED, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_psu_fan_ratio - Used to get the ratio of psu fan + * filled the value to buf + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_psu_fan_ratio(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_fan_ratio_str(psu_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_set_psu_fan_ratio - Used to set the ratio of psu fan + * @psu_index: start with 1 + * @ratio: from 0 to 100 + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int dfd_set_psu_fan_ratio(unsigned int psu_index, int ratio) +{ + /* add vendor codes here */ + return -WB_SYSFS_RV_UNSUPPORT; +} + +/* + * dfd_get_psu_fan_direction - Used to get psu air flow direction, + * filled the value to buf, air flow direction define enum air_flow_direction_e + * @psu_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_psu_fan_direction(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_info(psu_index, DFD_DEV_INFO_TYPE_FAN_DIRECTION, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_fan_led_status */ +static ssize_t dfd_get_psu_led_status(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status_word; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + status = LED_STATUS_DARK; /* led off */ + return (ssize_t)snprintf(buf, count, "%d\n", status); + } + status = LED_STATUS_GREEN; + + ret = dfd_get_psu_pmbus_status(psu_index, buf, count); + if (ret < 0) { + SWITCH_DEBUG(DBG_ERROR, "get psu pmbus status error, ret: %ld, psu_index: %u\n", ret, psu_index); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } else { + ret = kstrtoint(buf, 0, &status_word); + if (ret) { + SWITCH_DEBUG(DBG_ERROR, "invalid value: %s \n", buf); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + mem_clear(buf, count); + if (status_word > 0) { + status = LED_STATUS_YELLOW; /* led amber */ + return (ssize_t)snprintf(buf, count, "%d\n", status); + } + return (ssize_t)snprintf(buf, count, "%d\n", status); /* led green */ +} + +static ssize_t dfd_get_psu_fan_speed_cal(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_info(psu_index, DFD_DEV_INFO_TYPE_SPEED_CAL, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_temp_alias */ +static ssize_t dfd_get_psu_temp_alias(unsigned int psu_index, unsigned int temp_index, + char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_temp_info(WB_MAIN_DEV_PSU, psu_index, temp_index, WB_SENSOR_ALIAS, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_temp_type */ +static ssize_t dfd_get_psu_temp_type(unsigned int psu_index, unsigned int temp_index, + char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_temp_info(WB_MAIN_DEV_PSU, psu_index, temp_index, WB_SENSOR_TYPE, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; + +} + +/* Similar to dfd_get_main_board_temp_max */ +static ssize_t dfd_get_psu_temp_max(unsigned int psu_index, unsigned int temp_index, + char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_temp_info(WB_MAIN_DEV_PSU, psu_index, temp_index, WB_SENSOR_MAX, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_set_main_board_temp_max */ +static int dfd_set_psu_temp_max(unsigned int psu_index, unsigned int temp_index, + const char *buf, size_t count) +{ + /* add vendor codes here */ + return -WB_SYSFS_RV_UNSUPPORT; +} + +/* Similar to dfd_get_main_board_temp_min */ +static ssize_t dfd_get_psu_temp_min(unsigned int psu_index, unsigned int temp_index, + char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_temp_info(WB_MAIN_DEV_PSU, psu_index, temp_index, WB_SENSOR_MIN, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_set_main_board_temp_min */ +static int dfd_set_psu_temp_min(unsigned int psu_index, unsigned int temp_index, + const char *buf, size_t count) +{ + /* add vendor codes here */ + return -WB_SYSFS_RV_UNSUPPORT; +} + +/* Similar to dfd_get_main_board_temp_value */ +static ssize_t dfd_get_psu_temp_value(unsigned int psu_index, unsigned int temp_index, + char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_temp_info(WB_MAIN_DEV_PSU, psu_index, temp_index, WB_SENSOR_INPUT, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_psu_eeprom_size - Used to get psu eeprom size + * + * This function returns the size of psu eeprom, + * otherwise it returns a negative value on failed. + */ +static int dfd_get_psu_eeprom_size(unsigned int psu_index) +{ + int ret; + + ret = dfd_get_eeprom_size(WB_MAIN_DEV_PSU, psu_index); + return ret; +} + +/* + * dfd_read_psu_eeprom_data - Used to read psu eeprom data, + * @buf: Data read buffer + * @offset: offset address to read psu eeprom data + * @count: length of buf + * + * This function returns the length of the filled buffer, + * returns 0 means EOF, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_read_psu_eeprom_data(unsigned int psu_index, char *buf, loff_t offset, + size_t count) +{ + ssize_t ret; + + ret = dfd_read_eeprom_data(WB_MAIN_DEV_PSU, psu_index, buf, offset, count); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + +static ssize_t dfd_get_psu_blackbox_info(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_blackbox(psu_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +static ssize_t dfd_get_psu_pmbus_info(unsigned int psu_index, char *buf, size_t count) +{ + ssize_t ret; + int status; + + status = dfd_get_psu_present_status(psu_index); + if (status == DEV_ABSENT) { + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } + + ret = dfd_get_psu_pmbus(psu_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_clear_psu_blackbox_info - Used to clear psu blackbox information + * @psu_index: start with 1 + * @value: 1 + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int dfd_clear_psu_blackbox_info(unsigned int psu_index, uint8_t value) +{ + int ret; + + ret = dfd_clear_psu_blackbox(psu_index, value); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; + +} +/****************************************end of psu*******************************************/ +/****************************************transceiver******************************************/ +static int dfd_get_eth_number(void) +{ + int ret; + + ret = dfd_get_dev_number(WB_MAIN_DEV_SFF, WB_MINOR_DEV_NONE); + return ret; +} + +/* + * dfd_get_transceiver_power_on_status - Used to get the whole machine port power on status, + * filled the value to buf, 0: power off, 1: power on + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_transceiver_power_on_status(char *buf, size_t count) +{ + ssize_t ret; + unsigned int eth_index, eth_num; + int len, left_len; + eth_num = dfd_get_dev_number(WB_MAIN_DEV_SFF, WB_MINOR_DEV_NONE); + if (eth_num <= 0) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + + mem_clear(buf, count); + len = 0; + left_len = count - 1; + + for (eth_index = 1; eth_index <= eth_num; eth_index++) { + SWITCH_DEBUG(DBG_VERBOSE, "eth index: %u\n", eth_index); + if (left_len > 0) { + ret = dfd_get_sff_cpld_info(eth_index, WB_SFF_POWER_ON, buf, left_len); + if (ret < 0) { + SWITCH_DEBUG(DBG_ERROR, "get eth%u power status failed, ret: %ld\n", eth_index, ret); + break; + } + } else { + SWITCH_DEBUG(DBG_ERROR, "error: get_transceiver_power_on_status are not enough buffers.\n"); + ret = -DFD_RV_NO_MEMORY; + break; + } + dfd_ko_cfg_del_lf_cr(buf); /* del '\n' */ + len = strlen(buf); + left_len = count - len - 2; /* Reserve end to add '\n' and '\0' */ + } + + if (ret < 0) { + mem_clear(buf, count); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + + len = strlen(buf); + if (len >= count) { + SWITCH_DEBUG(DBG_ERROR, "error: get_transceiver_power_on_status buffers too long, need: %ld, act: %d.\n", count, len); + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + buf[len] = '\n'; + ret = strlen(buf); + SWITCH_DEBUG(DBG_VERBOSE, "get_transceiver_power_on_status ok. sff num:%d, len:%ld\n", eth_num, ret); + + return ret; +} + +/* + * dfd_set_transceiver_power_on_status - Used to set the whole machine port power on status, + * @status: power on status, 0: power off, 1: power on + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int dfd_set_transceiver_power_on_status(int status) +{ + int ret; + + ret = dfd_set_sff_cpld_info(0, WB_SFF_POWER_ON, status); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + +/* + * dfd_get_transceiver_present_status - Used to get the whole machine port present status, + * filled the value to buf, 0: absent, 1: present + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_transceiver_present_status(char *buf, size_t count) +{ + ssize_t ret; + unsigned int eth_index, eth_num; + int len, left_len; + + eth_num = dfd_get_dev_number(WB_MAIN_DEV_SFF, WB_MINOR_DEV_NONE); + if (eth_num <= 0) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + + mem_clear(buf, count); + len = 0; + left_len = count - 1; + + for (eth_index = 1; eth_index <= eth_num; eth_index++) { + SWITCH_DEBUG(DBG_VERBOSE, "eth index: %u\n", eth_index); + if (left_len > 0) { + ret = dfd_get_sff_cpld_info(eth_index, WB_SFF_MODULE_PRESENT, buf + len, left_len); + if (ret < 0) { + SWITCH_DEBUG(DBG_ERROR, "get eth%u present status failed, ret: %ld\n", eth_index, ret); + break; + } + } else { + SWITCH_DEBUG(DBG_ERROR, "error: get_transceiver_present_status are not enough buffers.\n"); + ret = -DFD_RV_NO_MEMORY; + break; + } + dfd_ko_cfg_del_lf_cr(buf); /* del '\n' */ + len = strlen(buf); + left_len = count - len - 2; /* Reserve end to add '\n' and '\0' */ + } + + if (ret < 0) { + mem_clear(buf, count); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + + len = strlen(buf); + if (len >= count) { + SWITCH_DEBUG(DBG_ERROR, "error: get_transceiver_present_status buffers too long, need: %ld, act: %d.\n", count, len); + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + buf[len] = '\n'; + ret = strlen(buf); + SWITCH_DEBUG(DBG_VERBOSE, "get_transceiver_present_status ok. sff num:%d, len:%ld\n", eth_num, ret); + + return ret; +} + + +/* + * dfd_get_eth_power_on_status - Used to get single port power on status, + * filled the value to buf, 0: power off, 1: power on + * @eth_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_eth_power_on_status(unsigned int eth_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_sff_cpld_info(eth_index, WB_SFF_POWER_ON, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_set_eth_power_on_status - Used to set single port power on status, + * @eth_index: start with 1 + * @status: power on status, 0: power off, 1: power on + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int dfd_set_eth_power_on_status(unsigned int eth_index, int status) +{ + int ret; + + ret = dfd_set_sff_cpld_info(eth_index, WB_SFF_POWER_ON, status); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + +/* + * dfd_get_eth_tx_fault_status - Used to get port tx_fault status, + * filled the value to buf, 0: normal, 1: abnormal + * @eth_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_eth_tx_fault_status(unsigned int eth_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_sff_cpld_info(eth_index, WB_SFF_TX_FAULT, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_eth_tx_disable_status - Used to get port tx_disable status, + * filled the value to buf, 0: tx_enable, 1: tx_disable + * @eth_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_eth_tx_disable_status(unsigned int eth_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_sff_cpld_info(eth_index, WB_SFF_TX_DIS, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_set_eth_tx_disable_status - Used to set port tx_disable status, + * @eth_index: start with 1 + * @status: tx_disable status, 0: tx_enable, 1: tx_disable + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int dfd_set_eth_tx_disable_status(unsigned int eth_index, int status) +{ + int ret; + + ret = dfd_set_sff_cpld_info(eth_index, WB_SFF_TX_DIS, status); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + +/* + * dfd_get_eth_present_status - Used to get port present status, + * filled the value to buf, 1: present, 0: absent + * @eth_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_eth_present_status(unsigned int eth_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_sff_cpld_info(eth_index, WB_SFF_MODULE_PRESENT, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_eth_rx_los_status - Used to get port rx_los status, + * filled the value to buf, 0: normal, 1: abnormal + * @eth_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_eth_rx_los_status(unsigned int eth_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_sff_cpld_info(eth_index, WB_SFF_RX_LOS, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_eth_reset_status - Used to get port reset status, + * filled the value to buf, 0: unreset, 1: reset + * @eth_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_eth_reset_status(unsigned int eth_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_sff_cpld_info(eth_index, WB_SFF_RESET, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_set_eth_reset_status - Used to set port reset status, + * @eth_index: start with 1 + * @status: reset status, 0: unreset, 1: reset + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int dfd_set_eth_reset_status(unsigned int eth_index, int status) +{ + int ret; + + ret = dfd_set_sff_cpld_info(eth_index, WB_SFF_RESET, status); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + +/** + * dfd_get_eth_optoe_type - get sff optoe type + * @sff_index: Optical module number, starting from 1 + * @optoe_type: Optical module type + * return: Success: Returns the length of fill buf + * : Failed: A negative value is returned + */ +static ssize_t dfd_get_eth_optoe_type(unsigned int eth_index, int *optoe_type, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_single_eth_optoe_type(eth_index, optoe_type); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return (ssize_t)snprintf(buf, count, "%d\n", *optoe_type); +} + +/** + * dfd_set_eth_optoe_type - set sff optoe type + * @sff_index: Optical module number, starting from 1 + * @optoe_type: Optical module type + * return: Success: Returns the length of fill buf + * : Failed: A negative value is returned + */ +static int dfd_set_eth_optoe_type(unsigned int eth_index, int optoe_type) +{ + int ret; + + ret = dfd_set_single_eth_optoe_type(eth_index, optoe_type); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + + +/* + * dfd_get_eth_low_power_mode_status - Used to get port low power mode status, + * filled the value to buf, 0: high power mode, 1: low power mode + * @eth_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_eth_low_power_mode_status(unsigned int eth_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_sff_cpld_info(eth_index, WB_SFF_LPMODE, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_eth_interrupt_status - Used to get port interruption status, + * filled the value to buf, 0: no interruption, 1: interruption + * @eth_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_eth_interrupt_status(unsigned int eth_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_sff_cpld_info(eth_index, WB_SFF_INTERRUPT, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_eth_eeprom_size - Used to get port eeprom size + * + * This function returns the size of port eeprom, + * otherwise it returns a negative value on failed. + */ +static int dfd_get_eth_eeprom_size(unsigned int eth_index) +{ + int ret; + + ret = dfd_get_eeprom_size(WB_MAIN_DEV_SFF, eth_index); + return ret; +} + +/* + * dfd_read_eth_eeprom_data - Used to read port eeprom data, + * @buf: Data read buffer + * @offset: offset address to read port eeprom data + * @count: length of buf + * + * This function returns the length of the filled buffer, + * returns 0 means EOF, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_read_eth_eeprom_data(unsigned int eth_index, char *buf, loff_t offset, + size_t count) +{ + ssize_t ret; + + ret = dfd_read_eeprom_data(WB_MAIN_DEV_SFF, eth_index, buf, offset, count); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + +/* + * dfd_write_eth_eeprom_data - Used to write port eeprom data + * @buf: Data write buffer + * @offset: offset address to write port eeprom data + * @count: length of buf + * + * This function returns the written length of port eeprom, + * returns 0 means EOF, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_write_eth_eeprom_data(unsigned int eth_index, char *buf, loff_t offset, + size_t count) +{ + ssize_t ret; + + ret = dfd_write_eeprom_data(WB_MAIN_DEV_SFF, eth_index, buf, offset, count); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} +/************************************end of transceiver***************************************/ +/*****************************************sysled**********************************************/ +/* + * dfd_get_sys_led_status - Used to get sys led status + * filled the value to buf, led status value define see enum fan_status_e + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_sys_led_status(char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_led_status(WB_SYS_LED_FRONT, WB_MINOR_DEV_NONE, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_set_sys_led_status - Used to set sys led status + * @status: led status, led status value define see enum led_status_e + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int dfd_set_sys_led_status(int status) +{ + int ret; + + ret = dfd_set_led_status(WB_SYS_LED_FRONT, WB_MINOR_DEV_NONE, status); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + +/* Similar to dfd_get_sys_led_status */ +static ssize_t dfd_get_bmc_led_status(char *buf, size_t count) +{ + int ret; + + ret = dfd_get_led_status(WB_BMC_LED_FRONT, WB_MINOR_DEV_NONE, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_set_sys_led_status */ +static int dfd_set_bmc_led_status(int status) +{ + int ret; + + ret = dfd_set_led_status(WB_BMC_LED_FRONT, WB_MINOR_DEV_NONE, status); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + +/* Similar to dfd_get_sys_led_status */ +static ssize_t dfd_get_sys_fan_led_status(char *buf, size_t count) +{ + int ret; + + ret = dfd_get_led_status(WB_FAN_LED_FRONT, WB_MINOR_DEV_NONE, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_set_sys_led_status */ +static int dfd_set_sys_fan_led_status(int status) +{ + int ret; + + ret = dfd_set_led_status(WB_FAN_LED_FRONT, WB_MINOR_DEV_NONE, status); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + +/* Similar to dfd_get_sys_led_status */ +static ssize_t dfd_get_sys_psu_led_status(char *buf, size_t count) +{ + int ret; + + ret = dfd_get_led_status(WB_PSU_LED_FRONT, WB_MINOR_DEV_NONE, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_set_sys_led_status */ +static int dfd_set_sys_psu_led_status(int status) +{ + int ret; + + ret = dfd_set_led_status(WB_PSU_LED_FRONT, WB_MINOR_DEV_NONE, status); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + +/* Similar to dfd_get_sys_led_status */ +static ssize_t dfd_get_id_led_status(char *buf, size_t count) +{ + int ret; + + ret = dfd_get_led_status(WB_ID_LED_FRONT, WB_MINOR_DEV_NONE, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_set_sys_led_status */ +static int dfd_set_id_led_status(int status) +{ + int ret; + + ret = dfd_set_led_status(WB_ID_LED_FRONT, WB_MINOR_DEV_NONE, status); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + +/**************************************end of sysled******************************************/ +/******************************************FPGA***********************************************/ +static int dfd_get_main_board_fpga_number(void) +{ + int ret; + + ret = dfd_get_dev_number(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_FPGA); + return ret; +} + +/* + * dfd_get_main_board_fpga_alias - Used to identify the location of fpga, + * @fpga_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_fpga_alias(unsigned int fpga_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_fpga_name(WB_MAIN_DEV_MAINBOARD, fpga_index - 1, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_fpga_type - Used to get fpga model name + * @fpga_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_fpga_type(unsigned int fpga_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_fpga_type(WB_MAIN_DEV_MAINBOARD, fpga_index - 1, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_fpga_firmware_version - Used to get fpga firmware version, + * @fpga_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_fpga_firmware_version(unsigned int fpga_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_fpga_fw_version(WB_MAIN_DEV_MAINBOARD, fpga_index - 1, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_fpga_board_version - Used to get fpga board version, + * @fpga_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_fpga_board_version(unsigned int fpga_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_fpga_hw_version(WB_MAIN_DEV_MAINBOARD, fpga_index - 1, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_fpga_test_reg - Used to test fpga register read + * filled the value to buf, value is hexadecimal, start with 0x + * @fpga_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_fpga_test_reg(unsigned int fpga_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_fpga_testreg_str(WB_MAIN_DEV_MAINBOARD, fpga_index - 1, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_set_main_board_fpga_test_reg - Used to test fpga register write + * @fpga_index: start with 1 + * @value: value write to fpga + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int dfd_set_main_board_fpga_test_reg(unsigned int fpga_index, unsigned int value) +{ + int ret; + + ret = dfd_set_fpga_testreg(WB_MAIN_DEV_MAINBOARD, fpga_index - 1, value); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} +/***************************************end of FPGA*******************************************/ +/******************************************CPLD***********************************************/ +static int dfd_get_main_board_cpld_number(void) +{ + int ret; + + ret = dfd_get_dev_number(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_CPLD); + return ret; +} + +/* + * dfd_get_main_board_cpld_alias - Used to identify the location of cpld, + * @cpld_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_cpld_alias(unsigned int cpld_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_cpld_name(WB_MAIN_DEV_MAINBOARD, cpld_index - 1, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_cpld_type - Used to get cpld model name + * @cpld_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_cpld_type(unsigned int cpld_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_cpld_type(WB_MAIN_DEV_MAINBOARD, cpld_index - 1, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_cpld_firmware_version - Used to get cpld firmware version, + * @cpld_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_cpld_firmware_version(unsigned int cpld_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_cpld_fw_version(WB_MAIN_DEV_MAINBOARD, cpld_index - 1, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_cpld_board_version - Used to get cpld board version, + * @cpld_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_cpld_board_version(unsigned int cpld_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_cpld_hw_version(WB_MAIN_DEV_MAINBOARD, cpld_index - 1, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_main_board_cpld_test_reg - Used to test cpld register read + * filled the value to buf, value is hexadecimal, start with 0x + * @cpld_index: start with 1 + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * if not support this attributes filled "NA" to buf, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_main_board_cpld_test_reg(unsigned int cpld_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_cpld_testreg_str(WB_MAIN_DEV_MAINBOARD, cpld_index - 1, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_set_main_board_cpld_test_reg - Used to test cpld register write + * @cpld_index: start with 1 + * @value: value write to cpld + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int dfd_set_main_board_cpld_test_reg(unsigned int cpld_index, unsigned int value) +{ + int ret; + + ret = dfd_set_cpld_testreg(WB_MAIN_DEV_MAINBOARD, cpld_index - 1, value); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} +/***************************************end of CPLD*******************************************/ +/****************************************watchdog*********************************************/ +/* + * dfd_get_watchdog_identify - Used to get watchdog identify, such as iTCO_wdt + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_watchdog_identify(char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_watchdog_info(WB_WDT_TYPE_NAME, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_watchdog_timeleft - Used to get watchdog timeleft, + * filled the value to buf + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_watchdog_timeleft(char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_watchdog_info(WB_WDT_TYPE_TIMELEFT, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_watchdog_timeout - Used to get watchdog timeout, + * filled the value to buf + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_watchdog_timeout(char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_watchdog_info(WB_WDT_TYPE_TIMEOUT, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_set_watchdog_timeout - Used to set watchdog timeout, + * @value: timeout value + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int dfd_set_watchdog_timeout(int value) +{ + /* add vendor codes here */ + return -WB_SYSFS_RV_UNSUPPORT; +} + +/* + * dfd_get_watchdog_enable_status - Used to get watchdog enable status, + * filled the value to buf, 0: disable, 1: enable + * @buf: Data receiving buffer + * @count: length of buf + * + * This function returns the length of the filled buffer, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_watchdog_enable_status(char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_watchdog_get_status(buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_set_watchdog_enable_status - Used to set watchdog enable status, + * @value: enable status value, 0: disable, 1: enable + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int dfd_set_watchdog_enable_status(int value) +{ + /* add vendor codes here */ + int ret; + ret = dfd_watchdog_set_status(value); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + +/* + * dfd_set_watchdog_reset - Used to feed watchdog, + * @value: any value to feed watchdog + * + * This function returns 0 on success, + * otherwise it returns a negative value on failed. + */ +static int dfd_set_watchdog_reset(int value) +{ + /* add vendor codes here */ + return -WB_SYSFS_RV_UNSUPPORT; +} +/*************************************end of watchdog*****************************************/ +/******************************************slot***********************************************/ +static int dfd_get_slot_number(void) +{ + int ret; + + ret = dfd_get_dev_number(WB_MAIN_DEV_SLOT, WB_MINOR_DEV_NONE); + return ret; +} + +static int dfd_get_slot_temp_number(unsigned int slot_index) +{ + int ret; + + ret = dfd_get_dev_number(WB_MAIN_DEV_SLOT, WB_MINOR_DEV_TEMP); + return ret; +} + +static int dfd_get_slot_vol_number(unsigned int slot_index) +{ + int ret; + + ret = dfd_get_dev_number(WB_MAIN_DEV_SLOT, WB_MINOR_DEV_IN); + return ret; +} + +static int dfd_get_slot_curr_number(unsigned int slot_index) +{ + int ret; + + ret = dfd_get_dev_number(WB_MAIN_DEV_SLOT, WB_MINOR_DEV_CURR); + return ret; +} + +static int dfd_get_slot_fpga_number(unsigned int slot_index) +{ + int ret; + + ret = dfd_get_dev_number(WB_MAIN_DEV_SLOT, WB_MINOR_DEV_FPGA); + return ret; +} + +static int dfd_get_slot_cpld_number(unsigned int slot_index) +{ + int ret; + + ret = dfd_get_dev_number(WB_MAIN_DEV_SLOT, WB_MINOR_DEV_CPLD); + return ret; +} + +/* Similar to dfd_get_fan_model_name */ +static ssize_t dfd_get_slot_model_name(unsigned int slot_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_slot_info(slot_index, DFD_DEV_INFO_TYPE_NAME, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +static ssize_t dfd_get_slot_vendor(unsigned int slot_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_slot_info(slot_index, DFD_DEV_INFO_TYPE_VENDOR, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to wb_get_fan_serial_number */ +static ssize_t dfd_get_slot_serial_number(unsigned int slot_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_slot_info(slot_index, DFD_DEV_INFO_TYPE_SN, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to wb_get_fan_part_number */ +static ssize_t dfd_get_slot_part_number(unsigned int slot_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_slot_info(slot_index, DFD_DEV_INFO_TYPE_PART_NUMBER, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to wb_get_fan_hardware_version */ +static ssize_t dfd_get_slot_hardware_version(unsigned int slot_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_slot_info(slot_index, DFD_DEV_INFO_TYPE_HW_INFO, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_fan_status */ +static ssize_t dfd_get_slot_status(unsigned int slot_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_slot_status_str(slot_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_fan_led_status */ +static ssize_t dfd_get_slot_led_status(unsigned int slot_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_led_status(WB_SLOT_LED_MODULE, slot_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_set_fan_led_status */ +static int dfd_set_slot_led_status(unsigned int slot_index, int status) +{ + int ret; + + ret = dfd_set_led_status(WB_SLOT_LED_MODULE, slot_index, status); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + +static ssize_t dfd_get_slot_power_status(unsigned int slot_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_slot_power_status_str(slot_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +static int dfd_set_slot_power_status(unsigned int slot_index, int status) +{ + int ret; + + ret = dfd_set_slot_power_status_str(slot_index, status); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + +/* Similar to dfd_get_main_board_temp_alias */ +static ssize_t dfd_get_slot_temp_alias(unsigned int slot_index, unsigned int temp_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_temp_info(WB_MAIN_DEV_SLOT, slot_index, temp_index, WB_SENSOR_ALIAS, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_temp_type */ +static ssize_t dfd_get_slot_temp_type(unsigned int slot_index, unsigned int temp_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_temp_info(WB_MAIN_DEV_SLOT, slot_index, temp_index, WB_SENSOR_TYPE, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_temp_max */ +static ssize_t dfd_get_slot_temp_max(unsigned int slot_index, unsigned int temp_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_temp_info(WB_MAIN_DEV_SLOT, slot_index, temp_index, WB_SENSOR_MAX, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_temp_min */ +static ssize_t dfd_get_slot_temp_min(unsigned int slot_index, unsigned int temp_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_temp_info(WB_MAIN_DEV_SLOT, slot_index, temp_index, WB_SENSOR_MIN, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_temp_value */ +static ssize_t dfd_get_slot_temp_value(unsigned int slot_index, unsigned int temp_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_temp_info(WB_MAIN_DEV_SLOT, slot_index, temp_index, WB_SENSOR_INPUT, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_vol_alias */ +static ssize_t dfd_get_slot_vol_alias(unsigned int slot_index, unsigned int vol_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_voltage_info(WB_MAIN_DEV_SLOT, slot_index, vol_index, WB_SENSOR_ALIAS, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_vol_type */ +static ssize_t dfd_get_slot_vol_type(unsigned int slot_index, unsigned int vol_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_voltage_info(WB_MAIN_DEV_SLOT, slot_index, vol_index, WB_SENSOR_TYPE, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_vol_max */ +static ssize_t dfd_get_slot_vol_max(unsigned int slot_index, unsigned int vol_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_voltage_info(WB_MAIN_DEV_SLOT, slot_index, vol_index, WB_SENSOR_MAX, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_vol_min */ +static ssize_t dfd_get_slot_vol_min(unsigned int slot_index, unsigned int vol_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_voltage_info(WB_MAIN_DEV_SLOT, slot_index, vol_index, WB_SENSOR_MIN, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_vol_range */ +static ssize_t dfd_get_slot_vol_range(unsigned int slot_index, unsigned int vol_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_voltage_info(WB_MAIN_DEV_SLOT, slot_index, vol_index, WB_SENSOR_RANGE, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_vol_nominal_value */ +static ssize_t dfd_get_slot_vol_nominal_value(unsigned int slot_index, + unsigned int vol_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_voltage_info(WB_MAIN_DEV_SLOT, slot_index, vol_index, WB_SENSOR_NOMINAL_VAL, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_vol_value */ +static ssize_t dfd_get_slot_vol_value(unsigned int slot_index, unsigned int vol_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_voltage_info(WB_MAIN_DEV_SLOT, slot_index, vol_index, WB_SENSOR_INPUT, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_curr_alias */ +static ssize_t dfd_get_slot_curr_alias(unsigned int slot_index, unsigned int curr_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_current_info(WB_MAIN_DEV_SLOT, slot_index, curr_index, WB_SENSOR_ALIAS, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_curr_type */ +static ssize_t dfd_get_slot_curr_type(unsigned int slot_index, unsigned int curr_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_current_info(WB_MAIN_DEV_SLOT, slot_index, curr_index, WB_SENSOR_TYPE, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_curr_max */ +static ssize_t dfd_get_slot_curr_max(unsigned int slot_index, unsigned int curr_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_current_info(WB_MAIN_DEV_SLOT, slot_index, curr_index, WB_SENSOR_MAX, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_curr_min */ +static ssize_t dfd_get_slot_curr_min(unsigned int slot_index, unsigned int curr_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_current_info(WB_MAIN_DEV_SLOT, slot_index, curr_index, WB_SENSOR_MIN, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_curr_value */ +static ssize_t dfd_get_slot_curr_value(unsigned int slot_index, unsigned int curr_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_current_info(WB_MAIN_DEV_SLOT, slot_index, curr_index, WB_SENSOR_INPUT, + buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_fpga_alias */ +static ssize_t dfd_get_slot_fpga_alias(unsigned int slot_index, unsigned int fpga_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_fpga_name(slot_index, fpga_index - 1, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_fpga_type */ +static ssize_t dfd_get_slot_fpga_type(unsigned int slot_index, unsigned int fpga_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_fpga_type(slot_index, fpga_index - 1, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_fpga_firmware_version */ +static ssize_t dfd_get_slot_fpga_firmware_version(unsigned int slot_index, unsigned int fpga_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_fpga_fw_version(slot_index, fpga_index - 1, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_fpga_board_version */ +static ssize_t dfd_get_slot_fpga_board_version(unsigned int slot_index, unsigned int fpga_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_fpga_hw_version(slot_index, fpga_index - 1, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_fpga_test_reg */ +static ssize_t dfd_get_slot_fpga_test_reg(unsigned int slot_index, unsigned int fpga_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_fpga_testreg_str(slot_index, fpga_index - 1, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_set_main_board_fpga_test_reg */ +static int dfd_set_slot_fpga_test_reg(unsigned int slot_index, unsigned int fpga_index, + unsigned int value) +{ + int ret; + + ret = dfd_set_fpga_testreg(slot_index, fpga_index - 1, value); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + +/* Similar to dfd_get_main_board_cpld_alias */ +static ssize_t dfd_get_slot_cpld_alias(unsigned int slot_index, unsigned int cpld_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_cpld_name(slot_index, cpld_index - 1, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_cpld_type */ +static ssize_t dfd_get_slot_cpld_type(unsigned int slot_index, unsigned int cpld_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_cpld_type(slot_index, cpld_index - 1, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_cpld_firmware_version */ +static ssize_t dfd_get_slot_cpld_firmware_version(unsigned int slot_index, unsigned int cpld_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_cpld_fw_version(slot_index, cpld_index - 1, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_cpld_board_version */ +static ssize_t dfd_get_slot_cpld_board_version(unsigned int slot_index, unsigned int cpld_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_cpld_hw_version(slot_index, cpld_index - 1, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_get_main_board_cpld_test_reg */ +static ssize_t dfd_get_slot_cpld_test_reg(unsigned int slot_index, unsigned int cpld_index, + char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_cpld_testreg_str(slot_index, cpld_index - 1, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* Similar to dfd_set_main_board_cpld_test_reg */ +static int dfd_set_slot_cpld_test_reg(unsigned int slot_index, unsigned int cpld_index, + unsigned int value) +{ + int ret; + + ret = dfd_set_cpld_testreg(slot_index, cpld_index - 1, value); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} +/***************************************end of slot*******************************************/ +/*****************************************system*********************************************/ +static ssize_t dfd_get_system_value(unsigned int type, int *value, char *buf, size_t count) +{ + int ret; + + ret = dfd_system_get_system_value(type, value); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return (ssize_t)snprintf(buf, count, "%d\n", *value); +} + +static ssize_t dfd_set_system_value(unsigned int type, int value) +{ + int ret; + + ret = dfd_system_set_system_value(type, value); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + +static ssize_t dfd_get_system_port_power_status(unsigned int type, char *buf, size_t count) +{ + int ret; + + ret = dfd_system_get_port_power_status(type, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} +/*************************************end of system*****************************************/ +/*****************************************eeprom*********************************************/ +static int dfd_get_eeprom_number(void) +{ + int ret; + + ret = dfd_get_dev_number(WB_MAIN_DEV_MAINBOARD, WB_MINOR_DEV_EEPROM); + return ret; +} + +/* + * dfd_get_board_eeprom_size - Used to get board eeprom size, including slots eeprom + * + * This function returns the size of board eeprom, including slots eeprom + * otherwise it returns a negative value on failed. + */ +static int dfd_get_board_eeprom_size(unsigned int e2_index) +{ + int ret; + + ret = dfd_get_eeprom_size(WB_MAIN_DEV_MAINBOARD, e2_index); + return ret; +} + +/* + * dfd_get_board_eeprom_alias - Used to get board eeprom alias, including slots eeprom + * + * This function returns the alias of board eeprom, including slots eeprom + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_board_eeprom_alias(unsigned int e2_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_eeprom_alias(WB_MAIN_DEV_MAINBOARD, e2_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_board_eeprom_tag - Used to get board eeprom tag, including slots eeprom + * + * This function returns the alias of board eeprom, including slots eeprom + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_board_eeprom_tag(unsigned int e2_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_eeprom_tag(WB_MAIN_DEV_MAINBOARD, e2_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_get_board_eeprom_type - Used to get board eeprom type, including slots eeprom + * + * This function returns the type of board eeprom, including slots eeprom + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_get_board_eeprom_type(unsigned int e2_index, char *buf, size_t count) +{ + ssize_t ret; + + ret = dfd_get_eeprom_type(WB_MAIN_DEV_MAINBOARD, e2_index, buf, count); + if (ret < 0) { + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, count, "%s\n", SWITCH_DEV_ERROR); + } + } + return ret; +} + +/* + * dfd_read_board_eeprom_data - Used to read board eeprom data, including slots eeprom + * @buf: Data read buffer + * @offset: offset address to read board eeprom data, including slots eeprom + * @count: length of buf + * + * This function returns the length of the filled buffer, + * returns 0 means EOF, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_read_board_eeprom_data(unsigned int e2_index, char *buf, loff_t offset, + size_t count) +{ + ssize_t ret; + + ret = dfd_read_eeprom_data(WB_MAIN_DEV_MAINBOARD, e2_index, buf, offset, count); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + +/* + * dfd_write_board_eeprom_data - Used to write board eeprom data, including slots eeprom + * @buf: Data write buffer + * @offset: offset address to write board eeprom data, including slots eeprom + * @count: length of buf + * + * This function returns the written length of eeprom, + * returns 0 means EOF, + * otherwise it returns a negative value on failed. + */ +static ssize_t dfd_write_board_eeprom_data(unsigned int e2_index, char *buf, loff_t offset, + size_t count) +{ + ssize_t ret; + + ret = dfd_write_eeprom_data(WB_MAIN_DEV_MAINBOARD, e2_index, buf, offset, count); + if (ret == -DFD_RV_DEV_NOTSUPPORT) { + return -WB_SYSFS_RV_UNSUPPORT; + } + return ret; +} + +/*************************************end of eeprom*****************************************/ + + +static struct switch_drivers_s switch_drivers = { + /* + * set odm switch drivers, + * if not support the function, set corresponding hook to NULL. + */ + /* temperature sensors */ + .get_main_board_temp_number = dfd_get_main_board_temp_number, + .get_main_board_temp_alias = dfd_get_main_board_temp_alias, + .get_main_board_temp_type = dfd_get_main_board_temp_type, + .get_main_board_temp_max = dfd_get_main_board_temp_max, + .get_main_board_temp_min = dfd_get_main_board_temp_min, + .get_main_board_temp_value = dfd_get_main_board_temp_value, + .get_main_board_temp_high = dfd_get_main_board_temp_high, + .get_main_board_temp_low = dfd_get_main_board_temp_low, + .get_main_board_temp_monitor_flag = dfd_get_main_board_temp_monitor_flag, + /* voltage sensors */ + .get_main_board_vol_number = dfd_get_main_board_vol_number, + .get_main_board_vol_alias = dfd_get_main_board_vol_alias, + .get_main_board_vol_type = dfd_get_main_board_vol_type, + .get_main_board_vol_max = dfd_get_main_board_vol_max, + .get_main_board_vol_min = dfd_get_main_board_vol_min, + .get_main_board_vol_range = dfd_get_main_board_vol_range, + .get_main_board_vol_nominal_value = dfd_get_main_board_vol_nominal_value, + .get_main_board_vol_value = dfd_get_main_board_vol_value, + .get_main_board_vol_monitor_flag = dfd_get_main_board_vol_monitor_flag, + /* current sensors */ + .get_main_board_curr_number = dfd_get_main_board_curr_number, + .get_main_board_curr_alias = dfd_get_main_board_curr_alias, + .get_main_board_curr_type = dfd_get_main_board_curr_type, + .get_main_board_curr_max = dfd_get_main_board_curr_max, + .get_main_board_curr_min = dfd_get_main_board_curr_min, + .get_main_board_curr_value = dfd_get_main_board_curr_value, + .get_main_board_curr_monitor_flag = dfd_get_main_board_curr_monitor_flag, + /* syseeprom */ + .get_syseeprom_size = dfd_get_syseeprom_size, + .read_syseeprom_data = dfd_read_syseeprom_data, + .write_syseeprom_data = dfd_write_syseeprom_data, + /* fan */ + .get_fan_number = dfd_get_fan_number, + .get_fan_motor_number = dfd_get_fan_motor_number, + .get_fan_model_name = dfd_get_fan_model_name, + .get_fan_vendor = dfd_get_fan_vendor, + .get_fan_serial_number = dfd_get_fan_serial_number, + .get_fan_part_number = dfd_get_fan_part_number, + .get_fan_hardware_version = dfd_get_fan_hardware_version, + .get_fan_status = dfd_get_fan_status, + .get_fan_present = dfd_get_fan_present, + .get_fan_led_status = dfd_get_fan_led_status, + .set_fan_led_status = dfd_set_fan_led_status, + .get_fan_direction = dfd_get_fan_direction, + .get_fan_motor_status = dfd_get_fan_motor_status, + .get_fan_motor_speed = dfd_get_fan_motor_speed, + .get_fan_motor_speed_tolerance = dfd_get_fan_motor_speed_tolerance, + .get_fan_motor_speed_target = dfd_get_fan_motor_speed_target, + .get_fan_motor_speed_max = dfd_get_fan_motor_speed_max, + .get_fan_motor_speed_min = dfd_get_fan_motor_speed_min, + .get_fan_ratio = dfd_get_fan_ratio, + .set_fan_ratio = dfd_set_fan_ratio, + /* psu */ + .get_psu_number = dfd_get_psu_number, + .get_psu_temp_number = dfd_get_psu_temp_number, + .get_psu_model_name = dfd_get_psu_model_name, + .get_psu_vendor = dfd_get_psu_vendor, + .get_psu_date = dfd_get_psu_date, + .get_psu_status = dfd_get_psu_status, + .get_psu_hw_status = dfd_get_psu_hw_status, + .get_psu_alarm = dfd_get_psu_alarm, + .get_psu_serial_number = dfd_get_psu_serial_number, + .get_psu_part_number = dfd_get_psu_part_number, + .get_psu_hardware_version = dfd_get_psu_hardware_version, + .get_psu_type = dfd_get_psu_type, + .get_psu_in_curr = dfd_get_psu_in_curr, + .get_psu_in_vol = dfd_get_psu_in_vol, + .get_psu_in_power = dfd_get_psu_in_power, + .get_psu_out_curr = dfd_get_psu_out_curr, + .get_psu_out_vol = dfd_get_psu_out_vol, + .get_psu_out_power = dfd_get_psu_out_power, + .get_psu_out_max_power = dfd_get_psu_out_max_power, + .get_psu_present_status = dfd_get_psu_present, + .get_psu_in_status = dfd_get_psu_in_status, + .get_psu_out_status = dfd_get_psu_out_status, + .get_psu_status_pmbus = dfd_get_psu_status_pmbus, + .get_psu_fan_speed = dfd_get_psu_fan_speed, + .get_psu_fan_ratio = dfd_get_psu_fan_ratio, + .set_psu_fan_ratio = dfd_set_psu_fan_ratio, + .get_psu_fan_direction = dfd_get_psu_fan_direction, + .get_psu_led_status = dfd_get_psu_led_status, + .get_psu_temp_alias = dfd_get_psu_temp_alias, + .get_psu_temp_type = dfd_get_psu_temp_type, + .get_psu_temp_max = dfd_get_psu_temp_max, + .set_psu_temp_max = dfd_set_psu_temp_max, + .get_psu_temp_min = dfd_get_psu_temp_min, + .set_psu_temp_min = dfd_set_psu_temp_min, + .get_psu_temp_value = dfd_get_psu_temp_value, + .get_psu_fan_speed_cal = dfd_get_psu_fan_speed_cal, + .get_psu_attr_threshold = dfd_get_psu_attr_threshold, + .get_psu_eeprom_size = dfd_get_psu_eeprom_size, + .read_psu_eeprom_data = dfd_read_psu_eeprom_data, + .get_psu_blackbox_info = dfd_get_psu_blackbox_info, + .get_psu_pmbus_info = dfd_get_psu_pmbus_info, + .clear_psu_blackbox = dfd_clear_psu_blackbox_info, + /* transceiver */ + .get_eth_number = dfd_get_eth_number, + .get_transceiver_power_on_status = dfd_get_transceiver_power_on_status, + .set_transceiver_power_on_status = dfd_set_transceiver_power_on_status, + .get_eth_power_on_status = dfd_get_eth_power_on_status, + .set_eth_power_on_status = dfd_set_eth_power_on_status, + .get_eth_tx_fault_status = dfd_get_eth_tx_fault_status, + .get_eth_tx_disable_status = dfd_get_eth_tx_disable_status, + .set_eth_tx_disable_status = dfd_set_eth_tx_disable_status, + .get_transceiver_present_status = dfd_get_transceiver_present_status, + .get_eth_present_status = dfd_get_eth_present_status, + .get_eth_rx_los_status = dfd_get_eth_rx_los_status, + .get_eth_reset_status = dfd_get_eth_reset_status, + .set_eth_reset_status = dfd_set_eth_reset_status, + .get_eth_low_power_mode_status = dfd_get_eth_low_power_mode_status, + .get_eth_interrupt_status = dfd_get_eth_interrupt_status, + .get_eth_eeprom_size = dfd_get_eth_eeprom_size, + .read_eth_eeprom_data = dfd_read_eth_eeprom_data, + .write_eth_eeprom_data = dfd_write_eth_eeprom_data, + .get_eth_optoe_type = dfd_get_eth_optoe_type, + .set_eth_optoe_type = dfd_set_eth_optoe_type, + /* sysled */ + .get_sys_led_status = dfd_get_sys_led_status, + .set_sys_led_status = dfd_set_sys_led_status, + .get_bmc_led_status = dfd_get_bmc_led_status, + .set_bmc_led_status = dfd_set_bmc_led_status, + .get_sys_fan_led_status = dfd_get_sys_fan_led_status, + .set_sys_fan_led_status = dfd_set_sys_fan_led_status, + .get_sys_psu_led_status = dfd_get_sys_psu_led_status, + .set_sys_psu_led_status = dfd_set_sys_psu_led_status, + .get_id_led_status = dfd_get_id_led_status, + .set_id_led_status = dfd_set_id_led_status, + /* FPGA */ + .get_main_board_fpga_number = dfd_get_main_board_fpga_number, + .get_main_board_fpga_alias = dfd_get_main_board_fpga_alias, + .get_main_board_fpga_type = dfd_get_main_board_fpga_type, + .get_main_board_fpga_firmware_version = dfd_get_main_board_fpga_firmware_version, + .get_main_board_fpga_board_version = dfd_get_main_board_fpga_board_version, + .get_main_board_fpga_test_reg = dfd_get_main_board_fpga_test_reg, + .set_main_board_fpga_test_reg = dfd_set_main_board_fpga_test_reg, + /* CPLD */ + .get_main_board_cpld_number = dfd_get_main_board_cpld_number, + .get_main_board_cpld_alias = dfd_get_main_board_cpld_alias, + .get_main_board_cpld_type = dfd_get_main_board_cpld_type, + .get_main_board_cpld_firmware_version = dfd_get_main_board_cpld_firmware_version, + .get_main_board_cpld_board_version = dfd_get_main_board_cpld_board_version, + .get_main_board_cpld_test_reg = dfd_get_main_board_cpld_test_reg, + .set_main_board_cpld_test_reg = dfd_set_main_board_cpld_test_reg, + /* watchdog */ + .get_watchdog_identify = dfd_get_watchdog_identify, + .get_watchdog_timeleft = dfd_get_watchdog_timeleft, + .get_watchdog_timeout = dfd_get_watchdog_timeout, + .set_watchdog_timeout = dfd_set_watchdog_timeout, + .get_watchdog_enable_status = dfd_get_watchdog_enable_status, + .set_watchdog_enable_status = dfd_set_watchdog_enable_status, + .set_watchdog_reset = dfd_set_watchdog_reset, + /* slot */ + .get_slot_number = dfd_get_slot_number, + .get_slot_temp_number = dfd_get_slot_temp_number, + .get_slot_vol_number = dfd_get_slot_vol_number, + .get_slot_curr_number = dfd_get_slot_curr_number, + .get_slot_cpld_number = dfd_get_slot_cpld_number, + .get_slot_fpga_number = dfd_get_slot_fpga_number, + .get_slot_model_name = dfd_get_slot_model_name, + .get_slot_vendor = dfd_get_slot_vendor, + .get_slot_serial_number = dfd_get_slot_serial_number, + .get_slot_part_number = dfd_get_slot_part_number, + .get_slot_hardware_version = dfd_get_slot_hardware_version, + .get_slot_status = dfd_get_slot_status, + .get_slot_led_status = dfd_get_slot_led_status, + .set_slot_led_status = dfd_set_slot_led_status, + .get_slot_power_status = dfd_get_slot_power_status, + .set_slot_power_status = dfd_set_slot_power_status, + .get_slot_temp_alias = dfd_get_slot_temp_alias, + .get_slot_temp_type = dfd_get_slot_temp_type, + .get_slot_temp_max = dfd_get_slot_temp_max, + .get_slot_temp_min = dfd_get_slot_temp_min, + .get_slot_temp_value = dfd_get_slot_temp_value, + .get_slot_vol_alias = dfd_get_slot_vol_alias, + .get_slot_vol_type = dfd_get_slot_vol_type, + .get_slot_vol_max = dfd_get_slot_vol_max, + .get_slot_vol_min = dfd_get_slot_vol_min, + .get_slot_vol_range = dfd_get_slot_vol_range, + .get_slot_vol_nominal_value = dfd_get_slot_vol_nominal_value, + .get_slot_vol_value = dfd_get_slot_vol_value, + .get_slot_curr_alias = dfd_get_slot_curr_alias, + .get_slot_curr_type = dfd_get_slot_curr_type, + .get_slot_curr_max = dfd_get_slot_curr_max, + .get_slot_curr_min = dfd_get_slot_curr_min, + .get_slot_curr_value = dfd_get_slot_curr_value, + .get_slot_fpga_alias = dfd_get_slot_fpga_alias, + .get_slot_fpga_type = dfd_get_slot_fpga_type, + .get_slot_fpga_firmware_version = dfd_get_slot_fpga_firmware_version, + .get_slot_fpga_board_version = dfd_get_slot_fpga_board_version, + .get_slot_fpga_test_reg = dfd_get_slot_fpga_test_reg, + .set_slot_fpga_test_reg = dfd_set_slot_fpga_test_reg, + .get_slot_cpld_alias = dfd_get_slot_cpld_alias, + .get_slot_cpld_type = dfd_get_slot_cpld_type, + .get_slot_cpld_firmware_version = dfd_get_slot_cpld_firmware_version, + .get_slot_cpld_board_version = dfd_get_slot_cpld_board_version, + .get_slot_cpld_test_reg = dfd_get_slot_cpld_test_reg, + .set_slot_cpld_test_reg = dfd_set_slot_cpld_test_reg, + .get_system_value = dfd_get_system_value, + .get_system_port_power_status = dfd_get_system_port_power_status, + .set_system_value = dfd_set_system_value, + /* eeprom */ + .get_eeprom_number = dfd_get_eeprom_number, + .get_eeprom_size = dfd_get_board_eeprom_size, + .get_eeprom_alias = dfd_get_board_eeprom_alias, + .get_eeprom_tag = dfd_get_board_eeprom_tag, + .get_eeprom_type = dfd_get_board_eeprom_type, + .read_eeprom_data = dfd_read_board_eeprom_data, + .write_eeprom_data = dfd_write_board_eeprom_data, +}; + +struct switch_drivers_s * s3ip_switch_driver_get(void) +{ + return &switch_drivers; +} + +static int32_t __init switch_driver_init(void) +{ + int ret; + + SWITCH_DEBUG(DBG_VERBOSE, "Enter.\n"); + ret = wb_dev_cfg_init(); + if (ret < 0) { + SWITCH_DEBUG(DBG_ERROR, "wb_dev_cfg_init failed ret %d.\n", ret); + return ret; + } + SWITCH_DEBUG(DBG_VERBOSE, "success.\n"); + return 0; +} + +static void __exit switch_driver_exit(void) +{ + SWITCH_DEBUG(DBG_VERBOSE, "switch_driver_exit.\n"); + wb_dev_cfg_exit(); + return; +} + +module_init(switch_driver_init); +module_exit(switch_driver_exit); +EXPORT_SYMBOL(s3ip_switch_driver_get); +module_param(g_switch_dbg_level, int, S_IRUGO | S_IWUSR); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_cpld_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_cpld_driver.c new file mode 100644 index 000000000000..d5bf876041ea --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_cpld_driver.c @@ -0,0 +1,274 @@ +/* + * An wb_cpld_driver driver for cpld devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#include "wb_module.h" +#include "dfd_cfg.h" +#include "dfd_cfg_adapter.h" +#include "dfd_cfg_info.h" + +int g_dfd_cpld_dbg_level = 0; +module_param(g_dfd_cpld_dbg_level, int, S_IRUGO | S_IWUSR); + +/** + * dfd_get_cpld_name - Obtain the CPLD name + * @main_dev_id: Motherboard :0 Subcard :5 + * @index:The number of the CPLD starts from 0 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_cpld_name(uint8_t main_dev_id, unsigned int cpld_index, char *buf, size_t count) +{ + uint64_t key; + char *cpld_name; + + if (buf == NULL) { + DBG_CPLD_DEBUG(DBG_ERROR, "param error, buf is NULL. main_dev_id: %u, cpld index: %u\n", + main_dev_id, cpld_index); + return -DFD_RV_INVALID_VALUE; + } + + if (count <= 0) { + DBG_CPLD_DEBUG(DBG_ERROR, "buf size error, count: %lu, main_dev_id: %u, cpld index: %u\n", + count, main_dev_id, cpld_index); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear(buf, count); + key = DFD_CFG_KEY(DFD_CFG_ITEM_CPLD_NAME, main_dev_id, cpld_index); + cpld_name = dfd_ko_cfg_get_item(key); + if (cpld_name == NULL) { + DBG_CPLD_DEBUG(DBG_ERROR, "main_dev_id: %u, cpld%u name config error, key_name:%s\n", + main_dev_id, cpld_index, key_to_name(DFD_CFG_ITEM_CPLD_NAME)); + return -DFD_RV_DEV_NOTSUPPORT; + } + + DBG_CPLD_DEBUG(DBG_VERBOSE, "%s\n", cpld_name); + snprintf(buf, count, "%s\n", cpld_name); + return strlen(buf); +} + +/** + * dfd_get_cpld_type - Obtain the CPLD model + * @main_dev_id: Motherboard :0 Subcard :5 + * @index:The number of the CPLD starts from 0 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_cpld_type(uint8_t main_dev_id, unsigned int cpld_index, char *buf, size_t count) +{ + uint64_t key; + char *cpld_type; + + if (buf == NULL) { + DBG_CPLD_DEBUG(DBG_ERROR, "param error, buf is NULL, main_dev_id: %u, cpld index: %u\n", + main_dev_id, cpld_index); + return -DFD_RV_INVALID_VALUE; + } + + if (count <= 0) { + DBG_CPLD_DEBUG(DBG_ERROR, "buf size error, count: %lu, main_dev_id: %u, cpld index: %u\n", + count, main_dev_id, cpld_index); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear(buf, count); + key = DFD_CFG_KEY(DFD_CFG_ITEM_CPLD_TYPE, main_dev_id, cpld_index); + cpld_type = dfd_ko_cfg_get_item(key); + if (cpld_type == NULL) { + DBG_CPLD_DEBUG(DBG_ERROR, "main_dev_id: %u, cpld%u type config error, key_name: %s\n", + main_dev_id, cpld_index, key_to_name(DFD_CFG_ITEM_CPLD_TYPE)); + return -DFD_RV_DEV_NOTSUPPORT; + } + + DBG_CPLD_DEBUG(DBG_VERBOSE, "%s\n", cpld_type); + snprintf(buf, count, "%s\n", cpld_type); + return strlen(buf); +} + +/** + * dfd_get_cpld_fw_version - Obtain the CPLD firmware version + * @main_dev_id: Motherboard :0 Subcard :5 + * @index:The number of the CPLD starts from 0 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_cpld_fw_version(uint8_t main_dev_id, unsigned int cpld_index, char *buf, size_t count) +{ + uint64_t key; + uint32_t value; + int rv; + + if (buf == NULL) { + DBG_CPLD_DEBUG(DBG_ERROR, "param error, buf is NULL, main_dev_id: %u, cpld index: %u\n", + main_dev_id, cpld_index); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DBG_CPLD_DEBUG(DBG_ERROR, "buf size error, count: %lu, main_dev_id: %u, cpld index: %u\n", + count, main_dev_id, cpld_index); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear(buf, count); + key = DFD_CFG_KEY(DFD_CFG_ITEM_CPLD_VERSION, main_dev_id, cpld_index); + rv = dfd_info_get_int(key, &value, NULL); + if (rv < 0) { + DBG_CPLD_DEBUG(DBG_ERROR, "main_dev_id: %u, cpld%u fw config error, key_name: %s, ret: %d\n", + main_dev_id, cpld_index, key_to_name(DFD_CFG_ITEM_CPLD_VERSION), rv); + return rv; + } + + DBG_CPLD_DEBUG(DBG_VERBOSE, "main_dev_id: %u, cpld%u firmware version: %x\n", + main_dev_id, cpld_index, value); + snprintf(buf, count, "%08x\n", value); + return strlen(buf); +} + +/** + * dfd_get_cpld_hw_version - Obtain the hardware version of the CPLD + * @main_dev_id: Motherboard :0 Subcard :5 + * @index:The number of the CPLD starts from 0 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_cpld_hw_version(uint8_t main_dev_id, unsigned int cpld_index, char *buf, size_t count) +{ + uint64_t key; + uint32_t value; + int rv; + + if (buf == NULL) { + DBG_CPLD_DEBUG(DBG_ERROR, "param error, buf is NULL, main_dev_id: %u, cpld index: %u\n", + main_dev_id, cpld_index); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DBG_CPLD_DEBUG(DBG_ERROR, "buf size error, count: %lu, main_dev_id: %u, cpld index: %u\n", + count, main_dev_id, cpld_index); + return -DFD_RV_INVALID_VALUE; + } + mem_clear(buf, count); + key = DFD_CFG_KEY(DFD_CFG_ITEM_CPLD_HW_VERSION, main_dev_id, cpld_index); + rv = dfd_info_get_int(key, &value, NULL); + if (rv < 0) { + DBG_CPLD_DEBUG(DBG_ERROR, "main_dev_id: %u, cpld%u fw config error, key_name: %s, ret: %d\n", + main_dev_id, cpld_index, key_to_name(DFD_CFG_ITEM_CPLD_HW_VERSION), rv); + return rv; + } + DBG_CPLD_DEBUG(DBG_VERBOSE, "main_dev_id: %u, cpld%u hardware version 0x%x\n", main_dev_id, cpld_index, value); + snprintf(buf, count, "%02x\n", value); + return strlen(buf); +} + +/** + * dfd_set_cpld_testreg - Set the CPLD test register value + * @main_dev_id: Motherboard :0 Subcard :5 + * @cpld_index:The number of the CPLD starts from 0 + * @value: Writes the value of the test register + * return: Success :0 + * : Failed: A negative value is returned + */ +int dfd_set_cpld_testreg(uint8_t main_dev_id, unsigned int cpld_index, int value) +{ + uint64_t key; + int ret; + + if (value < 0 || value > 0xff) { + DBG_CPLD_DEBUG(DBG_ERROR, "main_dev_id: %u, can't set cpld%u test reg value = 0x%02x\n", + main_dev_id, cpld_index, value); + return -DFD_RV_INVALID_VALUE; + } + + key = DFD_CFG_KEY(DFD_CFG_ITEM_CPLD_TEST_REG, main_dev_id, cpld_index); + ret = dfd_info_set_int(key, value); + if (ret < 0) { + DBG_CPLD_DEBUG(DBG_ERROR, "main_dev_id: %u, set cpld%u test reg error, key_name: %s, ret:%d\n", + main_dev_id, cpld_index, key_to_name(DFD_CFG_ITEM_CPLD_TEST_REG), ret); + return ret; + } + return DFD_RV_OK; +} + +/** + * dfd_get_cpld_testreg - Read the CPLD test register value + * @main_dev_id: Motherboard :0 Subcard :5 + * @cpld_index: The number of the CPLD starts from 0 + * @value: Read the test register value + * return: Success :0 + * : Failed: A negative value is returned + */ +int dfd_get_cpld_testreg(uint8_t main_dev_id, unsigned int cpld_index, int *value) +{ + uint64_t key; + int ret; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_CPLD_TEST_REG, main_dev_id, cpld_index); + ret = dfd_info_get_int(key, value, NULL); + if (ret < 0) { + DBG_CPLD_DEBUG(DBG_ERROR, "main_dev_id: %u, get cpld%u test reg error, key_name: %s, ret: %d\n", + main_dev_id, cpld_index, key_to_name(DFD_CFG_ITEM_CPLD_TEST_REG), ret); + return ret; + } + return DFD_RV_OK; +} + +/** + * dfd_get_cpld_testreg_str - Read the CPLD test register value + * @main_dev_id: Motherboard :0 Subcard :5 + * @cpld_index: The number of the CPLD starts from 0 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_cpld_testreg_str(uint8_t main_dev_id, unsigned int cpld_index, + char *buf, size_t count) +{ + int ret, value; + + if (buf == NULL) { + DBG_CPLD_DEBUG(DBG_ERROR, "param error, buf is NULL, main_dev_id: %u, cpld index: %u\n", + main_dev_id, cpld_index); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DBG_CPLD_DEBUG(DBG_ERROR, "buf size error, count: %lu, main_dev_id: %u, cpld index: %u\n", + count, main_dev_id, cpld_index); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear(buf, count); + ret = dfd_get_cpld_testreg(main_dev_id, cpld_index, &value); + if (ret < 0) { + return ret; + } + return (ssize_t)snprintf(buf, count, "0x%02x\n", value); +} + diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_eeprom_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_eeprom_driver.c new file mode 100644 index 000000000000..7a3b760c2266 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_eeprom_driver.c @@ -0,0 +1,230 @@ +/* + * An wb_eeprom_driver driver for eeprom devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#include "wb_module.h" +#include "dfd_cfg.h" +#include "dfd_cfg_adapter.h" +#include "dfd_tlveeprom.h" + +int g_dfd_eeprom_dbg_level = 0; +module_param(g_dfd_eeprom_dbg_level, int, S_IRUGO | S_IWUSR); + +/** + * dfd_get_eeprom_size - Gets the data size of the eeprom + * @e2_type: This section describes the E2 type, including system, PSU, fan, and module E2 + * @index: E2 number + * return: Succeeded: The data size of the eeprom is returned + * : Failed: A negative value is returned + */ +int dfd_get_eeprom_size(int e2_type, int index) +{ + uint64_t key; + int *p_eeprom_size; + + /* Obtain the eeprom size */ + key = DFD_CFG_KEY(DFD_CFG_ITEM_EEPROM_SIZE, e2_type, index); + + p_eeprom_size = dfd_ko_cfg_get_item(key); + if (p_eeprom_size == NULL) { + DBG_EEPROM_DEBUG(DBG_ERROR, "get eeprom size error. key_name:%s\n", + key_to_name(DFD_CFG_ITEM_EEPROM_SIZE)); + return -DFD_RV_DEV_NOTSUPPORT; + } + + return *p_eeprom_size; +} + +/** + * dfd_read_eeprom_data - Read eeprom data + * @e2_type: This section describes the E2 type, including system, PSU, fan, and module E2 + * @index: E2 number + * @buf: eeprom data receives buf + * @offset: The offset address of the read + * @count: Read length + * return: Success: Returns the length of fill buf + * : Failed: A negative value is returned + */ +ssize_t dfd_read_eeprom_data(int e2_type, int index, char *buf, loff_t offset, size_t count) +{ + uint64_t key; + ssize_t rd_len; + char *eeprom_path; + + if (buf == NULL || offset < 0 || count <= 0) { + DBG_EEPROM_DEBUG(DBG_ERROR, "params error, offset: 0x%llx, rd_count: %lu.\n", + offset, count); + return -DFD_RV_INVALID_VALUE; + } + + /* Obtain the eeprom read path*/ + key = DFD_CFG_KEY(DFD_CFG_ITEM_EEPROM_PATH, e2_type, index); + eeprom_path = dfd_ko_cfg_get_item(key); + if (eeprom_path == NULL) { + DBG_EEPROM_DEBUG(DBG_ERROR, "get eeprom path error, e2_type: %d, index: %d, key_name: %s\n", + e2_type, index, key_to_name(DFD_CFG_ITEM_EEPROM_PATH)); + return -DFD_RV_DEV_NOTSUPPORT; + } + + DBG_EEPROM_DEBUG(DBG_VERBOSE, "e2_type: %d, index: %d, path: %s, offset: 0x%llx, \ + rd_count: %lu\n", e2_type, index, eeprom_path, offset, count); + + mem_clear(buf, count); + rd_len = dfd_ko_read_file(eeprom_path, offset, buf, count); + if (rd_len < 0) { + DBG_EEPROM_DEBUG(DBG_ERROR, "read eeprom data failed, loc: %s, offset: 0x%llx, \ + rd_count: %lu, ret: %ld,\n", eeprom_path, offset, count, rd_len); + } else { + DBG_EEPROM_DEBUG(DBG_VERBOSE, "read eeprom data success, loc: %s, offset: 0x%llx, \ + rd_count: %lu, rd_len: %ld,\n", eeprom_path, offset, count, rd_len); + } + + return rd_len; +} + +/** + * dfd_write_eeprom_data - Write eeprom data + * @e2_type: This section describes the E2 type, including system, PSU, fan, and module E2 + * @index: E2 number + * @buf: eeprom data buf + * @offset: The offset address of the write + * @count: Write length + * return: Success: The length of the written data is returned + * : Failed: A negative value is returned + */ +ssize_t dfd_write_eeprom_data(int e2_type, int index, char *buf, loff_t offset, size_t count) +{ + uint64_t key; + ssize_t wr_len; + char *eeprom_path; + + if (buf == NULL || offset < 0 || count <= 0) { + DBG_EEPROM_DEBUG(DBG_ERROR, "params error, offset: 0x%llx, count: %lu.\n", offset, count); + return -DFD_RV_INVALID_VALUE; + } + + /* Obtain the eeprom read path */ + key = DFD_CFG_KEY(DFD_CFG_ITEM_EEPROM_PATH, e2_type, index); + eeprom_path = dfd_ko_cfg_get_item(key); + if (eeprom_path == NULL) { + DBG_EEPROM_DEBUG(DBG_ERROR, "get eeprom path error, e2_type: %d, index: %d, key_name: %s\n", + e2_type, index, key_to_name(DFD_CFG_ITEM_EEPROM_PATH)); + return -DFD_RV_DEV_NOTSUPPORT; + } + + DBG_EEPROM_DEBUG(DBG_VERBOSE, "e2_type: %d, index: %d, path: %s, offset: 0x%llx, \ + wr_count: %lu.\n", e2_type, index, eeprom_path, offset, count); + + wr_len = dfd_ko_write_file(eeprom_path, offset, buf, count); + if (wr_len < 0) { + DBG_EEPROM_DEBUG(DBG_ERROR, "write eeprom data failed, loc:%s, offset: 0x%llx, \ + wr_count: %lu, ret: %ld.\n", eeprom_path, offset, count, wr_len); + } else { + DBG_EEPROM_DEBUG(DBG_VERBOSE, "write eeprom data success, loc:%s, offset: 0x%llx, \ + wr_count: %lu, wr_len: %ld.\n", eeprom_path, offset, count, wr_len); + } + + return wr_len; +} + +ssize_t dfd_get_eeprom_alias(int e2_type, unsigned int e2_index, char *buf, size_t count) +{ + uint64_t key; + char *e2_alias; + + if (buf == NULL) { + DBG_EEPROM_DEBUG(DBG_ERROR, "param error buf is NULL.\n"); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DBG_EEPROM_DEBUG(DBG_ERROR, "buf size error, count: %lu\n", count); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear(buf, count); + key = DFD_CFG_KEY(DFD_CFG_ITEM_EEPROM_ALIAS, e2_type, e2_index); + e2_alias = dfd_ko_cfg_get_item(key); + if (e2_alias == NULL) { + DBG_EEPROM_DEBUG(DBG_ERROR, "get eeprom alias config error, e2_type: %d, e2_index: %u, key_name: %s\n", + e2_type, e2_index, key_to_name(DFD_CFG_ITEM_EEPROM_ALIAS)); + return -DFD_RV_DEV_NOTSUPPORT; + } + + DBG_FPGA_DEBUG(DBG_VERBOSE, "%s\n", e2_alias); + snprintf(buf, count, "%s\n", e2_alias); + return strlen(buf); +} + +ssize_t dfd_get_eeprom_tag(int e2_type, unsigned int e2_index, char *buf, size_t count) +{ + uint64_t key; + char *e2_tag; + + if (buf == NULL) { + DBG_EEPROM_DEBUG(DBG_ERROR, "param error buf is NULL.\n"); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DBG_EEPROM_DEBUG(DBG_ERROR, "buf size error, count: %lu\n", count); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear(buf, count); + key = DFD_CFG_KEY(DFD_CFG_ITEM_EEPROM_TAG, e2_type, e2_index); + e2_tag = dfd_ko_cfg_get_item(key); + if (e2_tag == NULL) { + DBG_EEPROM_DEBUG(DBG_ERROR, "get eeprom tag config error, e2_type: %d, e2_index: %u, key: %s\n", + e2_type, e2_index, key_to_name(DFD_CFG_ITEM_EEPROM_TAG)); + return -DFD_RV_DEV_NOTSUPPORT; + } + + DBG_FPGA_DEBUG(DBG_VERBOSE, "%s\n", e2_tag); + snprintf(buf, count, "%s\n", e2_tag); + return strlen(buf); +} + +ssize_t dfd_get_eeprom_type(int e2_type, unsigned int e2_index, char *buf, size_t count) +{ + uint64_t key; + char *eeprom_type; + + if (buf == NULL) { + DBG_EEPROM_DEBUG(DBG_ERROR, "param error buf is NULL.\n"); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DBG_EEPROM_DEBUG(DBG_ERROR, "buf size error, count: %lu\n", count); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear(buf, count); + key = DFD_CFG_KEY(DFD_CFG_ITEM_EEPROM_TYPE, e2_type, e2_index); + eeprom_type = dfd_ko_cfg_get_item(key); + if (eeprom_type == NULL) { + DBG_EEPROM_DEBUG(DBG_ERROR, "get eeprom type config error, e2_type: %d, e2_index: %u, key_name: %s\n", + e2_type, e2_index, key_to_name(DFD_CFG_ITEM_EEPROM_TYPE)); + return -DFD_RV_DEV_NOTSUPPORT; + } + + DBG_FPGA_DEBUG(DBG_VERBOSE, "%s\n", eeprom_type); + snprintf(buf, count, "%s\n", eeprom_type); + return strlen(buf); +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_fan_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_fan_driver.c new file mode 100644 index 000000000000..77f88429edfb --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_fan_driver.c @@ -0,0 +1,1093 @@ +/* + * An wb_fan_driver driver for fan devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include + +#include "wb_module.h" +#include "dfd_cfg.h" +#include "dfd_cfg_adapter.h" +#include "dfd_cfg_info.h" +#include "dfd_frueeprom.h" + +#define DFD_FAN_EEPROM_MODE_TLV_STRING "tlv" +#define DFD_FAN_EEPROM_MODE_FRU_STRING "fru" +#define FAN_SIZE (256) + +typedef enum fan_present_status_e { + ABSENT = 0, + PRESENT = 1, +} fan_present_status_t; + +typedef enum fan_motor_status_e { + MOTOR_STALL = 0, + MOTOR_ROLL = 1, +} fan_motor_status_t; + +typedef enum fan_eeprom_mode_e { + FAN_EEPROM_MODE_TLV, /* TLV */ + FAN_EEPROM_MODE_FRU, /*FRU*/ +} fan_eeprom_mode_t; + +typedef struct dfd_dev_head_info_s { + uint8_t ver; /* The version number defined in the E2PROM file, initially 0x01 */ + uint8_t flag; /* The new version E2PROM is identified as 0x7E */ + uint8_t hw_ver; /* It consists of two parts: the main version number and the revised version */ + uint8_t type; /* Hardware type definition information */ + int16_t tlv_len; /* Valid data length (16 bits) */ +} dfd_dev_head_info_t; + +typedef struct dfd_dev_tlv_info_s { + uint8_t type; /* Data type */ + uint8_t len; /* Data length */ + uint8_t data[0]; /* Data */ +} dfd_dev_tlv_info_t; + +/* Specifies the fixed value of the fan speed */ +typedef enum wb_fan_threshold_e { + FAN_SPEED_MIN = 1, /* Minimum value */ + FAN_SPEED_MAX = 2, /* Maximum value */ + FAN_SPEED_TOLERANCE = 3, /* tolerance */ + FAN_SPEED_TARGET_0 = 0x10, /* index of the rated speed when PWM=0x */ + FAN_SPEED_TARGET_10 = 0x11, + FAN_SPEED_TARGET_20 = 0x12, + FAN_SPEED_TARGET_30 = 0x13, + FAN_SPEED_TARGET_40 = 0x14, + FAN_SPEED_TARGET_50 = 0x15, + FAN_SPEED_TARGET_60 = 0x16, + FAN_SPEED_TARGET_70 = 0x17, + FAN_SPEED_TARGET_80 = 0x18, + FAN_SPEED_TARGET_90 = 0x19, + FAN_SPEED_TARGET_100 = 0x1a, /* index of the rated speed when PWM=100 */ + +} wb_fan_threshold_t; + +/* fan_threshold_[Threshold type(high 8bit)+Master device type(low 8bit)]_[subdevice ID(high 4bit)+Front and rear motor id(low 4bit)] */ +#define DFD_GET_FAN_THRESHOLD_KEY1(threshold_type, main_dev_id) \ + (((threshold_type & 0xff) << 8) | (main_dev_id & 0xff)) +#define DFD_GET_FAN_THRESHOLD_KEY2(sub_type_id, motor_id) \ + (((sub_type_id & 0x0f) << 4) | (motor_id & 0x0f)) + +int g_dfd_fan_dbg_level = 0; +module_param(g_dfd_fan_dbg_level, int, S_IRUGO | S_IWUSR); + +static char *dfd_get_fan_sysfs_name(void) +{ + uint64_t key; + char *sysfs_name; + + /* string type configuration item */ + key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_SYSFS_NAME, 0, 0); + sysfs_name = dfd_ko_cfg_get_item(key); + if (sysfs_name == NULL) { + DFD_FAN_DEBUG(DBG_VERBOSE, "key_name=%s, sysfs_name is NULL, use default way.\n", + key_to_name(DFD_CFG_ITEM_FAN_SYSFS_NAME)); + } else { + DFD_FAN_DEBUG(DBG_VERBOSE, "sysfs_name: %s.\n", sysfs_name); + } + return sysfs_name; +} + +/** + * dfd_get_fan_eeprom_mode - The fan type E2 is obtained + * return: 0:TLV + * 1:FRU + * : Negative value - Read failed + */ +static int dfd_get_fan_eeprom_mode(void) +{ + uint64_t key; + int mode; + char *name; + + /* string type configuration item */ + key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_E2_MODE, 0, 0); + name = dfd_ko_cfg_get_item(key); + if (name == NULL) { + /* By default, the TLV format is returned */ + DFD_FAN_DEBUG(DBG_WARN, "get fan eeprom mode fail, key_name=%s\n", + key_to_name(DFD_CFG_ITEM_FAN_E2_MODE)); + return FAN_EEPROM_MODE_TLV; + } + + DFD_FAN_DEBUG(DBG_VERBOSE, "fan eeprom mode_name %s.\n", name); + if (!strncmp(name, DFD_FAN_EEPROM_MODE_TLV_STRING, strlen(DFD_FAN_EEPROM_MODE_TLV_STRING))) { + mode = FAN_EEPROM_MODE_TLV; + } else if (!strncmp(name, DFD_FAN_EEPROM_MODE_FRU_STRING, strlen(DFD_FAN_EEPROM_MODE_FRU_STRING))) { + mode = FAN_EEPROM_MODE_FRU; + } else { + /* The default TLV mode is returned */ + mode = FAN_EEPROM_MODE_TLV; + } + + DFD_FAN_DEBUG(DBG_VERBOSE, "fan eeprom mode %d.\n", mode); + return mode; +} + +static int dfd_fan_tlv_eeprom_read(int bus, int addr, uint8_t cmd, char *buf, int len, + const char *sysfs_name) +{ + dfd_dev_head_info_t info; + char tmp_tlv_len[sizeof(uint16_t)]; + char *tlv_data; + dfd_dev_tlv_info_t *tlv; + int buf_len; + int rv, match_flag; + + rv = dfd_ko_i2c_read(bus, addr, 0, (uint8_t *)&info, sizeof(dfd_dev_head_info_t), sysfs_name); + if (rv < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "read fan i2c failed, bus: %d, addr: 0x%x, rv: %d\n", + bus, addr, rv); + return -DFD_RV_DEV_FAIL; + } + + /* convert TLV_LEN */ + memcpy(tmp_tlv_len, (uint8_t *)&info.tlv_len, sizeof(uint16_t)); + info.tlv_len = (tmp_tlv_len[0] << 8) + tmp_tlv_len[1]; + + if ((info.tlv_len <= 0) || (info.tlv_len > 0xFF)) { + DFD_FAN_DEBUG(DBG_ERROR, "fan maybe not set mac.\n"); + return -DFD_RV_TYPE_ERR; + } + DFD_FAN_DEBUG(DBG_VERBOSE, "info.tlv_len: %d\n", info.tlv_len); + + tlv_data = (uint8_t *)kmalloc(info.tlv_len, GFP_KERNEL); + if (tlv_data == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "tlv_data kmalloc failed \n"); + return -DFD_RV_NO_MEMORY; + } + mem_clear(tlv_data, info.tlv_len); + + rv = dfd_ko_i2c_read(bus, addr, sizeof(dfd_dev_head_info_t), tlv_data, info.tlv_len, sysfs_name); + if (rv < 0) { + DFD_FAN_DEBUG(DBG_ERROR,"fan eeprom read failed\n"); + kfree(tlv_data); + return -DFD_RV_DEV_FAIL; + } + + buf_len = len - 1; + match_flag = 0; + for (tlv = (dfd_dev_tlv_info_t *)tlv_data; (ulong)tlv < (ulong)tlv_data + info.tlv_len;) { + DFD_FAN_DEBUG(DBG_VERBOSE, "tlv: %p, tlv->type: 0x%x, tlv->len: 0x%x info->tlv_len: 0x%x\n", + tlv, tlv->type, tlv->len, info.tlv_len); + if (tlv->type == cmd && tlv->len <= buf_len) { + DFD_FAN_DEBUG(DBG_VERBOSE, "find tlv data, copy...\n"); + memcpy(buf, (uint8_t *)tlv->data, tlv->len); + buf_len = (uint32_t)tlv->len; + match_flag = 1; + break; + } + tlv = (dfd_dev_tlv_info_t *)((uint8_t*)tlv + sizeof(dfd_dev_tlv_info_t) + tlv->len); + } + kfree(tlv_data); + if (match_flag == 0) { + DFD_FAN_DEBUG(DBG_ERROR,"can't find fan tlv date. bus: %d, addr: 0x%02x, tlv type: %d.\n", + bus, addr, cmd); + return -DFD_RV_TYPE_ERR; + } + return buf_len; +} + +/** + * dfd_get_fan_present_status - Obtain the fan running status + * @index: Number of the fan, starting from 1 + * @motor_index: Motor number, starting with 1 + * return: 0:STALL + * 1:ROLL + * : Negative value - Read failed + */ +static int dfd_get_fan_roll_status(unsigned int fan_index, unsigned int motor_index) +{ + uint64_t key; + int ret; + int status; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_ROLL_STATUS, fan_index, motor_index); + ret = dfd_info_get_int(key, &status, NULL); + if (ret < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "get fan roll status error, fan: %u, motor: %u, key_name: %s\n", + fan_index, motor_index, key_to_name(DFD_CFG_ITEM_FAN_ROLL_STATUS)); + return ret; + } + return status; +} + +/** + * dfd_get_fan_present_status - Obtain the fan status + * @index: Number of the fan, starting from 1 + * return: 0:ABSENT + * 1:PRESENT + * : Negative value - Read failed + */ +int dfd_get_fan_present_status(unsigned int fan_index) +{ + uint64_t key; + int ret; + int status; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_DEV_PRESENT_STATUS, WB_MAIN_DEV_FAN, fan_index); + ret = dfd_info_get_int(key, &status, NULL); + if (ret < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "get fan present status error, key_name: %s\n", + key_to_name(DFD_CFG_ITEM_DEV_PRESENT_STATUS)); + return ret; + } + return status; +} + +/** + * dfd_get_fan_status - Obtaining fan status + * @index: Number of the fan, starting from 1 + * return: 0:ABSENT + * 1:OK + * 2:NOT OK + * : Negative value - Read failed + */ +static int dfd_get_fan_status(unsigned int fan_index) +{ + int motor_num, motor_index, status, errcnt; + + /* Obtaining fan status */ + status = dfd_get_fan_present_status(fan_index); + if (status != PRESENT) { + DFD_FAN_DEBUG(DBG_ERROR, "fan index: %u, status: %d\n", fan_index, status); + return status; + } + + /* Get the motor running state */ + motor_num = dfd_get_dev_number(WB_MAIN_DEV_FAN, WB_MINOR_DEV_MOTOR); + if (motor_num <= 0) { + DFD_FAN_DEBUG(DBG_ERROR, "get motor number error: %d\n", motor_num); + return -DFD_RV_DEV_FAIL; + } + errcnt = 0; + for (motor_index = 1; motor_index <= motor_num; motor_index++) { + status = dfd_get_fan_roll_status(fan_index, motor_index); + if (status < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "get fan roll status error, fan index: %u, motor index: %d, status: %d\n", + fan_index, motor_index, status); + return status; + } + if (status != MOTOR_ROLL) { + DFD_FAN_DEBUG(DBG_ERROR, + "stall:fan index: %u, motor index: %d, status: %d\n",fan_index, motor_index, status); + errcnt++; + } + } + if (errcnt > 0) { + return FAN_STATUS_NOT_OK; + } + return FAN_STATUS_OK; +} + +/** + * dfd_get_fan_status_str - Obtaining fan status + * @index: Number of the fan, starting from 1 + * return: Success: Length of the status string + * : Negative value - Read failed + */ +ssize_t dfd_get_fan_status_str(unsigned int fan_index, char *buf, size_t count) +{ + int ret; + + if (buf == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "params error, fan_index: %u count: %lu", + fan_index, count); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DFD_FAN_DEBUG(DBG_ERROR, "buf size error, count: %lu, fan index: %u\n", + count, fan_index); + return -DFD_RV_INVALID_VALUE; + } + ret = dfd_get_fan_status(fan_index); + if (ret < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "get fan status error, ret: %d, fan_index: %u\n", + ret, fan_index); + return ret; + } + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%d\n", ret); +} + + +/** + * dfd_get_fan_present_str - Obtaining fan present status + * @index: Number of the fan, starting from 1 + * return: Success: Length of the status string + * : Negative value - Read failed + */ +ssize_t dfd_get_fan_present_str(unsigned int fan_index, char *buf, size_t count) +{ + int ret; + + if (buf == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "params error, fan_index: %u count: %lu", + fan_index, count); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DFD_FAN_DEBUG(DBG_ERROR, "buf size error, count: %lu, fan index: %u\n", + count, fan_index); + return -DFD_RV_INVALID_VALUE; + } + ret = dfd_get_fan_present_status(fan_index); + if (ret < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "get fan present status error, ret: %d, fan_index: %u\n", + ret, fan_index); + return ret; + } + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%d\n", ret); +} + +/** + * dfd_get_fan_motor_status_str - Obtain the fan motor status + * @fan_index: Number of the fan, starting from 1 + * @motor_index: Motor number, starting with 1 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success :0 + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fan_motor_status_str(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count) +{ + int ret; + + if (buf == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "buf is NULL, fan index: %u, motor index: %u\n", + fan_index, motor_index); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DFD_FAN_DEBUG(DBG_ERROR, "buf size error, count: %lu, fan index: %u, motor index: %u\n", + count, fan_index, motor_index); + return -DFD_RV_INVALID_VALUE; + } + ret = dfd_get_fan_roll_status(fan_index, motor_index); + if (ret < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "get fan motor status error, ret: %d, fan_index: %u, motor index: %u\n", + ret, fan_index, motor_index); + return ret; + } + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%d\n", ret); +} + +/** + * dfd_fan_product_name_decode - Fan name conversion + * @psu_buf: Original fan name + * @buf_len: fan_buf length + * return: Success :0 + * : Failed: A negative value is returned + */ +static int dfd_fan_product_name_decode(char *fan_buf, int buf_len) +{ + uint64_t key; + int i, j; + char *p_fan_name, *p_decode_name; + int *fan_type_num; + int *fan_display_num; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_DEV_NUM, WB_MAIN_DEV_FAN, WB_MINOR_DEV_FAN); + fan_display_num = dfd_ko_cfg_get_item(key); + if (fan_display_num == NULL) { + DFD_FAN_DEBUG(DBG_VERBOSE, "get fan display name number error, key_name:%s, \ + skip fan name decode\n", key_to_name(DFD_CFG_ITEM_DEV_NUM)); + return DFD_RV_OK; + } + + for (i = 1; i <= *fan_display_num; i++) { + key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_TYPE_NUM, i, 0); + fan_type_num = dfd_ko_cfg_get_item(key); + if (fan_type_num == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "config error, get fan type number error, key_name: %s\n", + key_to_name(DFD_CFG_ITEM_FAN_TYPE_NUM)); + return -DFD_RV_DEV_NOTSUPPORT; + } + for (j = 1; j <= *fan_type_num; j++) { + key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_NAME, i, j); + p_fan_name = dfd_ko_cfg_get_item(key); + if (p_fan_name == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "config error, get fan origin name error, key_name: %s\n", + key_to_name(DFD_CFG_ITEM_FAN_NAME)); + return -DFD_RV_DEV_NOTSUPPORT; + } + if (!strncmp(fan_buf, p_fan_name, strlen(p_fan_name))) { + key = DFD_CFG_KEY(DFD_CFG_ITEM_DECODE_FAN_NAME, i, 0); + p_decode_name = dfd_ko_cfg_get_item(key); + if (p_decode_name == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "config error, get fan decode name error, key_name: %s\n", + key_to_name(DFD_CFG_ITEM_DECODE_FAN_NAME)); + return -DFD_RV_DEV_NOTSUPPORT; + } + mem_clear(fan_buf, buf_len); + strlcpy(fan_buf, p_decode_name, buf_len); + DFD_FAN_DEBUG(DBG_VERBOSE, "fan name match ok, display fan name: %s.\n", fan_buf); + return DFD_RV_OK; + } + } + } + + DFD_FAN_DEBUG(DBG_ERROR, "fan name: %s error, can't match.\n", fan_buf); + return -DFD_RV_DEV_NOTSUPPORT; +} + +/** + * dfd_get_fan_info - Obtaining Fan Information + * @index: Number of the fan, starting from 1 + * @cmd: Fan information type, fan name :2, fan serial number :3, fan hardware version :5 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fan_info(unsigned int fan_index, uint8_t cmd, char *buf, size_t count) +{ + uint64_t key; + int rv, eeprom_mode; + char fan_buf[FAN_SIZE]; + dfd_i2c_dev_t *i2c_dev; + const char *sysfs_name; + + if (buf == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "buf is NULL, fan index: %u, cmd: 0x%x.\n", fan_index, cmd); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DFD_FAN_DEBUG(DBG_ERROR, "buf size error, count: %lu, fan index: %u, cmd: 0x%x.\n", + count, fan_index, cmd); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear(buf, count); + key = DFD_CFG_KEY(DFD_CFG_ITEM_OTHER_I2C_DEV, WB_MAIN_DEV_FAN, fan_index); + i2c_dev = dfd_ko_cfg_get_item(key); + if (i2c_dev == NULL) { + DFD_FAN_DEBUG(DBG_VERBOSE, "can't find fan%u I2C dfd config, key_name: %s\n", + fan_index, key_to_name(DFD_CFG_ITEM_OTHER_I2C_DEV)); + return -DFD_RV_DEV_NOTSUPPORT; + } + + sysfs_name = dfd_get_fan_sysfs_name(); + eeprom_mode = dfd_get_fan_eeprom_mode(); + mem_clear(fan_buf, FAN_SIZE); + if (eeprom_mode == FAN_EEPROM_MODE_TLV) { + if (cmd == DFD_DEV_INFO_TYPE_PART_NUMBER) { + DFD_FAN_DEBUG(DBG_VERBOSE, "fan tlv not have part_number attributes\n"); + return -DFD_RV_DEV_NOTSUPPORT; + } + rv = dfd_fan_tlv_eeprom_read(i2c_dev->bus, i2c_dev->addr, cmd, fan_buf, FAN_SIZE, sysfs_name); + } else { + if (cmd == DFD_DEV_INFO_TYPE_VENDOR) { + rv = dfd_get_fru_board_data(i2c_dev->bus, i2c_dev->addr, cmd, fan_buf, FAN_SIZE, sysfs_name); + } else { + rv = dfd_get_fru_data(i2c_dev->bus, i2c_dev->addr, cmd, fan_buf, FAN_SIZE, sysfs_name); + } + } + + if (rv < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "fan eeprom read failed"); + return -DFD_RV_DEV_FAIL; + } + + DFD_FAN_DEBUG(DBG_VERBOSE, "%s\n", fan_buf); + /* Fan product name conversion */ + if (cmd == DFD_DEV_INFO_TYPE_NAME) { + rv = dfd_fan_product_name_decode(fan_buf, FAN_SIZE); + if (rv < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "fan name decode error. rv: %d\n", rv); + } + } + + snprintf(buf, count, "%s\n", fan_buf); + return strlen(buf); +} + +/** + * dfd_get_fan_speed - Obtain the fan speed + * @fan_index: Number of the fan, starting from 1 + * @motor_index: Motor number, starting with 1 + * @speed: Speed value + * return: Success :0 + * : Failed: A negative value is returned + */ +int dfd_get_fan_speed(unsigned int fan_index, unsigned int motor_index, unsigned int *speed) +{ + uint64_t key; + int ret, speed_tmp; + + if (speed == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "param error. fan index: %u, motor index: %u\n", + fan_index, motor_index); + return -DFD_RV_INVALID_VALUE; + } + + key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_SPEED, fan_index, motor_index); + ret = dfd_info_get_int(key, &speed_tmp, NULL); + if (ret < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "get fan%u motor%u speed error, key: %s, ret: %d\n", + fan_index, motor_index, key_to_name(DFD_CFG_ITEM_FAN_SPEED), ret); + return ret; + } + + if (speed_tmp == 0 || speed_tmp == 0xffff) { + *speed = 0; + } else { + *speed = 15000000 / speed_tmp; + } + return DFD_RV_OK; +} + +/** + * dfd_get_fan_speed_str - Obtain the fan speed + * @fan_index: Number of the fan, starting from 1 + * @motor_index: Motor number, starting with 1 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success :0 + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fan_speed_str(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count) +{ + int ret; + unsigned int speed; + + if (buf == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "buf is NULL, fan index: %u, motor index: %u\n", + fan_index, motor_index); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DFD_FAN_DEBUG(DBG_ERROR, "buf size error, count: %lu, fan index: %u, motor index: %u\n", + count, fan_index, motor_index); + return -DFD_RV_INVALID_VALUE; + } + ret = dfd_get_fan_speed(fan_index, motor_index, &speed); + if (ret < 0) { + return ret; + } + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%d\n", speed); +} + +/** + * dfd_set_fan_pwm - set the fan speed duty cycle + * @fan_index: Number of the fan, starting from 1 + * @pwm: Duty cycle + * return: Success :0 + * : Failed: A negative value is returned + */ +int dfd_set_fan_pwm(unsigned int fan_index, int pwm) +{ + uint64_t key; + int ret, data; + + if (pwm < 0 || pwm > 100) { + DFD_FAN_DEBUG(DBG_ERROR, "can not set pwm = %d.\n", pwm); + return -DFD_RV_INVALID_VALUE; + } + + data = pwm * 255 / 100; + key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_RATIO, fan_index, 0); + ret = dfd_info_set_int(key, data); + if (ret < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "set fan%u ratio error, key_name: %s,ret: %d\n", + fan_index, key_to_name(DFD_CFG_ITEM_FAN_RATIO), ret); + return ret; + } + return DFD_RV_OK; +} + +/** + * dfd_get_fan_pwm - Obtain the fan speed duty cycle + * @fan_index: Number of the fan, starting from 1 + * @pwm: Duty cycle + * return: Success :0 + * : Failed: A negative value is returned + */ +int dfd_get_fan_pwm(unsigned int fan_index, int *pwm) +{ + uint64_t key; + int ret, ratio; + + if (pwm == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "param error. fan index: %u\n", fan_index); + return -DFD_RV_INVALID_VALUE; + } + + key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_RATIO, fan_index, 0); + ret = dfd_info_get_int(key, &ratio, NULL); + if (ret < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "get fan%u ratio error, key_name: %s,ret: %d\n", + fan_index, key_to_name(DFD_CFG_ITEM_FAN_RATIO), ret); + return ret; + } + if ((ratio * 100) % 255 > 0) { + *pwm = ratio * 100 / 255 + 1; + } else { + *pwm = ratio * 100 / 255; + } + return DFD_RV_OK; +} + +/** + * dfd_get_fan_pwm_str - Obtain the fan speed duty cycle + * @fan_index: Number of the fan, starting from 1 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success :0 + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fan_pwm_str(unsigned int fan_index, char *buf, size_t count) +{ + int ret, value; + + if (buf == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "buf is NULL, fan index: %u\n", fan_index); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DFD_FAN_DEBUG(DBG_ERROR, "buf size error, count: %lu, fan index: %u\n", count, + fan_index); + return -DFD_RV_INVALID_VALUE; + } + + ret = dfd_get_fan_pwm(fan_index, &value); + if (ret < 0) { + return ret; + } + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%d\n", value); +} + +static int dfd_get_fan_type(unsigned int fan_index, int *fan_type, int *fan_sub_type) +{ + int rv; + char fan_buf[FAN_SIZE]; + + /* Get the fan name */ + rv = dfd_get_fan_info(fan_index, DFD_DEV_INFO_TYPE_NAME, fan_buf, FAN_SIZE); + if (rv < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "get fan%u name error, ret: %d\n", fan_index, rv); + return rv; + } + + DFD_FAN_DEBUG(DBG_VERBOSE, "%s\n", fan_buf); + dfd_info_del_no_print_string(fan_buf); + + DFD_FAN_DEBUG(DBG_VERBOSE, "dfd_fan_product_name_decode get fan name %s\n", fan_buf); + rv = dfd_ko_cfg_get_fan_type_by_name((char *)fan_buf, fan_type, fan_sub_type); + if (rv < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "get fan%u type by name error, ret: %d\n", fan_index, rv); + return -DFD_RV_NO_NODE; + } + + DFD_FAN_DEBUG(DBG_VERBOSE, "get fan%u type %d subtype %d by name ok\n", fan_index, *fan_type, *fan_sub_type); + return DFD_RV_OK; +} + +/** + * dfd_get_fan_speed_target - Obtain the standard fan speed + * @fan_index + * @motor_index + * @value Standard speed value + * @returns: 0 success, negative value: failed + */ +int dfd_get_fan_speed_target(unsigned int fan_index, unsigned int motor_index, int *value) +{ + uint64_t key; + int *p_fan_speed_target; + int key1, key2, fan_type, fan_sub_type, pwm; + int ret; + + if (value == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "param error. fan index: %u, motor index: %u\n", + fan_index, motor_index); + return -DFD_RV_INVALID_VALUE; + } + + /* Get the fan type */ + ret = dfd_get_fan_type(fan_index, &fan_type, &fan_sub_type); + if (ret < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "fan get type error, rv: %d\n", ret); + return -EIO; + } + + /* Get current PWM */ + ret = dfd_get_fan_pwm(fan_index, &pwm); + if (ret < 0) { + return ret; + } + + /* Gets the rated speed corresponding to the current PWM */ + key1 = DFD_GET_FAN_THRESHOLD_KEY1((pwm / 10 + FAN_SPEED_TARGET_0), WB_MAIN_DEV_FAN); + key2 = DFD_GET_FAN_THRESHOLD_KEY2(fan_type, motor_index); + key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_THRESHOLD, key1, key2); + p_fan_speed_target = dfd_ko_cfg_get_item(key); + if (p_fan_speed_target == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "get fan%u motor%u speed target failed, key_name: %s\n", + fan_index, motor_index, key_to_name(DFD_CFG_ITEM_FAN_THRESHOLD)); + return -DFD_RV_DEV_NOTSUPPORT; + } + *value = *p_fan_speed_target; + DFD_FAN_DEBUG(DBG_VERBOSE, "get fan%u motor%u speed target ok, key_name: %s, value: %d\n", + fan_index, motor_index, key_to_name(DFD_CFG_ITEM_FAN_THRESHOLD), *value); + return DFD_RV_OK; +} + +/** + * dfd_get_fan_motor_speed_target_str - Obtain the standard fan speed + * @fan_index: Number of the fan, starting from 1 + * @motor_index: Motor number, starting with 1 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success :0 + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fan_motor_speed_target_str(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count) +{ + int ret, value; + + if (buf == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "buf is NULL, fan index: %u, motor index: %u\n", + fan_index, motor_index); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DFD_FAN_DEBUG(DBG_ERROR, "buf size error, count: %lu, fan index: %u, motor index: %u\n", + count, fan_index, motor_index); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear(buf, count); + ret = dfd_get_fan_speed_target(fan_index, motor_index, &value); + if (ret < 0) { + return ret; + } + return (ssize_t)snprintf(buf, count, "%d\n", value); +} + +/** + * dfd_get_fan_motor_speed_tolerance - Obtain the fan speed tolerance + * @fan_index + * @motor_index + * @value Speed tolerance + */ +static int dfd_get_fan_motor_speed_tolerance(unsigned int fan_index, unsigned int motor_index, int *value) +{ + uint64_t key; + int *p_fan_speed_tolerance; + int target, ret; + int key1, key2, fan_type, fan_sub_type; + + if (value == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "param error. fan index: %u, motor index: %u.\n", + fan_index, motor_index); + return -DFD_RV_INVALID_VALUE; + } + + /* Get the fan type */ + ret = dfd_get_fan_type(fan_index, &fan_type, &fan_sub_type); + if (ret < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "fan get type error, ret: %d\n", ret); + return -EIO; + } + + /* Obtain the error rate of the fan */ + key1 = DFD_GET_FAN_THRESHOLD_KEY1(FAN_SPEED_TOLERANCE, WB_MAIN_DEV_FAN); + key2 = DFD_GET_FAN_THRESHOLD_KEY2(fan_type, motor_index); + key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_THRESHOLD, key1, key2); + p_fan_speed_tolerance = dfd_ko_cfg_get_item(key); + if (p_fan_speed_tolerance == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "get fan%u motor%u speed tolerance failed, key_name: %s\n", + fan_index, motor_index, key_to_name(DFD_CFG_ITEM_FAN_THRESHOLD)); + return -DFD_RV_DEV_NOTSUPPORT; + } + + /* Obtain the fan speed target */ + ret = dfd_get_fan_speed_target(fan_index, motor_index, &target); + if (ret < 0) { + return ret; + } + + /* error rpm = Rated speed corresponding to the current pwm * Fan error ratio / 100 */ + *value = target * *p_fan_speed_tolerance / 100; + + DFD_FAN_DEBUG(DBG_VERBOSE, "get fan%u motor%u speed tolerance ok, key: %s, tolerance rate: %d, value: %d\n", + fan_index, motor_index, key_to_name(DFD_CFG_ITEM_FAN_THRESHOLD), *p_fan_speed_tolerance, *value); + return DFD_RV_OK; +} + +/** + * dfd_get_fan_motor_speed_tolerance_str - Obtain the fan speed tolerance + * @fan_index: Number of the fan, starting from 1 + * @motor_index: Motor number, starting with 1 + * @buf: Receive buf + * @count: Duct type receives buf length + * return: Success :0 + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fan_motor_speed_tolerance_str(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count) +{ + int ret, value; + + if (buf == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "buf is NULL, fan index: %u, motor index: %u\n", + fan_index, motor_index); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DFD_FAN_DEBUG(DBG_ERROR, "buf size error, count: %lu, fan index: %u, motor index: %u\n", + count, fan_index, motor_index); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear(buf, count); + ret = dfd_get_fan_motor_speed_tolerance(fan_index, motor_index, &value); + if (ret < 0) { + return ret; + } + return (ssize_t)snprintf(buf, count, "%d\n", value); +} + +/** + * dfd_get_fan_direction - Obtain the fan air duct type + * @fan_index: The fan offset starts from 1 + * @value 0:F2B, 1:B2F + * @returns: 0 success, negative value: failed + */ +static int dfd_get_fan_direction(unsigned int fan_index, int *value) +{ + uint64_t key; + int *p_fan_dirction; + int fan_type, fan_sub_type; + int rv; + + if (value == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "param error, fan index: %u\n", fan_index); + return -DFD_RV_INVALID_VALUE; + } + + /* Get the fan type */ + rv = dfd_get_fan_type(fan_index, &fan_type, &fan_sub_type); + if (rv < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "fan get type error, rv: %d\n", rv); + return -EIO; + } + + /* Obtain the fan direction based on the fan type and subtype */ + key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_DIRECTION, fan_type, fan_sub_type); + p_fan_dirction = dfd_ko_cfg_get_item(key); + if (p_fan_dirction == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "get fan%u direction failed, key_name: %s\n", + fan_index, key_to_name(DFD_CFG_ITEM_FAN_DIRECTION)); + return -DFD_RV_DEV_NOTSUPPORT; + } + *value = *p_fan_dirction; + DFD_FAN_DEBUG(DBG_VERBOSE, "get fan%u direction success, key_name: %s, value: %d\n", + fan_index, key_to_name(DFD_CFG_ITEM_FAN_DIRECTION), *value); + return DFD_RV_OK; +} + +/** + * dfd_get_fan_direction_str - Obtain the fan air duct type + * @fan_index:The fan offset starts from 1 + * @buf :Duct type receives buf + * @count :Duct type receives buf length + * @returns: Succeeded: Air duct type String length + * Failure: negative value + */ +ssize_t dfd_get_fan_direction_str(unsigned int fan_index, char *buf, size_t count) +{ + int ret, value; + + if (buf == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "param error, buf is NULL, fan index: %u.\n", fan_index); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DFD_FAN_DEBUG(DBG_ERROR, "param error, buf is NULL, fan index: %u.\n", fan_index); + return -DFD_RV_INVALID_VALUE; + } + + ret = dfd_get_fan_direction(fan_index, &value); + if (ret < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "get fan direction string failed, ret: %d, fan_index: %u\n", + ret, fan_index); + return ret; + } + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%d\n", value); +} + +/** + * dfd_get_fan_motor_speed_max - Obtain the maximum fan speed + * @fan_index + * @motor_index + * @value Maximum fan speed + * @returns: 0 success, negative value: failed + */ +static int dfd_get_fan_motor_speed_max(unsigned int fan_index, unsigned int motor_index, int *value) +{ + uint64_t key; + int *p_fan_speed_max; + int key1, key2, fan_type, fan_sub_type; + int rv; + + if (value == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "param error, fan index: %u, motor index: %u\n", + fan_index, motor_index); + return -DFD_RV_INVALID_VALUE; + } + + /* Get the fan type */ + rv = dfd_get_fan_type(fan_index, &fan_type, &fan_sub_type); + if (rv < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "fan get type error, rv: %d\n", rv); + return -EIO; + } + + key1 = DFD_GET_FAN_THRESHOLD_KEY1(FAN_SPEED_MAX, WB_MAIN_DEV_FAN); + key2 = DFD_GET_FAN_THRESHOLD_KEY2(fan_type, motor_index); + key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_THRESHOLD, key1, key2); + p_fan_speed_max = dfd_ko_cfg_get_item(key); + if (p_fan_speed_max == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "get fan%u motor%u speed max failed, key_name: %s\n", + fan_index, motor_index, key_to_name(DFD_CFG_ITEM_FAN_THRESHOLD)); + return -DFD_RV_DEV_NOTSUPPORT; + } + *value = *p_fan_speed_max; + DFD_FAN_DEBUG(DBG_VERBOSE, "get fan%u motor%u speed max success, key_name: %s, value: %d\n", + fan_index, motor_index, key_to_name(DFD_CFG_ITEM_FAN_THRESHOLD), *value); + return DFD_RV_OK; +} + +/** + * dfd_get_fan_motor_speed_max_str - Obtain the standard fan speed + * @fan_index: Number of the fan, starting from 1 + * @motor_index: Motor number, starting with 1 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success :0 + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fan_motor_speed_max_str(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count) +{ + int ret, value; + + if (buf == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "buf is NULL, fan index: %u, motor index: %u\n", + fan_index, motor_index); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DFD_FAN_DEBUG(DBG_ERROR, "buf size error, count: %lu, fan index: %u, motor index: %u\n", + count, fan_index, motor_index); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear(buf, count); + ret = dfd_get_fan_motor_speed_max(fan_index, motor_index, &value); + if (ret < 0) { + return ret; + } + return (ssize_t)snprintf(buf, count, "%d\n", value); +} + +/** + * dfd_get_fan_motor_speed_min - Obtain the minimum fan speed + * @fan_index + * @motor_index + * @value Minimum fan speed + * @returns: 0 success, negative value: failed + */ +static int dfd_get_fan_motor_speed_min(unsigned int fan_index, unsigned int motor_index, int *value) +{ + uint64_t key; + int *p_fan_speed_min; + int key1, key2, fan_type, fan_sub_type; + int rv; + + if (value == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "param error. fan index: %u, motor index: %u\n", + fan_index, motor_index); + return -DFD_RV_INVALID_VALUE; + } + + /* Get the fan type */ + rv = dfd_get_fan_type(fan_index, &fan_type, &fan_sub_type); + if (rv < 0) { + DFD_FAN_DEBUG(DBG_ERROR, "fan get type error, rv: %d\n", rv); + return -EIO; + } + + key1 = DFD_GET_FAN_THRESHOLD_KEY1(FAN_SPEED_MIN, WB_MAIN_DEV_FAN); + key2 = DFD_GET_FAN_THRESHOLD_KEY2(fan_type, motor_index); + key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_THRESHOLD, key1, key2); + p_fan_speed_min = dfd_ko_cfg_get_item(key); + if (p_fan_speed_min == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "get fan%u motor%u speed min failed, key_name: %s\n", + fan_index, motor_index, key_to_name(DFD_CFG_ITEM_FAN_THRESHOLD)); + return -DFD_RV_DEV_NOTSUPPORT; + } + *value = *p_fan_speed_min; + DFD_FAN_DEBUG(DBG_VERBOSE, "get fan%u motor%u speed min success, key_name: %s, value: %d\n", + fan_index, motor_index, key_to_name(DFD_CFG_ITEM_FAN_THRESHOLD), *value); + return DFD_RV_OK; +} + +/** + * dfd_get_fan_motor_speed_min_str - Obtain the standard fan speed + * @fan_index: Number of the fan, starting from 1 + * @motor_index: Motor number, starting with 1 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success :0 + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fan_motor_speed_min_str(unsigned int fan_index, unsigned int motor_index, + char *buf, size_t count) +{ + int ret, value; + + if (buf == NULL) { + DFD_FAN_DEBUG(DBG_ERROR, "buf is NULL, fan index: %u, motor index: %u\n", + fan_index, motor_index); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DFD_FAN_DEBUG(DBG_ERROR, "buf size error, count: %lu, fan index: %u, motor index: %u\n", + count, fan_index, motor_index); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear(buf, count); + ret = dfd_get_fan_motor_speed_min(fan_index, motor_index, &value); + if (ret < 0) { + return ret; + } + return (ssize_t)snprintf(buf, count, "%d\n", value); +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_fpga_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_fpga_driver.c new file mode 100644 index 000000000000..e5c326df0eb0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_fpga_driver.c @@ -0,0 +1,341 @@ +/* + * An wb_fpga_driver driver for fpga devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#include "wb_module.h" +#include "dfd_cfg.h" +#include "dfd_cfg_adapter.h" +#include "dfd_cfg_info.h" + +#define FPGA_REG_WIDTH_MAX (4) + +int g_dfd_fpga_dbg_level = 0; +module_param(g_dfd_fpga_dbg_level, int, S_IRUGO | S_IWUSR); + +/** + * dfd_get_fpga_name - Get the FPGA name + * @main_dev_id: Motherboard :0 Subcard :5 + * @index:FPGA number, starting from 1 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fpga_name(uint8_t main_dev_id, unsigned int fpga_index, char *buf, size_t count) +{ + uint64_t key; + char *fpga_name; + + if (buf == NULL) { + DBG_FPGA_DEBUG(DBG_ERROR, "param error, buf is NULL. main_dev_id: %u, fpga index: %u\n", + main_dev_id, fpga_index); + return -DFD_RV_INVALID_VALUE; + } + + if (count <= 0) { + DBG_FPGA_DEBUG(DBG_ERROR, "buf size error, count: %lu, main_dev_id: %u, fpga index: %u\n", + count, main_dev_id, fpga_index); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear(buf, count); + key = DFD_CFG_KEY(DFD_CFG_ITEM_FPGA_NAME, main_dev_id, fpga_index); + fpga_name = dfd_ko_cfg_get_item(key); + if (fpga_name == NULL) { + DBG_FPGA_DEBUG(DBG_ERROR, "main_dev_id: %u, fpga%u name config error, key_name: %s\n", + main_dev_id, fpga_index, key_to_name(DFD_CFG_ITEM_FPGA_NAME)); + return -DFD_RV_DEV_NOTSUPPORT; + } + + DBG_FPGA_DEBUG(DBG_VERBOSE, "%s\n", fpga_name); + snprintf(buf, count, "%s\n", fpga_name); + return strlen(buf); +} + +static ssize_t dfd_get_fpga_model(uint8_t main_dev_id, unsigned int fpga_index, char *buf, size_t count) +{ + uint64_t key; + int ret, fpga_model_val; + char *fpga_type; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_FPGA_MODEL_REG, main_dev_id, fpga_index); + ret = dfd_info_get_int(key, &fpga_model_val, NULL); + if (ret < 0) { + DBG_FPGA_DEBUG(DBG_ERROR, "get main_dev_id: %u, fpga%u model failed, key_name: %s, ret: %d\n", + main_dev_id, fpga_index, key_to_name(DFD_CFG_ITEM_FPGA_MODEL_REG), ret); + return ret; + } + + key = DFD_CFG_KEY(DFD_CFG_ITEM_FPGA_MODEL_DECODE, fpga_model_val, 0); + fpga_type = dfd_ko_cfg_get_item(key); + if (fpga_type == NULL) { + DBG_FPGA_DEBUG(DBG_ERROR, "main_dev_id: %u, fpga%u decode fpga model val 0x%08x failed\n", + main_dev_id, fpga_index, fpga_model_val); + return -DFD_RV_DEV_NOTSUPPORT; + } + + DBG_FPGA_DEBUG(DBG_VERBOSE, + "main_dev_id: %u, fpga%u decode fpga model success, origin value: 0x%08x decode value: %s\n", + main_dev_id, fpga_index, fpga_model_val, fpga_type); + snprintf(buf, count, "%s\n", fpga_type); + return strlen(buf); +} + +/** + * dfd_get_fpga_type - Get FPGA model + * @main_dev_id: Motherboard :0 Subcard :5 + * @index:FPGA number, starting from 1 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fpga_type(uint8_t main_dev_id, unsigned int fpga_index, char *buf, size_t count) +{ + uint64_t key; + char *fpga_type; + ssize_t ret; + + if (buf == NULL) { + DBG_FPGA_DEBUG(DBG_ERROR, "param error, buf is NULL, main_dev_id: %u, fpga index: %u\n", + main_dev_id, fpga_index); + return -DFD_RV_INVALID_VALUE; + } + + if (count <= 0) { + DBG_FPGA_DEBUG(DBG_ERROR, "buf size error, count: %lu, main_dev_id: %u, fpga index: %u\n", + count, main_dev_id, fpga_index); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear(buf, count); + key = DFD_CFG_KEY(DFD_CFG_ITEM_FPGA_TYPE, main_dev_id, fpga_index); + fpga_type = dfd_ko_cfg_get_item(key); + if (fpga_type == NULL) { + DBG_FPGA_DEBUG(DBG_VERBOSE, + "main_dev_id: %u, fpga%u type config is NULL, try to get fpga type from fpga model\n", + main_dev_id, fpga_index); + /* Unconfigured fpga_type Obtain the device model from fpga_model */ + ret = dfd_get_fpga_model(main_dev_id, fpga_index, buf, count); + return ret; + } + + DBG_FPGA_DEBUG(DBG_VERBOSE, "%s\n", fpga_type); + snprintf(buf, count, "%s\n", fpga_type); + return strlen(buf); +} + +/** + * dfd_get_fpga_fw_version - Obtain the FPGA firmware version + * @main_dev_id: Motherboard :0 Subcard :5 + * @index:FPGA number, starting from 1 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fpga_fw_version(uint8_t main_dev_id, unsigned int fpga_index, char *buf, size_t count) +{ + uint64_t key; + int rv; + uint32_t value; + + if (buf == NULL) { + DBG_FPGA_DEBUG(DBG_ERROR, "param error, buf is NULL, main_dev_id: %u, fpga index: %u\n", + main_dev_id, fpga_index); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DBG_FPGA_DEBUG(DBG_ERROR, "buf size error, count: %lu, main_dev_id: %u, fpga index: %u\n", + count, main_dev_id, fpga_index); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear(buf, count); + key = DFD_CFG_KEY(DFD_CFG_ITEM_FPGA_VERSION, main_dev_id, fpga_index); + rv = dfd_info_get_int(key, &value, NULL); + if (rv < 0) { + DBG_FPGA_DEBUG(DBG_ERROR, "main_dev_id: %u, fpga%u fw config error, key_name: %s, ret: %d\n", + main_dev_id, fpga_index, key_to_name(DFD_CFG_ITEM_FPGA_VERSION), rv); + return rv; + } + + DBG_FPGA_DEBUG(DBG_VERBOSE, "main_dev_id: %u, fpga%u firmware version: %x\n", + main_dev_id, fpga_index, value); + snprintf(buf, count, "0x%08x\n", value); + return strlen(buf); +} + +/** + * dfd_get_fpga_hw_version - Obtain the hardware version of the FPGA + * @main_dev_id: Motherboard :0 Subcard :5 + * @index: FPGA number, starting from 1 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fpga_hw_version(uint8_t main_dev_id, unsigned int fpga_index, char *buf, size_t count) +{ + + if (buf == NULL) { + DBG_FPGA_DEBUG(DBG_ERROR, "param error, buf is NULL, main_dev_id: %u, fpga index: %u\n", + main_dev_id, fpga_index); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DBG_FPGA_DEBUG(DBG_ERROR, "buf size error, count: %lu, main_dev_id: %u, fpga index: %u\n", + count, main_dev_id, fpga_index); + return -DFD_RV_INVALID_VALUE; + } + DBG_FPGA_DEBUG(DBG_VERBOSE, "main_dev_id: %u, fpga%u hardware version not support\n", + main_dev_id, fpga_index); + return -DFD_RV_DEV_NOTSUPPORT; +} + +static int value_convert_to_buf(unsigned int value, uint8_t *buf, int len, int pola) +{ + int i; + + if ((pola != INFO_POLA_POSI) && (pola != INFO_POLA_NEGA)) { + DBG_FPGA_DEBUG(DBG_ERROR, "unsupport pola mode: %d\n", pola); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear(buf, len); + if (pola == INFO_POLA_POSI) { /* Big-end mode */ + for (i = 0; i < len; i++) { + buf[i] = (value >> ((len - i - 1) * 8)) & 0xff; + } + } else { /* Small terminal mode */ + for (i = 0; i < len; i++) { + buf[i] = (value >> (i * 8)) & 0xff; + } + } + return DFD_RV_OK; +} + +/** + * dfd_set_fpga_testreg - Sets the value of the FPGA test register + * @main_dev_id: Motherboard :0 Subcard :5 + * @fpga_index: FPGA number, starting from 1 + * @value: Writes the value of the test register + * return: Success :0 + * : Failed: A negative value is returned + */ +int dfd_set_fpga_testreg(uint8_t main_dev_id, unsigned int fpga_index, unsigned int value) +{ + uint64_t key; + int ret; + uint8_t wr_buf[FPGA_REG_WIDTH_MAX]; + info_ctrl_t *info_ctrl; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_FPGA_TEST_REG, main_dev_id, fpga_index); + /* Get the configuration item read and write control variables */ + info_ctrl = dfd_ko_cfg_get_item(key); + if (info_ctrl == NULL) { + DBG_FPGA_DEBUG(DBG_VERBOSE, "main_dev_id: %u, fpga%u get info ctrl failed, key_name: %s\n", + main_dev_id, fpga_index, key_to_name(DFD_CFG_ITEM_FPGA_TEST_REG)); + return -DFD_RV_DEV_NOTSUPPORT; + } + if (info_ctrl->fpath == NULL) { + DBG_FPGA_DEBUG(DBG_VERBOSE, "main_dev_id: %u, fpga%u get fpath failed\n", main_dev_id, + fpga_index); + return -DFD_RV_INVALID_VALUE; + } + if (info_ctrl->len > FPGA_REG_WIDTH_MAX) { + DBG_FPGA_DEBUG(DBG_ERROR, "main_dev_id: %u, fpga%u info_ctrl len: %d, unsupport\n", + main_dev_id, fpga_index, info_ctrl->len); + return -DFD_RV_INVALID_VALUE; + } + + ret = value_convert_to_buf(value, wr_buf, FPGA_REG_WIDTH_MAX, info_ctrl->pola); + if (ret < 0) { + DBG_FPGA_DEBUG(DBG_ERROR, "value: 0x%x convert to buf failed, pola:%d, ret: %d\n", + value, info_ctrl->pola, ret); + return ret; + } + + DBG_FPGA_DEBUG(DBG_VERBOSE, "main_dev_id: %u, fpga%u fpath: %s, addr: 0x%x, len: %d value: 0x%x\n", + main_dev_id, fpga_index, info_ctrl->fpath, info_ctrl->addr, info_ctrl->len, value); + ret = dfd_ko_write_file(info_ctrl->fpath, info_ctrl->addr, wr_buf, info_ctrl->len); + if (ret < 0) { + DBG_FPGA_DEBUG(DBG_ERROR, "set fpga test reg failed, ret: %d", ret); + return ret; + } + return DFD_RV_OK; +} + +/** + * dfd_get_fpga_testreg - Read the FPGA test register value + * @main_dev_id: Motherboard :0 Subcard :5 + * @fpga_index: FPGA number, starting from 1 + * @value: Read the test register value + * return: Success :0 + * : Failed: A negative value is returned + */ +int dfd_get_fpga_testreg(uint8_t main_dev_id, unsigned int fpga_index, int *value) +{ + uint64_t key; + int ret; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_FPGA_TEST_REG, main_dev_id, fpga_index); + ret = dfd_info_get_int(key, value, NULL); + if (ret < 0) { + DBG_FPGA_DEBUG(DBG_ERROR, "main_dev_id: %u, get fpga%u test reg error, key_name: %s, ret: %d\n", + main_dev_id, fpga_index, key_to_name(DFD_CFG_ITEM_FPGA_TEST_REG), ret); + return ret; + } + return DFD_RV_OK; +} + +/** + * dfd_get_fpga_testreg_str - Read the FPGA test register value + * @main_dev_id: Motherboard :0 Subcard :5 + * @fpga_index: FPGA number, starting from 1 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_fpga_testreg_str(uint8_t main_dev_id, unsigned int fpga_index, + char *buf, size_t count) +{ + int ret, value; + + if (buf == NULL) { + DBG_FPGA_DEBUG(DBG_ERROR, "param error, buf is NULL, main_dev_id: %u, fpga index: %u\n", + main_dev_id, fpga_index); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DBG_FPGA_DEBUG(DBG_ERROR, "buf size error, count: %lu, main_dev_id: %u, fpga index: %u\n", + count, main_dev_id, fpga_index); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear(buf, count); + ret = dfd_get_fpga_testreg(main_dev_id, fpga_index, &value); + if (ret < 0) { + return ret; + } + return (ssize_t)snprintf(buf, count, "0x%08x\n", value); +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_led_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_led_driver.c new file mode 100644 index 000000000000..c66c3150dd79 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_led_driver.c @@ -0,0 +1,133 @@ +/* + * An wb_led_driver driver for led devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#include "wb_module.h" +#include "dfd_cfg.h" +#include "dfd_cfg_info.h" +#include "dfd_cfg_adapter.h" + +int g_dfd_sysled_dbg_level = 0; +module_param(g_dfd_sysled_dbg_level, int, S_IRUGO | S_IWUSR); + +/** + * dfd_get_led_status_value - Get LED light status value + * @led_id See the wb_led_t definition + * @value 0: Off, 1: green, 2: yellow, 3: red, 4: blue, 5: green, 6: yellow, 7: red + * @returns: 0 success, negative value: failed + */ +static int dfd_get_led_status_value(uint16_t led_id, uint8_t led_index, int *value) +{ + uint64_t key; + int ori_value, ret; + int *p_decode_value; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_LED_STATUS, led_id, led_index); + ret = dfd_info_get_int(key, &ori_value, NULL); + if (ret < 0) { + DBG_SYSLED_DEBUG(DBG_ERROR, "get led status error, key: %s, ret: %d\n", + key_to_name(DFD_CFG_ITEM_LED_STATUS), ret); + return ret; + } + + key = DFD_CFG_KEY(DFD_CFG_ITEM_LED_STATUS_DECODE, led_id, ori_value); + p_decode_value = dfd_ko_cfg_get_item(key); + if (p_decode_value != NULL) { + DBG_SYSLED_DEBUG(DBG_VERBOSE, "led id: %u index: %u, ori_value: 0x%x, decode value :0x%x\n", + led_id, led_index, ori_value, *p_decode_value); + *value = *p_decode_value; + return DFD_RV_OK; + } + return -DFD_RV_INVALID_VALUE; +} + +/** + * dfd_get_led_status - Get LED light status + * @led_id: led lamp type + * @led_index: led light offset + * @buf: LED light status receives buf + * @count: Accept the buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_led_status(uint16_t led_id, uint8_t led_index, char *buf, size_t count) +{ + int ret, led_value; + + if (buf == NULL) { + DBG_SYSLED_DEBUG(DBG_ERROR, "param error, buf is NULL. led_id: %u, led_index: %u\n", + led_id, led_index); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DBG_SYSLED_DEBUG(DBG_ERROR, "buf size error, count: %lu, led_id: %u, led_index: %u\n", + count, led_id, led_index); + return -DFD_RV_INVALID_VALUE; + } + mem_clear(buf, count); + ret = dfd_get_led_status_value(led_id, led_index, &led_value); + if (ret < 0) { + DBG_SYSLED_DEBUG(DBG_ERROR, "get led status error, ret: %d, led_id: %u, led_index: %u\n", + ret, led_id, led_index); + return ret; + } + return (ssize_t)snprintf(buf, count, "%d\n", led_value); +} + +/** + * dfd_set_led_status - Set LED light status + * @led_id: led lamp type + * @led_index: led light offset + * @value: LED light status value + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_set_led_status(uint16_t led_id, uint8_t led_index, int value) +{ + uint64_t key; + int ret, led_value; + + if (value < 0 || value > 0xff) { + DBG_SYSLED_DEBUG(DBG_ERROR, "can not set led status value = %d.\n", value); + return -DFD_RV_INVALID_VALUE; + } + + DBG_SYSLED_DEBUG(DBG_VERBOSE, "set led id: %u index: %u, status[%d].\n", + led_id, led_index, value); + ret = dfd_ko_cfg_get_led_status_decode2_by_regval(value, led_id, &led_value); + if (ret < 0) { + DBG_SYSLED_DEBUG(DBG_ERROR, "get led status register error, ret: %d, led_id: %u, value: %d\n", + ret, led_id, value); + return ret; + } + + DBG_SYSLED_DEBUG(DBG_VERBOSE, "get led[%u] index[%u] status[%d] decode value[%d]\n", + led_id, led_index, value, led_value); + key = DFD_CFG_KEY(DFD_CFG_ITEM_LED_STATUS, led_id, led_index); + ret = dfd_info_set_int(key, led_value); + if (ret < 0) { + DBG_SYSLED_DEBUG(DBG_ERROR, "set led status error, key_name: %s, ret: %d\n", + key_to_name(DFD_CFG_ITEM_LED_STATUS), ret); + return ret; + } + + return DFD_RV_OK; +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_module.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_module.c new file mode 100644 index 000000000000..69610668a971 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_module.c @@ -0,0 +1,73 @@ +/* + * An wb_module driver for module devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#include "wb_module.h" +#include "dfd_cfg.h" + +int g_dfd_dbg_level = 0; /* Debug level */ +module_param(g_dfd_dbg_level, int, S_IRUGO | S_IWUSR); + +/** + * wb_dev_cfg_init - dfd module initialization + * + * @returns:<0 Failed, otherwise succeeded + */ +int32_t wb_dev_cfg_init(void) +{ + return dfd_dev_cfg_init(); +} + +/** + * wb_dev_cfg_exit - dfd module exit + * + * @returns: void + */ + +void wb_dev_cfg_exit(void) +{ + dfd_dev_cfg_exit(); + return; +} + +/** + * dfd_get_dev_number - Get the number of devices + * @main_dev_id:Master device number + * @minor_dev_id:Secondary device number + * @returns: <0 failed, otherwise number of devices is returned + */ +int dfd_get_dev_number(unsigned int main_dev_id, unsigned int minor_dev_id) +{ + uint64_t key; + int dev_num; + int *p_dev_num; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_DEV_NUM, main_dev_id, minor_dev_id); + p_dev_num = dfd_ko_cfg_get_item(key); + if (p_dev_num == NULL) { + DBG_DEBUG(DBG_ERROR, "get device number failed, key_name:%s\n", + key_to_name(DFD_CFG_ITEM_DEV_NUM)); + return -DFD_RV_DEV_NOTSUPPORT; + } + dev_num = *p_dev_num; + DBG_DEBUG(DBG_VERBOSE, "get device number ok, number:%d\n",dev_num); + return dev_num; +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_psu_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_psu_driver.c new file mode 100644 index 000000000000..aad65d282921 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_psu_driver.c @@ -0,0 +1,950 @@ +/* + * An wb_psu_driver driver for psu devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include + +#include "wb_module.h" +#include "dfd_cfg.h" +#include "dfd_cfg_adapter.h" +#include "dfd_cfg_info.h" +#include "dfd_frueeprom.h" + +#define PSU_SIZE (256) +#define WB_GET_PSU_PMBUS_BUS(addr) (((addr) >> 24) & 0xff) +#define WB_GET_PSU_PMBUS_ADDR(addr) (((addr) >> 8) & 0xffff) +#define WB_GET_PSU_PMBUS_OFFSET(addr) ((addr) & 0xff) +#define DFD_PSU_FRU_MODE_E2_STRING "eeprom" +#define DFD_PSU_FRU_MODE_PMBUS_STRING "pmbus" + +#define PSU_PMBUS_POWER_GOOD BIT(11) + +typedef enum dfd_psu_pmbus_type_e { + DFD_PSU_PMBUS_TYPE_AC = 1, + DFD_PSU_PMBUS_TYPE_DC = 2, +} dfd_psu_pmbus_type_t; + +typedef enum dfd_psu_sysfs_type_e { + DFD_PSU_SYSFS_TYPE_DC = 0, + DFD_PSU_SYSFS_TYPE_AC = 1, +} dfd_psu_sysfs_type_t; + +typedef enum dfd_psu_status_e { + DFD_PSU_PRESENT_STATUS = 0, + DFD_PSU_OUTPUT_STATUS = 1, + DFD_PSU_ALERT_STATUS = 2, + DFD_PSU_INPUT_STATUS = 3, +} dfd_psu_status_t; + +typedef enum dfd_psu_alarm_e { + DFD_PSU_NOT_OK = 0, + DFD_PSU_OK = 1, +} dfd_psu_alarm_t; + +enum knos_alarm { + PSU_TERMAL_ERROR = 0x1, + PSU_FAN_ERROR = 0x2, + PSU_VOL_ERROR = 0x4, +}; + +typedef enum psu_fru_mode_e { + PSU_FRU_MODE_E2, /* eeprom */ + PSU_FRU_MODE_PMBUS, /*pmbus*/ +} fan_eeprom_mode_t; + + +/* PMBUS STATUS WORD decode */ +#define PSU_STATUS_WORD_CML (1 << 1) +#define PSU_STATUS_WORD_TEMPERATURE (1 << 2) +#define PSU_STATUS_WORD_VIN_UV (1 << 3) +#define PSU_STATUS_WORD_IOUT_OC (1 << 4) +#define PSU_STATUS_WORD_VOUT_OV (1 << 5) +#define PSU_STATUS_WORD_OFF (1 << 6) +#define PSU_STATUS_WORD_BUSY (1 << 7) +#define PSU_STATUS_WORD_FANS (1 << 10) +#define PSU_STATUS_WORD_POWER_GOOD (1 << 11) +#define PSU_STATUS_WORD_INPUT (1 << 13) +#define PSU_STATUS_WORD_IOUT (1 << 14) +#define PSU_STATUS_WORD_VOUT (1 << 15) + +#define PSU_VOLTAGE_ERR_OFFSET (PSU_STATUS_WORD_VOUT | PSU_STATUS_WORD_IOUT | \ + PSU_STATUS_WORD_INPUT | PSU_STATUS_WORD_POWER_GOOD| \ + PSU_STATUS_WORD_OFF | PSU_STATUS_WORD_VOUT_OV| \ + PSU_STATUS_WORD_IOUT_OC | PSU_STATUS_WORD_VIN_UV) + +int g_dfd_psu_dbg_level = 0; +module_param(g_dfd_psu_dbg_level, int, S_IRUGO | S_IWUSR); + +static int dfd_get_psu_fru_mode(void) +{ + uint64_t key; + int mode; + char *name; + + /* string Type configuration item */ + key = DFD_CFG_KEY(DFD_CFG_ITEM_PSU_FRU_MODE, 0, 0); + name = dfd_ko_cfg_get_item(key); + if (name == NULL) { + /* The default EEPROM format is returned */ + DFD_PSU_DEBUG(DBG_VERBOSE, "get psu fru mode config fail, key=%s, use default eeprom mode\n", + key_to_name(DFD_CFG_ITEM_PSU_FRU_MODE)); + return PSU_FRU_MODE_E2; + } + + DFD_PSU_DEBUG(DBG_VERBOSE, "psu fru mode %s.\n", name); + if (!strncmp(name, DFD_PSU_FRU_MODE_E2_STRING, strlen(DFD_PSU_FRU_MODE_E2_STRING))) { + mode = PSU_FRU_MODE_E2; + } else if (!strncmp(name, DFD_PSU_FRU_MODE_PMBUS_STRING, strlen(DFD_PSU_FRU_MODE_PMBUS_STRING))) { + mode = PSU_FRU_MODE_PMBUS; + } else { + /* The default EEPROM format is returned */ + mode = PSU_FRU_MODE_E2; + } + + DFD_FAN_DEBUG(DBG_VERBOSE, "psu fru mode %d.\n", mode); + return mode; +} + +static char *dfd_get_psu_sysfs_name(void) +{ + uint64_t key; + char *sysfs_name; + + /* string Type configuration item */ + key = DFD_CFG_KEY(DFD_CFG_ITEM_PSU_SYSFS_NAME, 0, 0); + sysfs_name = dfd_ko_cfg_get_item(key); + if (sysfs_name == NULL) { + DFD_PSU_DEBUG(DBG_VERBOSE, "key_name=%s, sysfs_name is NULL, use default way.\n", + key_to_name(DFD_CFG_ITEM_PSU_SYSFS_NAME)); + } else { + DFD_PSU_DEBUG(DBG_VERBOSE, "sysfs_name: %s.\n", sysfs_name); + } + return sysfs_name; +} + +static void dfd_psu_del_no_print_string(char *buf) +{ + int i, len; + + len = strlen(buf); + /* Culling noncharacter */ + for (i = 0; i < len; i++) { + if ((buf[i] < 0x21) || (buf[i] > 0x7E)) { + buf[i] = '\0'; + break; + } + } + return; +} + +/** + * dfd_get_psu_present_status - Obtain the power supply status + * @index: Number of the power supply, starting from 1 + * return: 0:Not in the position + * 1:position + * : Negative value - Read failed + */ +int dfd_get_psu_present_status(unsigned int psu_index) +{ + int present_key, present_status; + int ret; + + /* Get presence status */ + present_key = DFD_CFG_KEY(DFD_CFG_ITEM_PSU_STATUS, psu_index, DFD_PSU_PRESENT_STATUS); + ret = dfd_info_get_int(present_key, &present_status, NULL); + if (ret < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "dfd_get_psu_status error. psu_index: %u, ret: %d\n", + psu_index, ret); + return ret; + } + + return present_status; +} + +/** + * dfd_get_psu_present_status_str - Obtain power status + * @index: Number of the power supply, starting from 1 + * return: Success: Length of the status string + * : Gets the value on the pmbus register of the power supply + */ +ssize_t dfd_get_psu_present_status_str(unsigned int psu_index, char *buf, size_t count) +{ + int ret; + if (buf == NULL) { + DFD_PSU_DEBUG(DBG_ERROR, "params error.psu_index: %u.",psu_index); + return -EINVAL; + } + if (count <= 0) { + DFD_PSU_DEBUG(DBG_ERROR, "buf size error, count: %lu, psu index: %u\n", + count, psu_index); + return -EINVAL; + } + + ret = dfd_get_psu_present_status(psu_index); + if (ret < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "get psu status error, ret: %d, psu_index: %u\n", ret, psu_index); + return ret; + } + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%d\n", ret); +} + +ssize_t dfd_get_psu_pmbus_status(unsigned int psu_index, char *buf, size_t count) +{ + int key; + int ret; + + /* PMBUS STATUS WORD (0x79) */ + key = DFD_CFG_KEY(DFD_CFG_ITEM_HWMON_PSU, psu_index, PSU_HW_STATUS); + ret = dfd_info_get_sensor(key, buf, count, NULL); + + if (ret < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "get psu%u pmbus status info failed, key: 0x%08x, ret: %d\n", + psu_index, DFD_CFG_ITEM_HWMON_PSU, ret); + } else { + DFD_PSU_DEBUG(DBG_VERBOSE, "psu_index: %u, pmbus_data = %s \n", psu_index, buf); + } + return ret; +} + +/** + * dfd_get_psu_hw_status_str - get psu status str + * @index: Number of the power supply, starting from 1 + * return: Success: Length of the status string + * : Gets the value on the pmbus register of the power supply + */ +ssize_t dfd_get_psu_hw_status_str(unsigned int psu_index, char *buf, size_t count) +{ + int ret; + int status_word; + int status; + int output_key, output_status; + int alert_key, alert_status; + + if (buf == NULL) { + DFD_PSU_DEBUG(DBG_ERROR, "params error, psu_index: %u", psu_index); + return -EINVAL; + } + if (count <= 0) { + DFD_PSU_DEBUG(DBG_ERROR, "buf size error, count: %lu, psu index: %u\n", + count, psu_index); + return -EINVAL; + } + + /* get psu present status first */ + ret = dfd_get_psu_present_status(psu_index); + if (ret < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "get psu present status error, ret: %d, psu_index: %u\n", ret, psu_index); + return ret; + } + if (ret == PSU_STATUS_ABSENT) { + return (ssize_t)snprintf(buf, count, "%d\n", PSU_STATUS_ABSENT); + } + + /* get psu alert and power status from cpld */ + output_key = DFD_CFG_KEY(DFD_CFG_ITEM_PSU_STATUS, psu_index, DFD_PSU_OUTPUT_STATUS); + alert_key = DFD_CFG_KEY(DFD_CFG_ITEM_PSU_STATUS, psu_index, DFD_PSU_ALERT_STATUS); + ret = dfd_info_get_int(output_key, &output_status, NULL); + if (ret < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "get psu output_key error, ret: %d, psu_index: %u\n", + ret, psu_index); + return ret; + } + ret = dfd_info_get_int(alert_key, &alert_status, NULL); + if (ret < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "get psu alert_key error, ret: %d, psu_index: %u\n", + ret, psu_index); + return ret; + } + DFD_PSU_DEBUG(DBG_VERBOSE, "get psu %u alert: %u, output: %u.\n", psu_index, alert_status, output_status); + /* if cpld status not ok */ + if (!alert_status || !output_status) { + /* jduge psu status from psu pmbus 0x79 */ + ret = dfd_get_psu_pmbus_status(psu_index, buf, count); + if (ret < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "get psu pmbus status error, ret: %d, psu_index: %u\n", ret, psu_index); + return ret; + } else { + ret = kstrtoint(buf, 0, &status_word); + if (ret) { + DFD_PSU_DEBUG(DBG_ERROR, "invalid value: %s \n", buf); + return -EINVAL; + } + DFD_PSU_DEBUG(DBG_VERBOSE, "get psu %u statu reg value: %u.\n", psu_index, status_word); + status = (status_word & PSU_PMBUS_POWER_GOOD) ? PSU_STATUS_FAIL : PSU_STATUS_WARN; + } + } else { + status = PSU_STATUS_PRESENT; + } + + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%d\n", status); +} + +/** + * dfd_get_psu_status_pmbus_str - Gets the value on the pmbus register of the power supply + * @index: Number of the power supply, starting from 1 + * return: Success: Length of the status string + * : Negative value - Read failed + */ +ssize_t dfd_get_psu_status_pmbus_str(unsigned int psu_index, char *buf, size_t count) +{ + uint64_t key; + int ret; + int pmbus_data; + + if (buf == NULL) { + DFD_PSU_DEBUG(DBG_ERROR, "buf is NULL, psu index: %u\n", psu_index); + return -EINVAL; + } + if (count <= 0) { + DFD_PSU_DEBUG(DBG_ERROR, "buf size error, count: %lu, psu index: %u\n", count, psu_index); + return -EINVAL; + } + + /* Gets the status from the pmbus register of the power supply */ + key = DFD_CFG_KEY(DFD_CFG_ITEM_PSU_PMBUS_REG, psu_index, PSU_SENSOR_NONE); + ret = dfd_info_get_int(key, &pmbus_data, NULL); + if (ret < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "get psu%u pmbus status info failed, key_name: %s, ret: %d\n", + psu_index, key_to_name(DFD_CFG_ITEM_PSU_PMBUS_REG), ret); + return ret; + } + + DFD_PSU_DEBUG(DBG_VERBOSE, "psu_index: %u, pmbus_data = 0x%x \n", psu_index, pmbus_data); + + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%d\n", pmbus_data); +} + +/** + * dfd_get_psu_fan_speed_cal_str - Obtain the formula for calculating the speed of the power supply + * @index: Number of the power supply, starting from 1 + * return: Success: Length of the status string + * : Negative value - Read failed + */ +static int dfd_get_psu_fan_speed_cal_str(int power_type, char *psu_buf, int buf_len) +{ + uint64_t key; + char *speed_cal; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_FAN_SPEED_CAL, power_type, 0); + speed_cal = dfd_ko_cfg_get_item(key); + if (speed_cal == NULL) { + DFD_PSU_DEBUG(DBG_ERROR, "config error, get psu speed cal error, key_name: %s\n", + key_to_name(DFD_CFG_ITEM_FAN_SPEED_CAL)); + return -DFD_RV_DEV_NOTSUPPORT; + } + mem_clear(psu_buf, buf_len); + strlcpy(psu_buf, speed_cal, buf_len); + DFD_PSU_DEBUG(DBG_VERBOSE, "psu speed cal match ok, speed_cal: %s\n", psu_buf); + return DFD_RV_OK; +} + +/** + * dfd_get_psu_out_status_str - Obtain the output power status + * @index: Number of the power supply, starting from 1 + * return: Success: Length of the status string + * : Negative value - Read failed + */ +ssize_t dfd_get_psu_out_status_str(unsigned int psu_index, char *buf, size_t count) +{ + uint64_t key; + int ret; + int pmbus_data; + int output_status; + + if (buf == NULL) { + DFD_PSU_DEBUG(DBG_ERROR, "buf is NULL, psu index: %u\n", psu_index); + return -EINVAL; + } + if (count <= 0) { + DFD_PSU_DEBUG(DBG_ERROR, "buf size error, count: %lu, psu index: %u\n", count, psu_index); + return -EINVAL; + } + + /* Gets the status from the pmbus register of the power supply */ + key = DFD_CFG_KEY(DFD_CFG_ITEM_PSU_PMBUS_REG, psu_index, PSU_OUT_STATUS); + ret = dfd_info_get_int(key, &pmbus_data, NULL); + if (ret < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "get psu%u pmbus status info failed, key_name: %s, ret: %d\n", + psu_index, key_to_name(DFD_CFG_ITEM_PSU_PMBUS_REG), ret); + return ret; + } + + output_status = DFD_PSU_OK; + if (pmbus_data & (PSU_STATUS_WORD_INPUT | PSU_STATUS_WORD_OFF | PSU_STATUS_WORD_POWER_GOOD)) { + /* The judgment logic of no power is consistent with that of Baidu sysfs */ + output_status = DFD_PSU_NOT_OK; + } + DFD_PSU_DEBUG(DBG_VERBOSE, "psu_index: %u, pmbus_data = 0x%x \n", psu_index, pmbus_data); + + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%d\n", output_status); +} + +/** + * dfd_psu_product_name_decode - Power name conversion + * @power_type: Power supply type + * @psu_buf: Power name buffer + * @buf_len: psu_buf length + * return: Success :0 + * : Failed: A negative value is returned + */ +static int dfd_psu_product_name_decode(int power_type, char *psu_buf, int buf_len) +{ + uint64_t key; + char *p_decode_name; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_DECODE_POWER_NAME, power_type, 0); + p_decode_name = dfd_ko_cfg_get_item(key); + if (p_decode_name == NULL) { + DFD_PSU_DEBUG(DBG_ERROR, "config error, get psu decode name error, key_name: %s\n", + key_to_name(DFD_CFG_ITEM_DECODE_POWER_NAME)); + return -DFD_RV_DEV_NOTSUPPORT; + } + mem_clear(psu_buf, buf_len); + strlcpy(psu_buf, p_decode_name, buf_len); + DFD_PSU_DEBUG(DBG_VERBOSE, "psu name match ok, display psu name: %s\n", psu_buf); + return DFD_RV_OK; +} + +/** + * dfd_psu_fan_direction_decode - Power duct type conversion + * @power_type: Power supply type + * @psu_buf: Power name buffer + * @buf_len: psu_buf length + * return: Success :0 + * : Failed: A negative value is returned + */ +static int dfd_psu_fan_direction_decode(int power_type, char *psu_buf, int buf_len) +{ + uint64_t key; + char *p_decode_direction; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_DECODE_POWER_FAN_DIR, power_type, 0); + p_decode_direction = dfd_ko_cfg_get_item(key); + if (p_decode_direction == NULL) { + DFD_PSU_DEBUG(DBG_ERROR, "config error, get psu decode direction error, key_name: %s\n", + key_to_name(DFD_CFG_ITEM_DECODE_POWER_FAN_DIR)); + return -DFD_RV_DEV_NOTSUPPORT; + } + mem_clear(psu_buf, buf_len); + snprintf(psu_buf, buf_len, "%d", *p_decode_direction); + DFD_PSU_DEBUG(DBG_VERBOSE, "psu%u fan direction match ok, display psu direction: %s\n", + power_type, psu_buf); + return DFD_RV_OK; +} + +/** + * dfd_psu_max_output_power - Rated power of supply + * @power_type: Power supply type + * @psu_buf: Data buffer + * @buf_len: psu_buf length + * return: Success :0 + * : Failed: A negative value is returned + */ +static int dfd_psu_max_output_power(int power_type, char *psu_buf, int buf_len) +{ + uint64_t key; + int value; + int *p_power_max_output_power; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_POWER_RSUPPLY, power_type, 0); + p_power_max_output_power = dfd_ko_cfg_get_item(key); + if (p_power_max_output_power == NULL) { + DFD_PSU_DEBUG(DBG_ERROR, "config error, get psu input type error, key_name: %s\n", + key_to_name(DFD_CFG_ITEM_POWER_RSUPPLY)); + return -DFD_RV_DEV_NOTSUPPORT; + } + value = *p_power_max_output_power; + mem_clear(psu_buf, buf_len); + snprintf(psu_buf, buf_len, "%d", value); + DFD_PSU_DEBUG(DBG_VERBOSE, "psu name %s match max output power %d\n", psu_buf, value); + return DFD_RV_OK; +} + +static int dfd_get_psu_fru_pmbus(unsigned int psu_index, uint8_t cmd, char *buf, size_t buf_len) +{ + uint64_t key; + int rv, len; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_PSU_FRU_PMBUS, psu_index, cmd); + DFD_PSU_DEBUG(DBG_VERBOSE, "psu index: %d, cmd: %d, key_name: %s\n", + psu_index, cmd, key_to_name(DFD_CFG_ITEM_PSU_FRU_PMBUS)); + + rv = dfd_info_get_sensor(key, buf, buf_len, NULL); + if (rv < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "get psu fru info by pmbus failed, key_name: %s, rv: %d\n", + key_to_name(DFD_CFG_ITEM_PSU_FRU_PMBUS), rv); + } else { + len = strlen(buf); + if (len > 0 && buf[len - 1] == '\n') { + buf[len - 1] = '\0'; + } + DFD_PSU_DEBUG(DBG_VERBOSE, "get psu fru info by pmbus success, value: %s\n", buf); + } + return rv; +} + +static int dfd_get_psu_type(unsigned int psu_index, dfd_i2c_dev_t *i2c_dev, int *power_type, + const char *sysfs_name, int fru_mode) +{ + int rv; + char psu_buf[PSU_SIZE]; + + mem_clear(psu_buf, sizeof(psu_buf)); + if (fru_mode == PSU_FRU_MODE_PMBUS) { + rv = dfd_get_psu_fru_pmbus(psu_index, DFD_DEV_INFO_TYPE_PART_NUMBER, psu_buf, PSU_SIZE); + } else { + rv = dfd_get_fru_data(i2c_dev->bus, i2c_dev->addr, DFD_DEV_INFO_TYPE_PART_NUMBER, psu_buf, + PSU_SIZE, sysfs_name); + } + + if (rv < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "get psu type from eeprom read failed, rv: %d\n", rv); + return -DFD_RV_DEV_FAIL; + } + + DFD_PSU_DEBUG(DBG_VERBOSE, "%s\n", psu_buf); + dfd_psu_del_no_print_string(psu_buf); + + DFD_PSU_DEBUG(DBG_VERBOSE, "dfd_psu_product_name_decode get psu name %s\n", psu_buf); + rv = dfd_ko_cfg_get_power_type_by_name((char *)psu_buf, power_type); + if (rv < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "get power type by name[%s] fail, rv: %d\n", psu_buf, rv); + return -DFD_RV_NO_NODE; + } + + DFD_PSU_DEBUG(DBG_VERBOSE, "get psu%u return power_type[0x%x]\n", psu_index, *power_type); + return DFD_RV_OK; +} + +/** + * dfd_get_psu_info - Get Power Information + * @index: Number of the power supply, starting from 1 + * @cmd: Power supply information Type, power supply name :2, power supply serial number :3, power supply hardware version :5 + * @buf: Receive buf + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_psu_info(unsigned int psu_index, uint8_t cmd, char *buf, size_t count) +{ + uint64_t key; + int rv; + char psu_buf[PSU_SIZE]; + dfd_i2c_dev_t *i2c_dev; + int power_type; + int fru_mode; + const char *sysfs_name; + + if (buf == NULL) { + DFD_PSU_DEBUG(DBG_ERROR, "buf is NULL, psu index: %u, cmd: 0x%x\n", psu_index, cmd); + return -EINVAL; + } + if (count <= 0) { + DFD_PSU_DEBUG(DBG_ERROR, "buf size error, count: %lu, psu index: %u, cmd: 0x%x\n", + count, psu_index, cmd); + return -EINVAL; + } + + fru_mode = dfd_get_psu_fru_mode(); + mem_clear(buf, count); + mem_clear(psu_buf, PSU_SIZE); + if (fru_mode == PSU_FRU_MODE_E2) { + key = DFD_CFG_KEY(DFD_CFG_ITEM_OTHER_I2C_DEV, WB_MAIN_DEV_PSU, psu_index); + i2c_dev = dfd_ko_cfg_get_item(key); + if (i2c_dev == NULL) { + DFD_PSU_DEBUG(DBG_ERROR, "psu i2c dev config error, key_name: %s\n", + key_to_name(DFD_CFG_ITEM_OTHER_I2C_DEV)); + return -DFD_RV_DEV_NOTSUPPORT; + } + sysfs_name = dfd_get_psu_sysfs_name(); + } + + /* Power E2 product name conversion */ + if (cmd == DFD_DEV_INFO_TYPE_PART_NAME) { + rv = dfd_get_psu_type(psu_index, i2c_dev, &power_type, sysfs_name, fru_mode); + if (rv < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "psu get type error, rv: %d\n", rv); + return -EIO; + } + rv = dfd_psu_product_name_decode(power_type, psu_buf, PSU_SIZE); + if (rv < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "psu name decode error, power_type[0x%x] rv: %d\n", + power_type, rv); + return -EIO; + } + } else if (cmd == DFD_DEV_INFO_TYPE_FAN_DIRECTION) { + rv = dfd_get_psu_type(psu_index, i2c_dev, &power_type, sysfs_name, fru_mode); + if (rv < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "psu get type error, rv: %d\n", rv); + return -EIO; + } + rv = dfd_psu_fan_direction_decode(power_type, psu_buf, PSU_SIZE); + if (rv < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "psu input type decode error, power_type[0x%x] rv: %d\n", + power_type, rv); + return -EIO; + } + } else if (cmd == DFD_DEV_INFO_TYPE_MAX_OUTPUT_POWRER) { + rv = dfd_get_psu_type(psu_index, i2c_dev, &power_type, sysfs_name, fru_mode); + if (rv < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "psu get type error, rv:%d\n", rv); + return -EIO; + } + rv = dfd_psu_max_output_power(power_type, psu_buf, PSU_SIZE); + if (rv < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "psu max ouput power error, power_type[0x%x] rv: %d\n", + power_type, rv); + return -EIO; + } + } else if (cmd == DFD_DEV_INFO_TYPE_SPEED_CAL) { + rv = dfd_get_psu_type(psu_index, i2c_dev, &power_type, sysfs_name, fru_mode); + if (rv < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "psu get type error, rv:%d\n", rv); + return -EIO; + } + rv = dfd_get_psu_fan_speed_cal_str(power_type, psu_buf, PSU_SIZE); + if (rv < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "psu fan speed cal error, power_type[0x%x] rv: %d\n", + power_type, rv); + return -EIO; + } + } else { + if (fru_mode == PSU_FRU_MODE_PMBUS) { + rv = dfd_get_psu_fru_pmbus(psu_index, cmd, psu_buf, PSU_SIZE); + } else { + rv = dfd_get_fru_data(i2c_dev->bus, i2c_dev->addr, cmd, psu_buf, PSU_SIZE, sysfs_name); + } + if (rv < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "psu eeprom read failed, rv: %d\n", rv); + return -EIO; + } + } + + snprintf(buf, count, "%s\n", psu_buf); + return strlen(buf); +} + +/** + * dfd_get_psu_input_type - Obtain the power input type + * @index: Number of the power supply, starting from 1 + * @buf: Receive buf + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_psu_input_type(unsigned int psu_index, char *buf, size_t count) +{ + uint64_t key; + int ret; + int data; + + if (buf == NULL) { + DFD_PSU_DEBUG(DBG_ERROR, "buf is NULL, psu index: %u\n", psu_index); + return -EINVAL; + } + if (count <= 0) { + DFD_PSU_DEBUG(DBG_ERROR, "buf size error, count: %lu, psu index: %u\n", count, psu_index); + return -EINVAL; + } + + key = DFD_CFG_KEY(DFD_CFG_ITEM_PSU_PMBUS_REG, psu_index, PSU_IN_TYPE); + ret = dfd_info_get_int(key, &data, NULL); + if (ret < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "get psu%u pmbus status info failed, key_name: %s, ret: %d\n", + psu_index, key_to_name(DFD_CFG_ITEM_PSU_PMBUS_REG), ret); + return ret; + } + + DFD_PSU_DEBUG(DBG_VERBOSE, "psu_index: %u, pmbus_data = 0x%x \n", psu_index, data); + + if (data == DFD_PSU_PMBUS_TYPE_AC) { + return snprintf(buf, count, "%d\n", DFD_PSU_SYSFS_TYPE_AC); + } else if (data == DFD_PSU_PMBUS_TYPE_DC) { + return snprintf(buf, count, "%d\n", DFD_PSU_SYSFS_TYPE_DC); + } else { + DFD_PSU_DEBUG(DBG_WARN, "get psu%u input type data[%u] unknow, ret: %d\n", + psu_index, data, ret); + return -DFD_RV_DEV_NOTSUPPORT; + } + + DFD_PSU_DEBUG(DBG_ERROR, "get psu%u pmbus type data[%u] unknow, ret: %d\n", + psu_index, data, ret); + return -EIO; +} + +/** + * dfd_get_psu_in_status_str - Obtain the input power status + * @index: Number of the power supply, starting from 1 + * return: Success: Length of the status string + * : Negative value - Read failed + */ +ssize_t dfd_get_psu_in_status_str(unsigned int psu_index, char *buf, size_t count) +{ + uint64_t key; + int ret; + int pmbus_data; + int input_status; + + if (buf == NULL) { + DFD_PSU_DEBUG(DBG_ERROR, "buf is NULL, psu index: %u\n", psu_index); + return -EINVAL; + } + if (count <= 0) { + DFD_PSU_DEBUG(DBG_ERROR, "buf size error, count: %lu, psu index: %u\n", count, psu_index); + return -EINVAL; + } + + key = DFD_CFG_KEY(DFD_CFG_ITEM_PSU_PMBUS_REG, psu_index, PSU_IN_STATUS); + ret = dfd_info_get_int(key, &pmbus_data, NULL); + if (ret < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "get psu%u pmbus status info failed, key_name: %s, ret: %d\n", + psu_index, key_to_name(DFD_CFG_ITEM_PSU_PMBUS_REG), ret); + return ret; + } + + input_status = DFD_PSU_OK; + if (pmbus_data & PSU_STATUS_WORD_INPUT) { + /* no power judgment logic, according to the opinion only bit13 judgment */ + DFD_PSU_DEBUG(DBG_VERBOSE, "psu_index: %u, no power, pmbus_data = 0x%x \n", psu_index, pmbus_data); + input_status = DFD_PSU_NOT_OK; + } + DFD_PSU_DEBUG(DBG_VERBOSE, "psu_index: %u, pmbus_data = 0x%x \n", psu_index, pmbus_data); + + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%d\n", input_status); +} + +ssize_t dfd_get_psu_alarm_status(unsigned int psu_index, char *buf, size_t count) +{ + uint64_t key; + int ret; + int pmbus_data; + int alarm; + + if (buf == NULL) { + DFD_PSU_DEBUG(DBG_ERROR, "buf is NULL, psu index: %u\n", psu_index); + return -EINVAL; + } + if (count <= 0) { + DFD_PSU_DEBUG(DBG_ERROR, "buf size error, count: %lu, psu index: %u\n", count, psu_index); + return -EINVAL; + } + + /* PMBUS STATUS WORD (0x79) */ + key = DFD_CFG_KEY(DFD_CFG_ITEM_PSU_PMBUS_REG, psu_index, PSU_OUT_STATUS); + ret = dfd_info_get_int(key, &pmbus_data, NULL); + if (ret < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "get psu%u pmbus status info failed, key_name: %s, ret: %d\n", + psu_index, key_to_name(DFD_CFG_ITEM_PSU_PMBUS_REG), ret); + return ret; + } + + alarm = 0; + if (pmbus_data & PSU_STATUS_WORD_TEMPERATURE) { + DFD_PSU_DEBUG(DBG_VERBOSE, "psu%d PSU_TERMAL_ERROR, pmbus_data = 0x%x \n", psu_index, pmbus_data); + alarm |= PSU_TERMAL_ERROR; + } + + if (pmbus_data & PSU_STATUS_WORD_FANS) { + DFD_PSU_DEBUG(DBG_VERBOSE, "psu%d PSU_FAN_ERROR, pmbus_data = 0x%x \n", psu_index, pmbus_data); + alarm |= PSU_FAN_ERROR; + } + + if (pmbus_data & PSU_VOLTAGE_ERR_OFFSET) { + DFD_PSU_DEBUG(DBG_VERBOSE, "psu%d PSU_VOL_ERROR, pmbus_data = 0x%x \n", psu_index, pmbus_data); + alarm |= PSU_VOL_ERROR; + } + DFD_PSU_DEBUG(DBG_VERBOSE, "psu_index: %u, pmbus_data = 0x%x \n", psu_index, pmbus_data); + + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%d\n", alarm); +} + +/** + * dfd_get_psu_fan_ratio_str - Gets the target fan rotation rate + * @index: Number of the power supply, starting from 1 + * return: Success: Length of the status string + * : Negative value - Read failed + */ +ssize_t dfd_get_psu_fan_ratio_str(unsigned int psu_index, char *buf, size_t count) +{ + uint64_t key; + int ret; + int pmbus_data; + + if (buf == NULL) { + DFD_PSU_DEBUG(DBG_ERROR, "buf is NULL, psu index: %u\n", psu_index); + return -EINVAL; + } + if (count <= 0) { + DFD_PSU_DEBUG(DBG_ERROR, "buf size error, count: %lu, psu index: %u\n", count, psu_index); + return -EINVAL; + } + + /* Gets the status from the pmbus register of the power supply */ + key = DFD_CFG_KEY(DFD_CFG_ITEM_PSU_PMBUS_REG, psu_index, PSU_FAN_RATIO); + ret = dfd_info_get_int(key, &pmbus_data, NULL); + if (ret < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "get psu%u pmbus fan ratio info failed, key_name: %s, ret: %d\n", + psu_index, key_to_name(DFD_CFG_ITEM_PSU_PMBUS_REG), ret); + return ret; + } + + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%d\n", pmbus_data); +} + +ssize_t dfd_get_psu_threshold_str(unsigned int psu_index, unsigned int type, char *buf, size_t count) +{ + uint64_t key; + int ret; + + if (buf == NULL) { + DFD_PSU_DEBUG(DBG_ERROR, "buf is NULL, psu index: %u\n", psu_index); + return -EINVAL; + } + if (count <= 0) { + DFD_PSU_DEBUG(DBG_ERROR, "buf size error, count: %lu, psu index: %u\n", count, psu_index); + return -EINVAL; + } + key = DFD_CFG_KEY(DFD_CFG_ITEM_HWMON_PSU, psu_index, type); + ret = dfd_info_get_sensor(key, buf, count, NULL); + if (ret < 0) { + DFD_SENSOR_DEBUG(DBG_ERROR, "get psu sensor info error, key_name: %s, ret: %d\n", + key_to_name(DFD_CFG_ITEM_HWMON_PSU), ret); + } else { + DFD_SENSOR_DEBUG(DBG_VERBOSE, "get psu sensor info success, value: %s\n", buf); + } + return ret; +} + +ssize_t dfd_get_psu_blackbox(unsigned int psu_index, char *buf, size_t count) +{ + uint64_t key; + ssize_t rd_len; + char *blackbox_path; + + if (buf == NULL) { + DFD_PSU_DEBUG(DBG_ERROR, "params error.psu_index: %u.",psu_index); + return -EINVAL; + } + if (count <= 0) { + DFD_PSU_DEBUG(DBG_ERROR, "buf size error, count: %lu, psu index: %u\n", + count, psu_index); + return -EINVAL; + } + + /* Obtain the blackbox_info path*/ + key = DFD_CFG_KEY(DFD_CFG_ITEM_PSU_BLACKBOX_INFO, psu_index, 0); + blackbox_path = dfd_ko_cfg_get_item(key); + if (blackbox_path == NULL) { + DFD_PSU_DEBUG(DBG_ERROR, "get psu%u blackbox_info path error, key_name: %s\n", + psu_index, key_to_name(DFD_CFG_ITEM_PSU_BLACKBOX_INFO)); + return -DFD_RV_DEV_NOTSUPPORT; + } + + DFD_PSU_DEBUG(DBG_VERBOSE, "psu_index: %u, blackbox_info path: %s\n", psu_index, blackbox_path); + + mem_clear(buf, count); + rd_len = dfd_ko_read_file(blackbox_path, 0, buf, count); + if (rd_len < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "read psu%u blackbox info failed, blackbox_info path: %s, ret: %ld\n", + psu_index, blackbox_path, rd_len); + } else { + DFD_PSU_DEBUG(DBG_VERBOSE, "read psu%u blackbox info success, blackbox_info path: %s, rd_len: %ld\n", + psu_index, blackbox_path, rd_len); + } + + return rd_len; +} + +ssize_t dfd_get_psu_pmbus(unsigned int psu_index, char *buf, size_t count) +{ + uint64_t key; + ssize_t rd_len; + char *pmbus_info_path; + + if (buf == NULL) { + DFD_PSU_DEBUG(DBG_ERROR, "params error.psu_index: %u.",psu_index); + return -EINVAL; + } + if (count <= 0) { + DFD_PSU_DEBUG(DBG_ERROR, "buf size error, count: %lu, psu index: %u\n", + count, psu_index); + return -EINVAL; + } + + /* Obtain the pmbus_info path*/ + key = DFD_CFG_KEY(DFD_CFG_ITEM_PSU_PMBUS_INFO, psu_index, 0); + pmbus_info_path = dfd_ko_cfg_get_item(key); + if (pmbus_info_path == NULL) { + DFD_PSU_DEBUG(DBG_ERROR, "get psu%u pmbus_info path error, key_name: %s\n", + psu_index, key_to_name(DFD_CFG_ITEM_PSU_PMBUS_INFO)); + return -DFD_RV_DEV_NOTSUPPORT; + } + + DFD_PSU_DEBUG(DBG_VERBOSE, "psu_index: %u, pmbus_info path: %s\n", psu_index, pmbus_info_path); + + mem_clear(buf, count); + rd_len = dfd_ko_read_file(pmbus_info_path, 0, buf, count); + if (rd_len < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "read psu%u pmbus info failed, pmbus_info path: %s, ret: %ld\n", + psu_index, pmbus_info_path, rd_len); + } else { + DFD_PSU_DEBUG(DBG_VERBOSE, "read psu%u pmbus info success, pmbus_info path: %s, rd_len: %ld\n", + psu_index, pmbus_info_path, rd_len); + } + + return rd_len; +} + +int dfd_clear_psu_blackbox(unsigned int psu_index, uint8_t value) +{ + uint64_t key; + int ret; + char *clear_blackbox_info_path; + uint8_t wr_buf[INFO_INT_MAX_LEN]; + + /* Obtain the clear_blackbox path*/ + key = DFD_CFG_KEY(DFD_CFG_ITEM_PSU_CLEAR_BLACKBOX, psu_index, 0); + clear_blackbox_info_path = dfd_ko_cfg_get_item(key); + if (clear_blackbox_info_path == NULL) { + DFD_PSU_DEBUG(DBG_ERROR, "get psu%u clear blackbox path error, key_name: %s\n", + psu_index, key_to_name(DFD_CFG_ITEM_PSU_CLEAR_BLACKBOX)); + return -DFD_RV_DEV_NOTSUPPORT; + } + + DFD_PSU_DEBUG(DBG_VERBOSE, "psu_index: %u, clear blackbox path: %s, write value: %u\n", + psu_index, clear_blackbox_info_path, value); + + mem_clear(wr_buf, sizeof(wr_buf)); + snprintf(wr_buf, sizeof(wr_buf), "%u", value); + ret = dfd_ko_write_file(clear_blackbox_info_path, 0, wr_buf, strlen(wr_buf)); + if (ret < 0) { + DFD_PSU_DEBUG(DBG_ERROR, "clear psu%u blackbox info failed, ret: %d\n", psu_index, ret); + return ret; + } + + DFD_PSU_DEBUG(DBG_VERBOSE, "psu_index: %u, clear blackbox info success\n", psu_index); + return DFD_RV_OK; +} + diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_sensors_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_sensors_driver.c new file mode 100644 index 000000000000..c7342de6e3e2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_sensors_driver.c @@ -0,0 +1,345 @@ +/* + * An wb_sensors_driver driver for snesors devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include + +#include "wb_module.h" +#include "dfd_cfg.h" +#include "dfd_cfg_adapter.h" +#include "dfd_cfg_info.h" +#include "dfd_frueeprom.h" +#include "dfd_cfg_file.h" + +#define DFD_GET_TEMP_SENSOR_KEY1(dev_index, temp_index) \ + (((dev_index & 0xff) << 8) | (temp_index & 0xff)) +#define DFD_GET_TEMP_SENSOR_KEY2(main_dev_id, temp_type) \ + (((main_dev_id & 0x0f) << 4) | (temp_type & 0x0f)) +#define DFD_FORMAT_STR_MAX_LEN (32) + +int g_dfd_sensor_dbg_level = 0; +module_param(g_dfd_sensor_dbg_level, int, S_IRUGO | S_IWUSR); + +static int dfd_deal_hwmon_buf(uint8_t *buf, int buf_len, uint8_t *buf_new, int *buf_len_new, + info_ctrl_t *info_ctrl, int coefficient, int addend) +{ + int i, tmp_len; + int exp, decimal, divisor; + int org_value, tmp_value; + int div_result, div_mod; + char fmt_str[DFD_FORMAT_STR_MAX_LEN]; + + exp = info_ctrl->int_cons; /* Numerical conversion index */ + decimal = info_ctrl->bit_offset; /* Decimal point retention number */ + + /* No conversion is required, just copy the value */ + if ((exp <= 0) && (coefficient == 1) && (addend == 0)) { + DBG_DEBUG(DBG_VERBOSE, "exponent %d, coefficient: %d, addend: %d, don't need transform, buf_len: %d, buf_len_new: %d\n", + exp, coefficient, addend, buf_len, *buf_len_new); + snprintf(buf_new, *buf_len_new, "%s", buf); + *buf_len_new = strlen(buf_new); + return DFD_RV_OK; + } + + divisor = 1; + for (i = 0; i < exp; i++) { + divisor *= 10; + } + org_value = simple_strtol(buf, NULL, 10); + DBG_DEBUG(DBG_VERBOSE, "original value: %d, exp: %d, divisor: %d, decimal: %d, coefficient: %d, addend: %d\n", + org_value, exp, divisor, decimal, coefficient, addend); + + org_value = (org_value + addend) * coefficient; + if (org_value < 0) { + tmp_value = 0 - org_value; + } else { + tmp_value = org_value; + } + div_result = tmp_value / divisor; + div_mod = tmp_value % divisor; + DBG_DEBUG(DBG_VERBOSE, "tmp_value: %d, divisor: %d, div_result: %d, div_mod: %d\n", + tmp_value, divisor, div_result, div_mod); + /* don't need to keep the decimal, just round it */ + if (decimal == 0) { + snprintf(buf_new, *buf_len_new, "%d\n", div_result); + *buf_len_new = strlen(buf_new); + return DFD_RV_OK; + } + mem_clear(fmt_str, sizeof(fmt_str)); + if (org_value < 0) { + snprintf(fmt_str, sizeof(fmt_str), "-%%d.%%0%dd\n",exp); + } else { + snprintf(fmt_str, sizeof(fmt_str), "%%d.%%0%dd\n",exp); + } + DBG_DEBUG(DBG_VERBOSE, "format string: %s",fmt_str); + snprintf(buf_new, *buf_len_new, fmt_str, div_result, div_mod); + *buf_len_new = strlen(buf_new); + tmp_len = *buf_len_new; + /* Keep decimal places only when the number of decimal places is reduced */ + if (decimal > 0) { + for (i = 0; i < *buf_len_new; i++) { + if (buf_new[i] == '.') { + if (i + decimal + 2 <= *buf_len_new) { + buf_new[i + decimal + 1 ] = '\n'; + buf_new[i + decimal + 2 ] = '\0'; + *buf_len_new = strlen(buf_new); + DBG_DEBUG(DBG_VERBOSE, "deal decimal[%d] ok, str len:%d, value:%s\n", + decimal, *buf_len_new, buf_new); + } + break; + } + } + if (tmp_len == *buf_len_new) { + DBG_DEBUG(DBG_WARN, "deal decimal[%d] failed, use original value:%s\n", decimal, + buf_new); + } + } + return DFD_RV_OK; +} + +static int dfd_get_sensor_info(uint8_t main_dev_id, uint8_t dev_index, uint8_t sensor_type, + uint8_t sensor_index, uint8_t sensor_attr, char *buf, size_t count) +{ + uint64_t key; + uint16_t key_index1; + uint8_t key_index2; + int rv; + info_hwmon_buf_f pfunc; + + key_index1 = DFD_GET_TEMP_SENSOR_KEY1(dev_index, sensor_index); + key_index2 = DFD_GET_TEMP_SENSOR_KEY2(main_dev_id, sensor_attr); + if (sensor_type == WB_MINOR_DEV_TEMP) { + key = DFD_CFG_KEY(DFD_CFG_ITEM_HWMON_TEMP, key_index1, key_index2); + } else if (sensor_type == WB_MINOR_DEV_IN) { + key = DFD_CFG_KEY(DFD_CFG_ITEM_HWMON_IN, key_index1, key_index2); + } else if (sensor_type == WB_MINOR_DEV_CURR) { + key = DFD_CFG_KEY(DFD_CFG_ITEM_HWMON_CURR, key_index1, key_index2); + } else { + DFD_SENSOR_DEBUG(DBG_ERROR, "Unknow sensor type: %u\n",sensor_type); + return -DFD_RV_INVALID_VALUE; + } + + DFD_SENSOR_DEBUG(DBG_VERBOSE, "main_dev_id: %u, dev_index: 0x%x, sensor_index: 0x%x, \ + sensor_attr: 0x%x, key: 0x%08llx\n", main_dev_id, dev_index, sensor_index, sensor_attr, key); + + pfunc = dfd_deal_hwmon_buf; + rv = dfd_info_get_sensor(key, buf, count, pfunc); + return rv; +} + +/** + * dfd_get_temp_info - Get temperature information + * @main_dev_id: Motherboard :0 Power supply :2 subcard :5 + * @dev_index: If no device index exists, the value is 0, and 1 indicates slot1/psu1 + * @temp_index: Temperature index, starting at 1 + * @temp_type: Read type,1:alias 2:type 3:max 4:max_hyst 5:min 6:input + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_temp_info(uint8_t main_dev_id, uint8_t dev_index, uint8_t temp_index, + uint8_t temp_attr, char *buf, size_t count) +{ + int rv; + + if (buf == NULL) { + DFD_SENSOR_DEBUG(DBG_ERROR, "param error, buf is NULL\n"); + return -DFD_RV_INVALID_VALUE; + } + + if (count <= 0) { + DFD_SENSOR_DEBUG(DBG_ERROR, "buf size error, count: %lu\n", count); + return -DFD_RV_INVALID_VALUE; + } + + rv = dfd_get_sensor_info(main_dev_id, dev_index, WB_MINOR_DEV_TEMP, temp_index, temp_attr, + buf, count); + if (rv < 0) { + DFD_SENSOR_DEBUG(DBG_ERROR, "get temp info error, rv: %d\n", rv); + } else { + DFD_SENSOR_DEBUG(DBG_VERBOSE, "get temp info success, value: %s\n", buf); + } + return rv; +} + +/** + * dfd_get_voltage_info - Get voltage information + * @main_dev_id: Motherboard :0 Power supply :2 subcard :5 + * @dev_index: If no device index exists, the value is 0, and 1 indicates slot1 + * @in_index: Voltage index, starting at 1 + * @in_type: Voltage type,1:alias 2:type 3:max 4:max_hyst 5:min 6:input + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_voltage_info(uint8_t main_dev_id, uint8_t dev_index, uint8_t in_index, + uint8_t in_attr, char *buf, size_t count) +{ + int rv; + + if (buf == NULL) { + DFD_SENSOR_DEBUG(DBG_ERROR, "param error buf is NULL.\n"); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DFD_SENSOR_DEBUG(DBG_ERROR, "buf size error, count: %lu\n", count); + return -DFD_RV_INVALID_VALUE; + } + rv = dfd_get_sensor_info(main_dev_id, dev_index, WB_MINOR_DEV_IN, in_index, in_attr, buf, + count); + if (rv < 0) { + DFD_SENSOR_DEBUG(DBG_ERROR, "get voltage info error, rv: %d\n", rv); + } else { + DFD_SENSOR_DEBUG(DBG_VERBOSE, "get voltage info success, value: %s\n", buf); + } + return rv; +} + +/** + * dfd_get_current_info - Get current information + * @main_dev_id: Motherboard :0 Power supply :2 subcard :5 + * @dev_index: If no device index exists, the value is 0, and 1 indicates slot1 + * @in_index: Current index, starting at 1 + * @in_type: Current type,1:alias 2:type 3:max 4:max_hyst 5:min 6:input + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_current_info(uint8_t main_dev_id, uint8_t dev_index, uint8_t curr_index, + uint8_t curr_attr, char *buf, size_t count) +{ + int rv; + + if (buf == NULL) { + DFD_SENSOR_DEBUG(DBG_ERROR, "param error buf is NULL.\n"); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DFD_SENSOR_DEBUG(DBG_ERROR, "buf size error, count: %lu\n", count); + return -DFD_RV_INVALID_VALUE; + } + rv = dfd_get_sensor_info(main_dev_id, dev_index, WB_MINOR_DEV_CURR, curr_index, curr_attr, + buf, count); + if (rv < 0) { + DFD_SENSOR_DEBUG(DBG_ERROR, "get current info error, rv: %d\n", rv); + } else { + DFD_SENSOR_DEBUG(DBG_VERBOSE, "get current info success, value: %s\n", buf); + } + return rv; +} + +/** + * dfd_get_psu_sensor_info - Obtain PMBUS information about the power supply + * @psu_index: Power index, starting at 1 + * @sensor_type: Type of the obtained pmbus information + * @buf: pmbus results are stored in buf + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_psu_sensor_info(uint8_t psu_index, uint8_t sensor_type, char *buf, size_t count) +{ + uint64_t key; + int rv; + info_hwmon_buf_f pfunc; + + if (buf == NULL) { + DFD_SENSOR_DEBUG(DBG_ERROR, "param error. buf is NULL.\n"); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DFD_SENSOR_DEBUG(DBG_ERROR, "buf size error, count: %lu\n", count); + return -DFD_RV_INVALID_VALUE; + } + key = DFD_CFG_KEY(DFD_CFG_ITEM_HWMON_PSU, psu_index, sensor_type); + DFD_SENSOR_DEBUG(DBG_VERBOSE, "psu index: %d, sensor type: %d, key_name: %s,\n", psu_index, + sensor_type, key_to_name(DFD_CFG_ITEM_HWMON_PSU)); + pfunc = dfd_deal_hwmon_buf; + rv = dfd_info_get_sensor(key, buf, count, pfunc); + if (rv < 0) { + DFD_SENSOR_DEBUG(DBG_ERROR, "get psu sensor info error, key_name: %s, rv: %d\n", + key_to_name(DFD_CFG_ITEM_HWMON_PSU), rv); + } else { + DFD_SENSOR_DEBUG(DBG_VERBOSE, "get psu sensor info success, value: %s\n", buf); + } + return rv; +} + +/** + * dfd_get_main_board_monitor_flag - Get Monitor flag info + * @main_dev_id: Motherboard :0 Power supply :2 subcard :5 + * @dev_index: If no device index exists, the value is 0, and 1 indicates slot1 + * @sensor_type: Type of the obtained pmbus information + * @in_type: Voltage type,1:alias 2:type 3:max 4:max_hyst 5:min 6:input + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +int dfd_get_main_board_monitor_flag(uint8_t main_dev_id, uint8_t dev_index, uint8_t sensor_type, + uint8_t sensor_index, char *buf, size_t count) +{ + uint64_t key; + uint16_t key_index1; + uint8_t key_index2; + int rv, sensor_type_key, decode_key; + int data; + info_ctrl_t *info_ctrl; + int *p_decode_value; + + key_index1 = DFD_GET_TEMP_SENSOR_KEY1(dev_index, sensor_index); + key_index2 = DFD_GET_TEMP_SENSOR_KEY2(main_dev_id, 0); /* 4bytes. currently low bytes is 0. */ + if (sensor_type == WB_MINOR_DEV_TEMP) { + sensor_type_key = DFD_CFG_ITEM_HWMON_TEMP_MONITOR_FLAG; + decode_key = DFD_CFG_ITEM_HWMON_TEMP_MONITOR_DC; + } else if (sensor_type == WB_MINOR_DEV_IN) { + sensor_type_key = DFD_CFG_ITEM_HWMON_IN_MONITOR_FLAG; + decode_key = DFD_CFG_ITEM_HWMON_IN_MONITOR_FLAG_DC; + } else if (sensor_type == WB_MINOR_DEV_CURR) { + sensor_type_key = DFD_CFG_ITEM_HWMON_CURR_MONITOR_FLAG; + decode_key = DFD_CFG_ITEM_HWMON_CURR_MONITOR_FLAG_DC; + } else { + DFD_SENSOR_DEBUG(DBG_ERROR, "Unknow sensor type: %u\n",sensor_type); + return -DFD_RV_INVALID_VALUE; + } + + key = DFD_CFG_KEY(sensor_type_key, key_index1, key_index2); + info_ctrl = dfd_ko_cfg_get_item(key); + if (info_ctrl == NULL) { + DBG_DEBUG(DBG_VERBOSE, "get info ctrl failed, key=0x%08llx\n", key); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", WB_SENSOR_MONITOR_YES); + } + + rv = dfd_info_get_int(key, &data, NULL); + if (rv < 0) { + DFD_SENSOR_DEBUG(DBG_ERROR, "get monitor flag error, key_name: %s, rv: %d\n", + key_to_name(sensor_type_key), rv); + return rv; + } + + key = DFD_CFG_KEY(decode_key, key_index1, data); + p_decode_value = dfd_ko_cfg_get_item(key); + if (p_decode_value == NULL) { + DFD_SENSOR_DEBUG(DBG_VERBOSE, "status needn't decode. value:0x%x\n", data); + } else { + DFD_SENSOR_DEBUG(DBG_VERBOSE, "ori_value:0x%x, decoded value:0x%x\n", data, *p_decode_value); + data = *p_decode_value; + } + + DFD_SENSOR_DEBUG(DBG_VERBOSE, "main_dev_id: %u, dev_index: 0x%x, sensor_index: 0x%x, \ + key_name: %s, data = %d\n", main_dev_id, dev_index, sensor_index, key_to_name(sensor_type_key), data); + + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", data); +} + diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_sff_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_sff_driver.c new file mode 100644 index 000000000000..1b55989ebde0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_sff_driver.c @@ -0,0 +1,143 @@ +/* + * An wb_sff_driver driver for sff devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#include "wb_module.h" +#include "dfd_cfg.h" +#include "dfd_cfg_info.h" +#include "dfd_cfg_adapter.h" + +int g_dfd_sff_dbg_level = 0; +module_param(g_dfd_sff_dbg_level, int, S_IRUGO | S_IWUSR); + +/** + * dfd_set_sff_cpld_info - Example Set the CPLD register status of the optical module + * @sff_index: Optical module number, starting from 1 + * @cpld_reg_type: Optical module CPLD register type + * @value: Writes the value to the register + * return: Success :0 + * : Failed: A negative value is returned + */ +int dfd_set_sff_cpld_info(unsigned int sff_index, int cpld_reg_type, int value) +{ + uint64_t key; + int ret; + + if ((value != 0) && (value != 1)) { + DFD_SFF_DEBUG(DBG_ERROR, "sff%u cpld reg type %d, can't set invalid value: %d\n", + sff_index, cpld_reg_type, value); + return -DFD_RV_INVALID_VALUE; + } + key = DFD_CFG_KEY(DFD_CFG_ITEM_SFF_CPLD_REG, sff_index, cpld_reg_type); + ret = dfd_info_set_int(key, value); + if (ret < 0) { + DFD_SFF_DEBUG(DBG_ERROR, "set sff%u cpld reg type %d error, key_name: %s, ret: %d.\n", + sff_index, cpld_reg_type, key_to_name(DFD_CFG_ITEM_SFF_CPLD_REG), ret); + return ret; + } + + return DFD_RV_OK; +} + +/** + * dfd_get_sff_cpld_info - Obtain the CPLD register status of the optical module + * @sff_index: Optical module number, starting from 1 + * @cpld_reg_type: Optical module CPLD register type + * @buf: Optical module E2 receives information from buf + * @count: buf length + * return: Success: Returns the length of fill buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_sff_cpld_info(unsigned int sff_index, int cpld_reg_type, char *buf, size_t count) +{ + uint64_t key; + int ret, value; + + if (buf == NULL) { + DFD_SFF_DEBUG(DBG_ERROR, "param error, buf is NULL. sff_index: %u, cpld_reg_type: %d\n", + sff_index, cpld_reg_type); + return -DFD_RV_INVALID_VALUE; + } + if (count <= 0) { + DFD_SFF_DEBUG(DBG_ERROR, "buf size error, count: %lu, sff index: %u, cpld_reg_type: %d\n", + count, sff_index, cpld_reg_type); + return -DFD_RV_INVALID_VALUE; + } + mem_clear(buf, count); + key = DFD_CFG_KEY(DFD_CFG_ITEM_SFF_CPLD_REG, sff_index, cpld_reg_type); + ret = dfd_info_get_int(key, &value, NULL); + if (ret < 0) { + DFD_SFF_DEBUG(DBG_ERROR, "get sff%u cpld reg type %d error, key_name: %s, ret: %d\n", + sff_index, cpld_reg_type, key_to_name(DFD_CFG_ITEM_SFF_CPLD_REG), ret); + return ret; + } + return (ssize_t)snprintf(buf, count, "%d\n", value); +} + +/** + * dfd_get_single_eth_optoe_type - get sff optoe type + * @sff_index: Optical module number, starting from 1 + * @optoe_type: Optical module type + * return: Success: Returns the length of fill buf + * : Failed: A negative value is returned + */ +int dfd_get_single_eth_optoe_type(unsigned int sff_index, int *optoe_type) +{ + uint64_t key; + int ret, value; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_SFF_OPTOE_TYPE, sff_index, 0); + ret = dfd_info_get_int(key, &value, NULL); + if (ret < 0) { + DFD_SFF_DEBUG(DBG_ERROR, "get sff optoe type error, key_name: %s, ret:%d.\n", + key_to_name(DFD_CFG_ITEM_SFF_OPTOE_TYPE), ret); + return ret; + } + + /* assic int to int */ + *optoe_type = value - '0'; + return ret; +} + +/** + * dfd_set_single_eth_optoe_type - set sff optoe type + * @sff_index: Optical module number, starting from 1 + * @optoe_type: Optical module type + * return: Success: Returns the length of fill buf + * : Failed: A negative value is returned + */ +int dfd_set_single_eth_optoe_type(unsigned int sff_index, int optoe_type) +{ + uint64_t key; + int ret, value; + + /* int to assic int */ + value = optoe_type + '0'; + key = DFD_CFG_KEY(DFD_CFG_ITEM_SFF_OPTOE_TYPE, sff_index, 0); + ret = dfd_info_set_int(key, value); + if (ret < 0) { + DFD_SFF_DEBUG(DBG_ERROR, "set sff optoe type error, key_name: %s, ret:%d.\n", + key_to_name(DFD_CFG_ITEM_SFF_OPTOE_TYPE), ret); + return ret; + } + + return ret; +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_slot_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_slot_driver.c new file mode 100644 index 000000000000..5ba743f3c4d4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_slot_driver.c @@ -0,0 +1,174 @@ +/* + * An wb_slot_driver driver for slot devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include + +#include "wb_module.h" +#include "dfd_cfg.h" +#include "dfd_cfg_adapter.h" +#include "dfd_cfg_info.h" +#include "dfd_frueeprom.h" + +#define SLOT_SIZE (256) + +int g_dfd_slot_dbg_level = 0; +module_param(g_dfd_slot_dbg_level, int, S_IRUGO | S_IWUSR); + +static char *dfd_get_slot_sysfs_name(void) +{ + uint64_t key; + char *sysfs_name; + + /* string Type configuration item */ + key = DFD_CFG_KEY(DFD_CFG_ITEM_SLOT_SYSFS_NAME, 0, 0); + sysfs_name = dfd_ko_cfg_get_item(key); + if (sysfs_name == NULL) { + DFD_SLOT_DEBUG(DBG_VERBOSE, "key_name=%s, sysfs_name is NULL, use default way.\n", + key_to_name(DFD_CFG_ITEM_SLOT_SYSFS_NAME)); + } else { + DFD_SLOT_DEBUG(DBG_VERBOSE, "sysfs_name: %s.\n", sysfs_name); + } + return sysfs_name; +} + +/** + * dfd_get_slot_status - Gets the subcard status + * @index: Number of the sub-card, starting from 1 + * return: 0:ABSENT + * 1:OK + * : Negative value - Read failed + */ +static int dfd_get_slot_status(unsigned int slot_index) +{ + uint64_t key; + int ret; + int status; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_DEV_PRESENT_STATUS, WB_MAIN_DEV_SLOT, slot_index); + ret = dfd_info_get_int(key, &status, NULL); + if (ret < 0) { + DFD_SLOT_DEBUG(DBG_ERROR, "get slot status error, key_name:%s\n", + key_to_name(DFD_CFG_ITEM_DEV_PRESENT_STATUS)); + return ret; + } + return status; +} + +/** + * dfd_get_slot_status_str - Gets the subcard status + * @slot_index: Number of the sub-card, starting from 1 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success: Length of the status string + * : Negative value - Read failed + */ +ssize_t dfd_get_slot_status_str(unsigned int slot_index, char *buf, size_t count) +{ + int ret; + if (buf == NULL) { + DFD_SLOT_DEBUG(DBG_ERROR, "params error.slot_index:%d.",slot_index); + return -DFD_RV_INVALID_VALUE; + } + ret = dfd_get_slot_status(slot_index); + if (ret < 0) { + DFD_SLOT_DEBUG(DBG_ERROR, "get slot status error,ret:%d, slot_index:%d\n", ret, slot_index); + return ret; + } + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%d\n", ret); +} + +/** + * dfd_get_slot_info - Obtain the subcard information + * @slot_index: Number of the sub-card, starting from 1 + * @cmd: Subcard information type, subcard name :2, subcard serial number :3, subcard hardware version number :5 + * @buf: Receive buf + * @count: Accept the buf length + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_slot_info(unsigned int slot_index, uint8_t cmd, char *buf, size_t count) +{ + uint64_t key; + int rv; + char slot_buf[SLOT_SIZE]; + dfd_i2c_dev_t *i2c_dev; + const char *sysfs_name; + + if (buf == NULL) { + DFD_SLOT_DEBUG(DBG_ERROR, "buf is NULL, slot index:%d, cmd:%d\n", slot_index, cmd); + return -DFD_RV_INVALID_VALUE; + } + + mem_clear(buf, count); + mem_clear(slot_buf, SLOT_SIZE); + + key = DFD_CFG_KEY(DFD_CFG_ITEM_OTHER_I2C_DEV, WB_MAIN_DEV_SLOT, slot_index); + i2c_dev = dfd_ko_cfg_get_item(key); + if (i2c_dev == NULL) { + DFD_SLOT_DEBUG(DBG_ERROR, "slot i2c dev config error, key_name=%s\n", + key_to_name(DFD_CFG_ITEM_OTHER_I2C_DEV)); + return -DFD_RV_DEV_NOTSUPPORT; + } + sysfs_name = dfd_get_slot_sysfs_name(); + rv = dfd_get_fru_board_data(i2c_dev->bus, i2c_dev->addr, cmd, slot_buf, SLOT_SIZE, sysfs_name); + + if (rv < 0) { + DFD_SLOT_DEBUG(DBG_ERROR, "slot eeprom read failed"); + return -DFD_RV_DEV_FAIL; + } + + DFD_SLOT_DEBUG(DBG_VERBOSE, "%s\n", slot_buf); + snprintf(buf, count, "%s\n", slot_buf); + return strlen(buf); +} + +ssize_t dfd_get_slot_power_status_str(unsigned int slot_index, char *buf, size_t count) +{ + uint64_t key; + int ret; + int status; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_POWER_STATUS, WB_MAIN_DEV_SLOT, slot_index); + ret = dfd_info_get_int(key, &status, NULL); + if (ret < 0) { + DFD_SLOT_DEBUG(DBG_ERROR, "get slot status error, key_name: %s\r\n", + key_to_name(DFD_CFG_ITEM_POWER_STATUS)); + return ret; + } + mem_clear(buf, count); + return (ssize_t)snprintf(buf, count, "%d\n", status); +} + +int dfd_set_slot_power_status_str(unsigned int slot_index, int value) +{ + uint64_t key; + int ret; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_POWER_STATUS, WB_MAIN_DEV_SLOT, slot_index); + ret = dfd_info_set_int(key, value); + if (ret < 0) { + DBG_SYSLED_DEBUG(DBG_ERROR, "set led status error, key_name: %s,ret:%d\r\n", + key_to_name(DFD_CFG_ITEM_POWER_STATUS), ret); + return ret; + } + return ret; +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_system_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_system_driver.c new file mode 100644 index 000000000000..d938c118b086 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_system_driver.c @@ -0,0 +1,253 @@ +/* + * An wb_system_driver driver for system devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include + +#include "wb_module.h" +#include "dfd_cfg.h" +#include "dfd_cfg_info.h" +#include "dfd_cfg_adapter.h" +#include "wb_system_driver.h" +#include "switch_driver.h" + +#define NODE_MAX_LEN (64) + +int g_dfd_custom_dbg_level = 0; +module_param(g_dfd_custom_dbg_level, int, S_IRUGO | S_IWUSR); + +/* Get current function step number */ +int dfd_get_cmd_count(unsigned int type) +{ + uint64_t key; + int cmd_num; + int *p_cmd_num; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_BMC_SYSTEM_CMD_NUM, type, 0); + p_cmd_num = dfd_ko_cfg_get_item(key); + if (p_cmd_num == NULL) { + DFD_SYSTEM_DEBUG(DBG_ERROR, "get cmd number failed, key_name:%s\n", + key_to_name(DFD_CFG_ITEM_BMC_SYSTEM_CMD_NUM)); + return -DFD_RV_DEV_NOTSUPPORT; + } + cmd_num = *p_cmd_num; + DFD_SYSTEM_DEBUG(DBG_VERBOSE, "get cmd number ok, type:0x%x, number:%d\n", type, cmd_num); + return cmd_num; +} + +void dfd_cmd_delay(unsigned int usdelay) +{ + DFD_SYSTEM_DEBUG(DBG_VERBOSE, "usdelay:%d\n", usdelay); + usleep_range(usdelay, usdelay + 1); + return; +} + +ssize_t dfd_system_get_system_value(unsigned int type, int *value) +{ + uint64_t key; + int ret; + info_ctrl_t *info_ctrl; + int *p_decode_value; + + + key = DFD_CFG_KEY(DFD_CFG_ITEM_BMC_SYSTEM, type, 0); + info_ctrl = dfd_ko_cfg_get_item(key); + if (info_ctrl == NULL) { + DFD_SYSTEM_DEBUG(DBG_ERROR, "get info ctrl fail, key_name: %s, type=0x%x\n", + key_to_name(DFD_CFG_ITEM_BMC_SYSTEM), type); + return -DFD_RV_DEV_NOTSUPPORT; + } + DFD_SYSTEM_DEBUG(DBG_VERBOSE, "get, key_name: %s, type=0x%x\n", + key_to_name(DFD_CFG_ITEM_BMC_SYSTEM), type); + ret = dfd_info_get_int(key, value, NULL); + if (ret < 0) { + DFD_SYSTEM_DEBUG(DBG_ERROR, "get system value error, key_name: %s, type=0x%x, ret:%d\n", + key_to_name(DFD_CFG_ITEM_BMC_SYSTEM), type, ret); + return ret; + } + + key = DFD_CFG_KEY(DFD_CFG_ITEM_SYSTEM_STATUS_DECODE, type, *value); + p_decode_value = dfd_ko_cfg_get_item(key); + if (p_decode_value == NULL) { + DFD_SYSTEM_DEBUG(DBG_VERBOSE, "type:%d, status needn't decode. value:0x%x\n", type, *value); + } else { + DFD_SYSTEM_DEBUG(DBG_VERBOSE, "type:%d, ori_value:0x%x, decoded value:0x%x\n", type, *value, *p_decode_value); + *value = *p_decode_value; + } + return DFD_RV_OK; +} + +static int dfd_system_check_value_i(unsigned int type_detail, int cmd_i) +{ + uint64_t key; + int ret, i; + info_ctrl_t *info_ctrl; + int tmp_value, retry_times; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_CHECK_VAL_BMC_SYSTEM, type_detail, cmd_i); + info_ctrl = dfd_ko_cfg_get_item(key); + if (info_ctrl == NULL) { + DFD_SYSTEM_DEBUG(DBG_VERBOSE, "key=%s, type_detail=0x%x, cmd_i=%d, don't need to check value\n", + key_to_name(DFD_CFG_ITEM_CHECK_VAL_BMC_SYSTEM), type_detail, cmd_i); + return DFD_RV_OK; + } + + DFD_SYSTEM_DEBUG(DBG_VERBOSE, "key_name=%s, type_detail=0x%x, cmd_i=%d, start to check value,\n", + key_to_name(DFD_CFG_ITEM_CHECK_VAL_BMC_SYSTEM), type_detail, cmd_i); + DFD_SYSTEM_DEBUG(DBG_VERBOSE, "check value, except value: %d, retry_times: %d, sleep_time: %dus\n", + info_ctrl->int_extra1, info_ctrl->int_extra2, info_ctrl->int_extra3); + + if (info_ctrl->int_extra2 <= 0) { + retry_times = 1; + } else { + retry_times = info_ctrl->int_extra2; + } + + for (i = 0; i < retry_times; i++) { + ret = dfd_info_get_int(key, &tmp_value, NULL); + if (ret < 0) { + DFD_SYSTEM_DEBUG(DBG_ERROR, "key_name=%s, type_detail=0x%x, cmd_i=%d, get check value error, ret: %d\n", + key_to_name(DFD_CFG_ITEM_CHECK_VAL_BMC_SYSTEM), type_detail, cmd_i, ret); + return ret; + } + if (tmp_value == info_ctrl->int_extra1) { + DFD_SYSTEM_DEBUG(DBG_VERBOSE, "key_name=%s, type_detail=0x%x, cmd_i=%d, check value ok, get value: %d, except value: %d\n", + key_to_name(DFD_CFG_ITEM_CHECK_VAL_BMC_SYSTEM), type_detail, cmd_i, tmp_value, info_ctrl->int_extra1); + return DFD_RV_OK; + } + DFD_SYSTEM_DEBUG(DBG_VERBOSE, "key_name=%s, type_detail=0x%x, cmd_i=%d, check value failed, get value: %d, except value: %d, retry: %d\n", + key_to_name(DFD_CFG_ITEM_CHECK_VAL_BMC_SYSTEM), type_detail, cmd_i, tmp_value, info_ctrl->int_extra1, i + 1); + + if (info_ctrl->int_extra3 > 0) { + dfd_cmd_delay(info_ctrl->int_extra3); + } + } + + DFD_SYSTEM_DEBUG(DBG_ERROR, "key_name=%s, type_detail=0x%x, cmd_i=%d, check value failed, get value: %d, except value: %d\n", + key_to_name(DFD_CFG_ITEM_CHECK_VAL_BMC_SYSTEM), type_detail, cmd_i, tmp_value, info_ctrl->int_extra1); + return -DFD_RV_CHECK_FAIL; +} + +ssize_t dfd_system_set_system_value(unsigned int type, int value) +{ + uint64_t key; + int ret, cmd_i, cmd_count; + info_ctrl_t *info_ctrl; + unsigned int type_detail; + int tmp_value; + + DFD_SYSTEM_DEBUG(DBG_VERBOSE, "set system value, type=0x%x, value=%d\n", type, value); + /* get step number */ + type_detail = type | (value & 0xff); + ret = dfd_get_cmd_count(type_detail); + if(ret <= 0) { + DFD_SYSTEM_DEBUG(DBG_ERROR, "get cmd number, type_detail=0x%x\n", type_detail); + return -DFD_RV_DEV_NOTSUPPORT; + } + + cmd_count = ret; + /* exec each step */ + for(cmd_i = 0; cmd_i < cmd_count; cmd_i++) { + /* first do pre check */ + key = DFD_CFG_KEY(DFD_CFG_ITEM_PRE_CHECK_BMC_SYSTEM, type_detail, cmd_i); + info_ctrl = dfd_ko_cfg_get_item(key); + if (info_ctrl) { + DFD_SYSTEM_DEBUG(DBG_VERBOSE, "key_name=%s, type_detail=0x%x, cmd_i=%d, start to pre check\n", + key_to_name(DFD_CFG_ITEM_PRE_CHECK_BMC_SYSTEM), type_detail, cmd_i); + ret = dfd_info_get_int(key, &tmp_value, NULL); + if (ret < 0) { + DFD_SYSTEM_DEBUG(DBG_ERROR, "key_name=%s, type_detail=0x%x, cmd_i=%d, get pre check value error, ret: %d\n", + key_to_name(DFD_CFG_ITEM_PRE_CHECK_BMC_SYSTEM), type_detail, cmd_i, ret); + return ret; + } + if (tmp_value != info_ctrl->int_extra1) { + DFD_SYSTEM_DEBUG(DBG_VERBOSE, "key_name=%s, type_detail=0x%x, cmd_i=%d, pre check error, get value: %d, except value: %d, skip this step\n", + key_to_name(DFD_CFG_ITEM_PRE_CHECK_BMC_SYSTEM), type_detail, cmd_i, tmp_value, info_ctrl->int_extra1); + continue; + } + DFD_SYSTEM_DEBUG(DBG_VERBOSE, "key_name=%s, type_detail=0x%x, cmd_i=%d, pre check ok, get value: %d, except value: %d\n", + key_to_name(DFD_CFG_ITEM_PRE_CHECK_BMC_SYSTEM), type_detail, cmd_i, tmp_value, info_ctrl->int_extra1); + } + /* get current step cfg */ + key = DFD_CFG_KEY(DFD_CFG_ITEM_BMC_SYSTEM, type_detail, cmd_i); + info_ctrl = dfd_ko_cfg_get_item(key); + if (info_ctrl == NULL) { + DFD_SYSTEM_DEBUG(DBG_ERROR, "get info ctrl fail, key_name=%s, type_detail=0x%x, cmd_i=%d\n", + key_to_name(DFD_CFG_ITEM_BMC_SYSTEM), type_detail, cmd_i); + return -DFD_RV_DEV_NOTSUPPORT; + } + + DFD_SYSTEM_DEBUG(DBG_VERBOSE, "set, key_name=%s, type_detail=0x%x, cmd_i=%d\n", + key_to_name(DFD_CFG_ITEM_BMC_SYSTEM), type_detail, cmd_i); + /* set int type info */ + ret = dfd_info_set_int(key, info_ctrl->int_cons); + if (ret < 0) { + DFD_SYSTEM_DEBUG(DBG_ERROR, "set system value error, key_name=%s, type_detail=0x%x, cmd_i=%d, value=%d, ret:%d\n", + key_to_name(DFD_CFG_ITEM_BMC_SYSTEM), type_detail, cmd_i, value, ret); + return ret; + } + + /* delay if it has */ + if(info_ctrl->int_extra1 > 0) { + dfd_cmd_delay(info_ctrl->int_extra1); + } + + /* check value */ + ret = dfd_system_check_value_i(type_detail, cmd_i); + if (ret < 0) { + DFD_SYSTEM_DEBUG(DBG_ERROR, "set system value check value error, ret: %d\n", ret); + return ret; + } + } + + return DFD_RV_OK; +} + +ssize_t dfd_system_get_port_power_status(unsigned int type, char *buf, size_t count) +{ + int ret, cmd_i, cmd_count; + unsigned int type_detail; + + /* get step number */ + type_detail = type; + ret = dfd_get_cmd_count(type_detail); + if(ret <= 0) { + DFD_SYSTEM_DEBUG(DBG_ERROR, "get cmd number, type_detail=0x%x\n", type_detail); + return -DFD_RV_DEV_NOTSUPPORT; + } + + cmd_count = ret; + /* exec each step */ + for(cmd_i = 0; cmd_i < cmd_count; cmd_i++) { + /* check value */ + ret = dfd_system_check_value_i(type_detail, cmd_i); + if (ret < 0) { + if(ret == -DFD_RV_CHECK_FAIL) { + return (ssize_t)snprintf(buf, count, "%d\n", WB_PORT_POWER_ON); + } + DFD_SYSTEM_DEBUG(DBG_ERROR, "set system value check value error, ret: %d\n", ret); + return ret; + } + } + + return (ssize_t)snprintf(buf, count, "%d\n", WB_PORT_POWER_OFF); +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_watchdog_driver.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_watchdog_driver.c new file mode 100644 index 000000000000..a146b2e9a337 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/switch_driver/wb_watchdog_driver.c @@ -0,0 +1,217 @@ +/* + * An wb_watchdog_driver driver for watchdog devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include + +#include "wb_module.h" +#include "dfd_cfg.h" +#include "dfd_cfg_info.h" +#include "dfd_cfg_adapter.h" + +#define WDT_FILE_NAME_LEN (64) +#define WDT_ABSOLUTE_PATH_NAME_LEN (256) +#define WDT_SYSFS_FILE_DIR ("/sys/class/watchdog/watchdog%d/") + +typedef enum wb_wdt_enable_status_e { + WB_WDT_DISENABLE = 0, /* close watchdog */ + WB_WDT_ENABLE = 1, /* open watchdog */ +} wb_wdt_enable_status_t; + +struct wdt_file_enable_status_s { + wb_wdt_enable_status_t value; + char state[WDT_FILE_NAME_LEN]; +}; + +struct wdt_file_enable_status_s wdt_file_enable_status_match[] = { + {WB_WDT_DISENABLE, "inactive"}, + {WB_WDT_ENABLE, "active"}, +}; + +int g_dfd_watchdog_dbg_level = 0; +module_param(g_dfd_watchdog_dbg_level, int, S_IRUGO | S_IWUSR); + +static int watchdog_file_read(char *fpath, char *buf, int size) +{ + int ret; + struct file *filp; + loff_t pos; + + filp = filp_open(fpath, O_RDONLY, 0); + if (IS_ERR(filp)) { + DFD_WDT_DEBUG(DBG_ERROR, "watchdog can't open %s.\n", fpath); + filp = NULL; + ret = -ENOENT; + return ret; + } + + mem_clear(buf, size); + pos = 0; + ret = kernel_read(filp, buf, size - 1, &pos); + if (ret < 0) { + DFD_WDT_DEBUG(DBG_ERROR, "kernel_read failed, path=%s, addr=0, size=%d, ret=%d\n", + fpath, size -1, ret); + } + + filp_close(filp, NULL); + filp = NULL; + return ret; +} + +/** + * dfd_get_watchdog_id - Obtain watchdog Number + * @wdt_index: watchdwatchdog index number + + * return: Succeeded: The watchdog number is returned + * : Failed: A negative value is returned + */ +static int dfd_get_watchdog_id(unsigned int wdt_index) +{ + uint64_t key; + int *p_watchdog_id; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_WATCHDOG_ID, wdt_index, 0); + p_watchdog_id = dfd_ko_cfg_get_item(key); + if (p_watchdog_id == NULL) { + DFD_WDT_DEBUG(DBG_ERROR, "get watchdog id error, key_name: %s\n", + key_to_name(DFD_CFG_ITEM_WATCHDOG_ID)); + return -DFD_RV_DEV_NOTSUPPORT; + } + DFD_WDT_DEBUG(DBG_VERBOSE, "get watchdog id ok, watchdog index:%u, id:0x%x.\n", + wdt_index, *p_watchdog_id); + return *p_watchdog_id; +} + +static int watchdog_get_file_name(unsigned int wdt_index, wb_wdt_type_t type, char *buf, int len) +{ + uint64_t key; + char *watchdog_name; + + key = DFD_CFG_KEY(DFD_CFG_ITEM_WATCHDOG_NAME, wdt_index, type); + watchdog_name = dfd_ko_cfg_get_item(key); + if (watchdog_name == NULL) { + DFD_WDT_DEBUG(DBG_ERROR, "watchdog name config error, key_name: %s\n", + key_to_name(DFD_CFG_ITEM_WATCHDOG_NAME)); + return -DFD_RV_DEV_NOTSUPPORT; + } + + DFD_WDT_DEBUG(DBG_VERBOSE, "get watchdog%u %s\n", wdt_index, watchdog_name); + snprintf(buf, len, "%s", watchdog_name); + return DFD_RV_OK; +} + +/** + * dfd_get_watchdog_info - Get watchdog information + * @type: Watchdog information type + * @buf: Receive buf + * return: Success: Returns the length of buf + * : Failed: A negative value is returned + */ +ssize_t dfd_get_watchdog_info(uint8_t type, char *buf, size_t count) +{ + char fpath[WDT_ABSOLUTE_PATH_NAME_LEN]; + int watchdog_id, len, ret; + + /* get watchdog sysfs name */ + watchdog_id = dfd_get_watchdog_id(0); + mem_clear(fpath, WDT_ABSOLUTE_PATH_NAME_LEN); + snprintf(fpath, WDT_ABSOLUTE_PATH_NAME_LEN - 1, WDT_SYSFS_FILE_DIR, watchdog_id); + len = strlen(fpath); + ret = watchdog_get_file_name(watchdog_id, type, &fpath[len], WDT_ABSOLUTE_PATH_NAME_LEN - len); + if (ret < 0) { + DFD_WDT_DEBUG(DBG_WARN, "watchdog type[%u] don't support to get sysfs name.\n", type); + return -DFD_RV_DEV_NOTSUPPORT; + } + + ret = watchdog_file_read(fpath, buf, count - 1); + if (ret < 0) { + DFD_WDT_DEBUG(DBG_ERROR, "watchdog read file %s error, ret: %d\n", fpath, ret); + } + + return ret; +} + +ssize_t dfd_watchdog_get_status(char *buf, size_t count) +{ + uint64_t key; + int watchdog_id, ret, value; + + watchdog_id = dfd_get_watchdog_id(0); + + key = DFD_CFG_KEY(DFD_CFG_ITEM_WATCHDOG_DEV, watchdog_id, WB_WDT_TYPE_ENABLE); + ret = dfd_info_get_int(key, &value, NULL); + if (ret < 0) { + DFD_WDT_DEBUG(DBG_ERROR, "get watchdog enable status, key_name: %s\n", + key_to_name(DFD_CFG_ITEM_WATCHDOG_DEV)); + return ret; + } + DFD_WDT_DEBUG(DBG_VERBOSE, "get watchdog enable status ok, watchdog index:%u, enable:0x%x.\n", + watchdog_id, value); + return (ssize_t)snprintf(buf, count, "%d\n", value); +} + +ssize_t dfd_watchdog_set_status(int value) +{ + uint64_t key; + int watchdog_id, ret; + + watchdog_id = dfd_get_watchdog_id(0); + key = DFD_CFG_KEY(DFD_CFG_ITEM_WATCHDOG_DEV, watchdog_id, WB_WDT_TYPE_ENABLE); + ret = dfd_info_set_int(key, value); + if (ret < 0) { + DFD_WDT_DEBUG(DBG_ERROR, "set watchdog enable status, key: %s\n", + key_to_name(DFD_CFG_ITEM_WATCHDOG_DEV)); + return ret; + } + DFD_WDT_DEBUG(DBG_VERBOSE, "set watchdog enable status ok, watchdog index:%u, enable:0x%x.\n", + watchdog_id, value); + return 0; +} + +ssize_t dfd_watchdog_get_status_str(char *buf, size_t count) +{ + int ret, i; + int enable_status; + + ret = dfd_get_watchdog_info(WB_WDT_TYPE_STATE, buf, count); + if (ret < 0) { + DFD_WDT_DEBUG(DBG_ERROR, "watchdog type[%d] get sysfs name failed.\n", WB_WDT_TYPE_STATE); + return -DFD_RV_DEV_FAIL; + } + + enable_status = -1; + for (i = 0; i < ARRAY_SIZE(wdt_file_enable_status_match); i++) { + if (strncmp(wdt_file_enable_status_match[i].state, buf, \ + strlen(wdt_file_enable_status_match[i].state)) == 0) { + enable_status = wdt_file_enable_status_match[i].value; + DFD_WDT_DEBUG(DBG_VERBOSE, "watchdog read state file %s match enable status[%d].\n", + buf, enable_status); + break; + } + } + + if (enable_status < 0) { + DFD_WDT_DEBUG(DBG_ERROR, "watchdog read state file %s don't match enable status\n", buf); + return -DFD_RV_DEV_FAIL; + } + + return (ssize_t)snprintf(buf, count, "%d\n", enable_status); +} diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/Makefile b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/Makefile new file mode 100644 index 000000000000..197a0e6ff98f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/Makefile @@ -0,0 +1,34 @@ +PWD = $(shell pwd) + +MAKEFILE_FILE_PATH = $(abspath $(lastword $(MAKEFILE_LIST))) +DEV_SYSFS_HEADER_DIR = $(abspath $(MAKEFILE_FILE_PATH)/../../sysfs_driver/include) +SWITCH_DVR_HEADER_DIR = $(abspath $(MAKEFILE_FILE_PATH)/../../switch_driver/include) +EXTRA_CFLAGS:= -I$(M)/include +EXTRA_CFLAGS+= -I$(DEV_SYSFS_HEADER_DIR) +EXTRA_CFLAGS+= -I$(SWITCH_DVR_HEADER_DIR) +EXTRA_CFLAGS+= -Wall + +s3ip_sysfs-objs := switch.o cpld_sysfs.o \ +curr_sensor_sysfs.o \ +fan_sysfs.o \ +fpga_sysfs.o \ +psu_sysfs.o \ +slot_sysfs.o \ +sysled_sysfs.o \ +temp_sensor_sysfs.o \ +transceiver_sysfs.o \ +vol_sensor_sysfs.o \ +watchdog_sysfs.o \ +system_sysfs.o \ +eeprom_sysfs.o \ + +obj-m := s3ip_sysfs.o + +all: + $(MAKE) -C $(KERNEL_SRC)/build M=$(PWD) modules + @if [ ! -d $(module_out_put_dir) ]; then mkdir -p $(module_out_put_dir) ;fi + cp -p $(PWD)/*.ko $(module_out_put_dir) +clean: + rm -f $(PWD)/*.o $(PWD)/*.ko $(PWD)/*.mod.c $(PWD)/.*.cmd + rm -f $(PWD)/Module.markers $(PWD)/Module.symvers $(PWD)/modules.order + rm -rf $(PWD)/.tmp_versions \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/cpld_sysfs.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/cpld_sysfs.c new file mode 100644 index 000000000000..d5b13e3a83f5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/cpld_sysfs.c @@ -0,0 +1,444 @@ +/* + * An cpld_sysfs driver for cpld sysfs devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include + +#include "switch.h" +#include "cpld_sysfs.h" + +static int g_cpld_loglevel = 0; + +#define CPLD_REBOOT_CAUSE_FILE "/etc/.reboot/.previous-reboot-cause.txt" +#define REBOOT_CAUSE_NAME_LEN (64) + +/* Reboot cause type */ +typedef enum wb_reboot_cause_type_e { + REBOOT_CAUSE_NON_HARDWARE = 0, + REBOOT_CAUSE_POWER_LOSS, + REBOOT_CAUSE_THERMAL_OVERLOAD_CPU, + REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC, + REBOOT_CAUSE_THERMAL_OVERLOAD_OTHER, + REBOOT_CAUSE_INSUFFICIENT_FAN_SPEED, + REBOOT_CAUSE_WATCHDOG, + REBOOT_CAUSE_HARDWARE_OTHER, + REBOOT_CAUSE_CPU_COLD_RESET, + REBOOT_CAUSE_CPU_WARM_RESET, + REBOOT_CAUSE_BIOS_RESET, + REBOOT_CAUSE_PSU_SHUTDOWN, + REBOOT_CAUSE_BMC_SHUTDOWN, + REBOOT_CAUSE_RESET_BUTTON_SHUTDOWN, + REBOOT_CAUSE_RESET_BUTTON_COLD_SHUTDOWN, +} wb_reboot_cause_type_t; + +struct reboot_cause_file_info_s { + wb_reboot_cause_type_t reboot_cause_type; + char reboot_cause_name[REBOOT_CAUSE_NAME_LEN]; +}; + +struct reboot_cause_file_info_s reboot_cause_file_info_match[] = { + {REBOOT_CAUSE_POWER_LOSS, "Power Loss"}, + {REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC, "Watchdog reboot"}, + {REBOOT_CAUSE_THERMAL_OVERLOAD_OTHER, "BMC reboot"}, + {REBOOT_CAUSE_BMC_SHUTDOWN, "BMC powerdown"}, + {REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC, "Thermal Overload: ASIC"}, + {REBOOT_CAUSE_CPU_WARM_RESET, "Warm reboot"}, +}; + +#define CPLD_INFO(fmt, args...) do { \ + if (g_cpld_loglevel & INFO) { \ + printk(KERN_INFO "[CPLD_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define CPLD_ERR(fmt, args...) do { \ + if (g_cpld_loglevel & ERR) { \ + printk(KERN_ERR "[CPLD_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define CPLD_DBG(fmt, args...) do { \ + if (g_cpld_loglevel & DBG) { \ + printk(KERN_DEBUG "[CPLD_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct cpld_obj_s { + struct switch_obj *obj; +}; + +struct cpld_s { + unsigned int cpld_number; + struct cpld_obj_s *cpld; +}; + +static struct cpld_s g_cpld; +static struct switch_obj *g_cpld_obj = NULL; +static struct s3ip_sysfs_cpld_drivers_s *g_cpld_drv = NULL; + +static int cpld_file_read(char *fpath, char *buf, int size) +{ + int ret; + struct file *filp; + loff_t pos; + + filp = filp_open(fpath, O_RDONLY, 0); + if (IS_ERR(filp)) { + CPLD_ERR("can't open %s", fpath); + filp = NULL; + ret = -ENOENT; + goto fail; + } + mem_clear(buf, size); + pos = 0; + ret = kernel_read(filp, buf, size - 1, &pos); + if (ret < 0) { + CPLD_ERR("read file %s error, ret:%d\n", fpath, ret); + } +fail: + if (filp != NULL) { + filp_close(filp, NULL); + filp = NULL; + } + + return ret; +} + +static ssize_t cpld_number_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_cpld.cpld_number); +} + +static ssize_t cpld_reboot_cause_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + char reboot_cause_buf[REBOOT_CAUSE_NAME_LEN]; + int ret, i; + char *point; + int reboot_cause_type; + + mem_clear(reboot_cause_buf, sizeof(reboot_cause_buf)); + ret = cpld_file_read(CPLD_REBOOT_CAUSE_FILE, reboot_cause_buf, REBOOT_CAUSE_NAME_LEN - 1); + if (ret < 0) { + CPLD_ERR("read file %s error, ret:%d\n", CPLD_REBOOT_CAUSE_FILE, ret); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", 0); + } + + point = strchr(reboot_cause_buf, ','); + if (point != NULL) { + *point = 0; + } + CPLD_DBG("read reboot cause:%s\n", reboot_cause_buf); + + reboot_cause_type = 0; + for (i = 0; i < ARRAY_SIZE(reboot_cause_file_info_match); i++) { + if (strncmp(reboot_cause_file_info_match[i].reboot_cause_name, reboot_cause_buf, \ + strlen(reboot_cause_file_info_match[i].reboot_cause_name)) == 0) { + reboot_cause_type = reboot_cause_file_info_match[i].reboot_cause_type; + CPLD_DBG("reboot cause %s match type[%d].\n", reboot_cause_file_info_match[i].reboot_cause_name, reboot_cause_type); + break; + } + } + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", reboot_cause_type); +} + +static ssize_t cpld_alias_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int cpld_index; + + check_p(g_cpld_drv); + check_p(g_cpld_drv->get_main_board_cpld_alias); + + cpld_index = obj->index; + CPLD_DBG("cpld index: %u\n", cpld_index); + return g_cpld_drv->get_main_board_cpld_alias(cpld_index, buf, PAGE_SIZE); +} + +static ssize_t cpld_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int cpld_index; + + check_p(g_cpld_drv); + check_p(g_cpld_drv->get_main_board_cpld_type); + + cpld_index = obj->index; + CPLD_DBG("cpld index: %u\n", cpld_index); + return g_cpld_drv->get_main_board_cpld_type(cpld_index, buf, PAGE_SIZE); +} + +static ssize_t cpld_fw_version_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int cpld_index; + + check_p(g_cpld_drv); + check_p(g_cpld_drv->get_main_board_cpld_firmware_version); + + cpld_index = obj->index; + CPLD_DBG("cpld index: %u\n", cpld_index); + return g_cpld_drv->get_main_board_cpld_firmware_version(cpld_index, buf, PAGE_SIZE); +} + +static ssize_t cpld_board_version_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int cpld_index; + + check_p(g_cpld_drv); + check_p(g_cpld_drv->get_main_board_cpld_board_version); + + cpld_index = obj->index; + CPLD_DBG("cpld index: %u\n", cpld_index); + return g_cpld_drv->get_main_board_cpld_board_version(cpld_index, buf, PAGE_SIZE); +} + +static ssize_t cpld_test_reg_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int cpld_index; + + check_p(g_cpld_drv); + check_p(g_cpld_drv->get_main_board_cpld_test_reg); + + cpld_index = obj->index; + CPLD_DBG("cpld index: %u\n", cpld_index); + return g_cpld_drv->get_main_board_cpld_test_reg(cpld_index, buf, PAGE_SIZE); +} + +static ssize_t cpld_test_reg_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int cpld_index, value; + int ret; + + check_p(g_cpld_drv); + check_p(g_cpld_drv->set_main_board_cpld_test_reg); + + cpld_index = obj->index; + sscanf(buf, "0x%x", &value); + ret = g_cpld_drv->set_main_board_cpld_test_reg(cpld_index, value); + if (ret < 0) { + CPLD_ERR("set cpld%u test reg failed, value:0x%x, ret: %d.\n", cpld_index, value, ret); + return ret; + } + CPLD_DBG("set cpld%u test reg success, value: 0x%x.\n", cpld_index, value); + return count; +} + +/************************************cpld dir and attrs*******************************************/ +static struct switch_attribute cpld_number_att = __ATTR(number, S_IRUGO, cpld_number_show, NULL); +static struct switch_attribute cpld_reboot_cause_att = __ATTR(reboot_cause, S_IRUGO, cpld_reboot_cause_show, NULL); + +static struct attribute *cpld_dir_attrs[] = { + &cpld_number_att.attr, + &cpld_reboot_cause_att.attr, + NULL, +}; + +static struct attribute_group cpld_root_attr_group = { + .attrs = cpld_dir_attrs, +}; + +/*******************************cpld[1-n] dir and attrs*******************************************/ +static struct switch_attribute cpld_alias_attr = __ATTR(alias, S_IRUGO, cpld_alias_show, NULL); +static struct switch_attribute cpld_type_attr = __ATTR(type, S_IRUGO, cpld_type_show, NULL); +static struct switch_attribute cpld_fw_version_attr = __ATTR(firmware_version, S_IRUGO, cpld_fw_version_show, NULL); +static struct switch_attribute cpld_board_version_attr = __ATTR(board_version, S_IRUGO, cpld_board_version_show, NULL); +static struct switch_attribute cpld_test_reg_attr = __ATTR(reg_test, S_IRUGO | S_IWUSR, cpld_test_reg_show, cpld_test_reg_store); + +static struct attribute *cpld_attrs[] = { + &cpld_alias_attr.attr, + &cpld_type_attr.attr, + &cpld_fw_version_attr.attr, + &cpld_board_version_attr.attr, + &cpld_test_reg_attr.attr, + NULL, +}; + +static struct attribute_group cpld_attr_group = { + .attrs = cpld_attrs, +}; + +static int cpld_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct cpld_obj_s *curr_cpld; + + curr_cpld = &g_cpld.cpld[index - 1]; + if (curr_cpld->obj) { + sysfs_remove_group(&curr_cpld->obj->kobj, &cpld_attr_group); + switch_kobject_delete(&curr_cpld->obj); + CPLD_DBG("delete cpld%u dir and attrs success.\n", index); + } + + return 0; +} + +static int cpld_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index) +{ + char name[8]; + struct cpld_obj_s *curr_cpld; + + curr_cpld = &g_cpld.cpld[index - 1]; + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "cpld%u", index); + curr_cpld->obj = switch_kobject_create(name, parent); + if (!curr_cpld->obj) { + CPLD_ERR("create %s object error!\n", name); + return -EBADRQC; + } + curr_cpld->obj->index = index; + if (sysfs_create_group(&curr_cpld->obj->kobj, &cpld_attr_group) != 0) { + CPLD_ERR("create %s attrs error.\n", name); + switch_kobject_delete(&curr_cpld->obj); + return -EBADRQC; + } + CPLD_DBG("create %s dir and attrs success.\n", name); + return 0; +} + +static int cpld_sub_create_kobj_and_attrs(struct kobject *parent, int cpld_num) +{ + unsigned int cpld_index, i; + + g_cpld.cpld = kzalloc(sizeof(struct cpld_obj_s) * cpld_num, GFP_KERNEL); + if (!g_cpld.cpld) { + CPLD_ERR("kzalloc g_cpld.cpld error, cpld number = %d.\n", cpld_num); + return -ENOMEM; + } + + for (cpld_index = 1; cpld_index <= cpld_num; cpld_index++) { + if (cpld_sub_single_create_kobj_and_attrs(parent, cpld_index) != 0) { + goto error; + } + } + return 0; +error: + for (i = cpld_index; i > 0; i--) { + cpld_sub_single_remove_kobj_and_attrs(i); + } + kfree(g_cpld.cpld); + g_cpld.cpld = NULL; + return -EBADRQC; +} + +/* create cpld[1-n] directory and attributes*/ +static int cpld_sub_create(void) +{ + int ret; + + ret = cpld_sub_create_kobj_and_attrs(&g_cpld_obj->kobj, g_cpld.cpld_number); + return ret; +} + +/* delete cpld[1-n] directory and attributes*/ +static void cpld_sub_remove(void) +{ + unsigned int cpld_index; + + if (g_cpld.cpld) { + for (cpld_index = g_cpld.cpld_number; cpld_index > 0; cpld_index--) { + cpld_sub_single_remove_kobj_and_attrs(cpld_index); + } + kfree(g_cpld.cpld); + g_cpld.cpld = NULL; + } + g_cpld.cpld_number = 0; + return; +} + +/* create cpld directory and number attributes */ +static int cpld_root_create(void) +{ + g_cpld_obj = switch_kobject_create("cpld", NULL); + if (!g_cpld_obj) { + CPLD_ERR("switch_kobject_create cpld error!\n"); + return -ENOMEM; + } + + if (sysfs_create_group(&g_cpld_obj->kobj, &cpld_root_attr_group) != 0) { + switch_kobject_delete(&g_cpld_obj); + CPLD_ERR("create cpld dir attrs error!\n"); + return -EBADRQC; + } + return 0; +} + +/* delete cpld directory and number attributes */ +static void cpld_root_remove(void) +{ + if (g_cpld_obj) { + sysfs_remove_group(&g_cpld_obj->kobj, &cpld_root_attr_group); + switch_kobject_delete(&g_cpld_obj); + } + + return; +} + +int s3ip_sysfs_cpld_drivers_register(struct s3ip_sysfs_cpld_drivers_s *drv) +{ + int ret, cpld_num; + + CPLD_INFO("s3ip_sysfs_cpld_drivers_register...\n"); + if (g_cpld_drv) { + CPLD_ERR("g_cpld_drv is not NULL, can't register\n"); + return -EPERM; + } + + check_p(drv); + check_p(drv->get_main_board_cpld_number); + g_cpld_drv = drv; + + cpld_num = g_cpld_drv->get_main_board_cpld_number(); + if (cpld_num <= 0) { + CPLD_ERR("cpld number: %d, don't need to create cpld dirs and attrs.\n", cpld_num); + g_cpld_drv = NULL; + return -EINVAL; + } + + mem_clear(&g_cpld, sizeof(struct cpld_s)); + g_cpld.cpld_number = cpld_num; + ret = cpld_root_create(); + if (ret < 0) { + CPLD_ERR("create cpld root dir and attrs failed, ret: %d\n", ret); + g_cpld_drv = NULL; + return ret; + } + ret = cpld_sub_create(); + if (ret < 0) { + CPLD_ERR("create cpld sub dir and attrs failed, ret: %d\n", ret); + cpld_root_remove(); + g_cpld_drv = NULL; + return ret; + } + CPLD_INFO("s3ip_sysfs_cpld_drivers_register success\n"); + return 0; +} + +void s3ip_sysfs_cpld_drivers_unregister(void) +{ + if (g_cpld_drv) { + cpld_sub_remove(); + cpld_root_remove(); + g_cpld_drv = NULL; + CPLD_DBG("s3ip_sysfs_cpld_drivers_unregister success.\n"); + } + return; +} + +EXPORT_SYMBOL(s3ip_sysfs_cpld_drivers_register); +EXPORT_SYMBOL(s3ip_sysfs_cpld_drivers_unregister); +module_param(g_cpld_loglevel, int, 0644); +MODULE_PARM_DESC(g_cpld_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/curr_sensor_sysfs.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/curr_sensor_sysfs.c new file mode 100644 index 000000000000..3d2e86382ef1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/curr_sensor_sysfs.c @@ -0,0 +1,385 @@ +/* + * An curr_sensor_sysfs driver for current sysfs devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#include "switch.h" +#include "curr_sensor_sysfs.h" + +static int g_curr_sensor_loglevel = 0; + +#define CURR_SENSOR_INFO(fmt, args...) do { \ + if (g_curr_sensor_loglevel & INFO) { \ + printk(KERN_INFO "[CURR_SENSOR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define CURR_SENSOR_ERR(fmt, args...) do { \ + if (g_curr_sensor_loglevel & ERR) { \ + printk(KERN_ERR "[CURR_SENSOR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define CURR_SENSOR_DBG(fmt, args...) do { \ + if (g_curr_sensor_loglevel & DBG) { \ + printk(KERN_DEBUG "[CURR_SENSOR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct curr_sensor_obj_s { + struct switch_obj *obj; +}; + +struct curr_sensor_s { + unsigned int curr_number; + struct curr_sensor_obj_s *curr; +}; + +static struct s3ip_sysfs_curr_sensor_drivers_s *g_curr_sensor_drv = NULL; +static struct curr_sensor_s g_curr_sensor; +static struct switch_obj *g_curr_sensor_obj = NULL; + +static ssize_t curr_sensor_number_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_curr_sensor.curr_number); +} + +static ssize_t curr_sensor_value_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int curr_index; + + check_p(g_curr_sensor_drv); + check_p(g_curr_sensor_drv->get_main_board_curr_value); + + curr_index = obj->index; + CURR_SENSOR_DBG("curr index: %u\n", curr_index); + return g_curr_sensor_drv->get_main_board_curr_value(curr_index, buf, PAGE_SIZE); +} + +static ssize_t curr_sensor_alias_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int curr_index; + + check_p(g_curr_sensor_drv); + check_p(g_curr_sensor_drv->get_main_board_curr_alias); + + curr_index = obj->index; + CURR_SENSOR_DBG("curr index: %u\n", curr_index); + return g_curr_sensor_drv->get_main_board_curr_alias(curr_index, buf, PAGE_SIZE); +} + +static ssize_t curr_sensor_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int curr_index; + + check_p(g_curr_sensor_drv); + check_p(g_curr_sensor_drv->get_main_board_curr_type); + + curr_index = obj->index; + CURR_SENSOR_DBG("curr index: %u\n", curr_index); + return g_curr_sensor_drv->get_main_board_curr_type(curr_index, buf, PAGE_SIZE); +} + +static ssize_t curr_sensor_max_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int curr_index; + + check_p(g_curr_sensor_drv); + check_p(g_curr_sensor_drv->get_main_board_curr_max); + + curr_index = obj->index; + CURR_SENSOR_DBG("curr index: %u\n", curr_index); + return g_curr_sensor_drv->get_main_board_curr_max(curr_index, buf, PAGE_SIZE); +} + +static ssize_t curr_sensor_max_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int curr_index; + int ret; + + check_p(g_curr_sensor_drv); + check_p(g_curr_sensor_drv->set_main_board_curr_max); + + curr_index = obj->index; + CURR_SENSOR_DBG("curr index: %u\n", curr_index); + ret = g_curr_sensor_drv->set_main_board_curr_max(curr_index, buf, count); + if (ret < 0) { + CURR_SENSOR_ERR("set curr%u max threshold failed, value: %s, count: %lu, ret: %d\n", + curr_index, buf, count, ret); + return ret; + } + CURR_SENSOR_DBG("set curr%u max threshold success, value: %s, count: %lu, ret: %d\n", + curr_index, buf, count, ret); + return count; +} + +static ssize_t curr_sensor_min_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int curr_index; + + check_p(g_curr_sensor_drv); + check_p(g_curr_sensor_drv->get_main_board_curr_min); + + curr_index = obj->index; + CURR_SENSOR_DBG("curr index: %u\n", curr_index); + return g_curr_sensor_drv->get_main_board_curr_min(curr_index, buf, PAGE_SIZE); +} + +static ssize_t curr_sensor_min_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int curr_index; + int ret; + + check_p(g_curr_sensor_drv); + check_p(g_curr_sensor_drv->set_main_board_curr_min); + + curr_index = obj->index; + CURR_SENSOR_DBG("curr index: %u\n", curr_index); + ret = g_curr_sensor_drv->set_main_board_curr_min(curr_index, buf, count); + if (ret < 0) { + CURR_SENSOR_ERR("set curr%u min threshold failed, value: %s, count: %lu, ret: %d\n", + curr_index, buf, count, ret); + return ret; + } + CURR_SENSOR_DBG("set curr%u min threshold success, value: %s, count: %lu, ret: %d\n", + curr_index, buf, count, ret); + return count; +} + +static ssize_t curr_sensor_monitor_flag_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int curr_index; + + check_p(g_curr_sensor_drv); + check_p(g_curr_sensor_drv->get_main_board_curr_monitor_flag); + + curr_index = obj->index; + CURR_SENSOR_DBG("curr index: %u\n", curr_index); + return g_curr_sensor_drv->get_main_board_curr_monitor_flag(curr_index, buf, PAGE_SIZE); +} +/************************************curr_sensor dir and attrs*******************************************/ +static struct switch_attribute num_curr_att = __ATTR(number, S_IRUGO, curr_sensor_number_show, NULL); + +static struct attribute *curr_sensor_dir_attrs[] = { + &num_curr_att.attr, + NULL, +}; + +static struct attribute_group curr_sensor_root_attr_group = { + .attrs = curr_sensor_dir_attrs, +}; + +/*******************************curr1 curr2 dir and attrs*******************************************/ +static struct switch_attribute curr_value_attr = __ATTR(value, S_IRUGO, curr_sensor_value_show, NULL); +static struct switch_attribute curr_alias_attr = __ATTR(alias, S_IRUGO, curr_sensor_alias_show, NULL); +static struct switch_attribute curr_type_attr = __ATTR(type, S_IRUGO, curr_sensor_type_show, NULL); +static struct switch_attribute curr_max_attr = __ATTR(max, S_IRUGO | S_IWUSR, curr_sensor_max_show, curr_sensor_max_store); +static struct switch_attribute curr_min_attr = __ATTR(min, S_IRUGO | S_IWUSR, curr_sensor_min_show, curr_sensor_min_store); +static struct switch_attribute curr_monitor_flag_attr = __ATTR(monitor_flag, S_IRUGO, curr_sensor_monitor_flag_show, NULL); + +static struct attribute *curr_sensor_attrs[] = { + &curr_value_attr.attr, + &curr_alias_attr.attr, + &curr_type_attr.attr, + &curr_max_attr.attr, + &curr_min_attr.attr, + &curr_monitor_flag_attr.attr, + NULL, +}; + +static struct attribute_group curr_sensor_attr_group = { + .attrs = curr_sensor_attrs, +}; + +static int curr_sensor_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index) +{ + char name[DIR_NAME_MAX_LEN]; + struct curr_sensor_obj_s *curr_sensor; + + curr_sensor = &g_curr_sensor.curr[index - 1]; + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "curr%u", index); + curr_sensor->obj = switch_kobject_create(name, parent); + if (!curr_sensor->obj) { + CURR_SENSOR_ERR("create %s object error.\n", name); + return -ENOMEM; + } + curr_sensor->obj->index = index; + if (sysfs_create_group(&curr_sensor->obj->kobj, &curr_sensor_attr_group) != 0) { + CURR_SENSOR_ERR("create %s attrs error.\n", name); + switch_kobject_delete(&curr_sensor->obj); + return -EBADRQC; + } + CURR_SENSOR_DBG("create %s dir and attrs success.\n", name); + return 0; +} + +static void curr_sensor_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct curr_sensor_obj_s *curr_sensor; + + curr_sensor = &g_curr_sensor.curr[index - 1]; + if (curr_sensor->obj) { + sysfs_remove_group(&curr_sensor->obj->kobj, &curr_sensor_attr_group); + switch_kobject_delete(&curr_sensor->obj); + CURR_SENSOR_DBG("delete curr%u dir and attrs success.\n", index); + } + + return; +} + +static int curr_sensor_sub_create_kobj_and_attrs(struct kobject *parent, int curr_num) +{ + unsigned int curr_index, i; + + g_curr_sensor.curr = kzalloc(sizeof(struct curr_sensor_obj_s) * curr_num, GFP_KERNEL); + if (!g_curr_sensor.curr) { + CURR_SENSOR_ERR("kzalloc g_curr_sensor.curr error, curr number: %d.\n", curr_num); + return -ENOMEM; + } + + for (curr_index = 1; curr_index <= curr_num; curr_index++) { + if (curr_sensor_sub_single_create_kobj_and_attrs(parent, curr_index) != 0) { + goto error; + } + } + return 0; +error: + for (i = curr_index; i > 0; i--) { + curr_sensor_sub_single_remove_kobj_and_attrs(i); + } + kfree(g_curr_sensor.curr); + g_curr_sensor.curr = NULL; + return -EBADRQC; +} + +/* create curr[1-n] directory and attributes*/ +static int curr_sensor_sub_create(void) +{ + int ret; + + ret = curr_sensor_sub_create_kobj_and_attrs(&g_curr_sensor_obj->kobj, + g_curr_sensor.curr_number); + return ret; +} + +/* delete curr[1-n] directory and attributes*/ +static void curr_sensor_sub_remove(void) +{ + unsigned int curr_index; + + if (g_curr_sensor.curr) { + for (curr_index = g_curr_sensor.curr_number; curr_index > 0; curr_index--) { + curr_sensor_sub_single_remove_kobj_and_attrs(curr_index); + } + kfree(g_curr_sensor.curr); + g_curr_sensor.curr = NULL; + } + g_curr_sensor.curr_number = 0; + return; +} + +/* create curr_sensor directory and number attributes */ +static int curr_sensor_root_create(void) +{ + g_curr_sensor_obj = switch_kobject_create("curr_sensor", NULL); + if (!g_curr_sensor_obj) { + CURR_SENSOR_ERR("switch_kobject_create curr_sensor error!\n"); + return -ENOMEM; + } + + if (sysfs_create_group(&g_curr_sensor_obj->kobj, &curr_sensor_root_attr_group) != 0) { + switch_kobject_delete(&g_curr_sensor_obj); + CURR_SENSOR_ERR("create curr_sensor dir attrs error!\n"); + return -EBADRQC; + } + return 0; +} + +/* delete curr_sensor directory and number attributes */ +static void curr_sensor_root_remove(void) +{ + if (g_curr_sensor_obj) { + sysfs_remove_group(&g_curr_sensor_obj->kobj, &curr_sensor_root_attr_group); + switch_kobject_delete(&g_curr_sensor_obj); + } + + return; +} + +int s3ip_sysfs_curr_sensor_drivers_register(struct s3ip_sysfs_curr_sensor_drivers_s *drv) +{ + int ret, curr_num; + + CURR_SENSOR_INFO("s3ip_sysfs_curr_sensor_drivers_register...\n"); + if (g_curr_sensor_drv) { + CURR_SENSOR_ERR("g_curr_sensor_drv is not NULL, can't register\n"); + return -EPERM; + } + + check_p(drv); + check_p(drv->get_main_board_curr_number); + g_curr_sensor_drv = drv; + + curr_num = g_curr_sensor_drv->get_main_board_curr_number(); + if (curr_num <= 0) { + CURR_SENSOR_ERR("curr sensor number: %d, don't need to create curr_sensor dirs and attrs.\n", + curr_num); + g_curr_sensor_drv = NULL; + return -EINVAL; + } + mem_clear(&g_curr_sensor, sizeof(struct curr_sensor_s)); + g_curr_sensor.curr_number = curr_num; + ret = curr_sensor_root_create(); + if (ret < 0) { + CURR_SENSOR_ERR("create curr_sensor root dir and attrs failed, ret: %d\n", ret); + g_curr_sensor_drv = NULL; + return ret; + } + + ret = curr_sensor_sub_create(); + if (ret < 0) { + CURR_SENSOR_ERR("create curr_sensor sub dir and attrs failed, ret: %d\n", ret); + curr_sensor_root_remove(); + g_curr_sensor_drv = NULL; + return ret; + } + CURR_SENSOR_INFO("s3ip_sysfs_curr_sensor_drivers_register success\n"); + return ret; +} + +void s3ip_sysfs_curr_sensor_drivers_unregister(void) +{ + if (g_curr_sensor_drv) { + curr_sensor_sub_remove(); + curr_sensor_root_remove(); + g_curr_sensor_drv = NULL; + CURR_SENSOR_DBG("s3ip_sysfs_curr_sensor_drivers_unregister success.\n"); + } + return; +} + +EXPORT_SYMBOL(s3ip_sysfs_curr_sensor_drivers_register); +EXPORT_SYMBOL(s3ip_sysfs_curr_sensor_drivers_unregister); +module_param(g_curr_sensor_loglevel, int, 0644); +MODULE_PARM_DESC(g_curr_sensor_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/eeprom_sysfs.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/eeprom_sysfs.c new file mode 100644 index 000000000000..920cbf0bb824 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/eeprom_sysfs.c @@ -0,0 +1,417 @@ +/* + * An eeprom_sysfs driver for eeprom sysfs devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#include "switch.h" +#include "eeprom_sysfs.h" + +static int g_eeprom_loglevel = 0; + +#define EEPROM_INFO(fmt, args...) do { \ + if (g_eeprom_loglevel & INFO) { \ + printk(KERN_INFO "[EEPROM_SYSFS][func:%s line:%d]"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define EEPROM_ERR(fmt, args...) do { \ + if (g_eeprom_loglevel & ERR) { \ + printk(KERN_ERR "[EEPROM_SYSFS][func:%s line:%d]"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define EEPROM_DBG(fmt, args...) do { \ + if (g_eeprom_loglevel & DBG) { \ + printk(KERN_DEBUG "[EEPROM_SYSFS][func:%s line:%d]"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct eeprom_obj_s { + struct switch_obj *eeprom_obj; + struct bin_attribute bin; + int eeprom_creat_bin_flag; +}; + +struct eeprom_s { + unsigned int eeprom_number; + struct eeprom_obj_s *eeprom; +}; + +static struct eeprom_s g_eeprom; +static struct switch_obj *g_eeprom_obj = NULL; +static struct s3ip_sysfs_eeprom_drivers_s *g_eeprom_drv = NULL; + +static ssize_t eeprom_number_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", g_eeprom.eeprom_number); +} + +static ssize_t eeprom_size_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + struct eeprom_obj_s *curr_eeprom; + + EEPROM_DBG("get eeprom size, eeprom index: %u\n", obj->index); + curr_eeprom = &g_eeprom.eeprom[obj->index - 1]; + return (ssize_t)snprintf(buf, PAGE_SIZE, "%ld\n", curr_eeprom->bin.size); +} + +static ssize_t eeprom_alias_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int eeprom_index; + + check_p(g_eeprom_drv); + check_p(g_eeprom_drv->get_eeprom_alias); + + eeprom_index = obj->index; + EEPROM_DBG("get eeprom alias, eeprom index: %u\n", eeprom_index); + return g_eeprom_drv->get_eeprom_alias(eeprom_index, buf, PAGE_SIZE); +} + +static ssize_t eeprom_tag_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int eeprom_index; + + check_p(g_eeprom_drv); + check_p(g_eeprom_drv->get_eeprom_tag); + + eeprom_index = obj->index; + EEPROM_DBG("get eeprom tag, eeprom index: %u\n", eeprom_index); + return g_eeprom_drv->get_eeprom_tag(eeprom_index, buf, PAGE_SIZE); +} + +static ssize_t eeprom_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int eeprom_index; + + check_p(g_eeprom_drv); + check_p(g_eeprom_drv->get_eeprom_type); + + eeprom_index = obj->index; + EEPROM_DBG("get eeprom type, eeprom index: %u\n", eeprom_index); + return g_eeprom_drv->get_eeprom_type(eeprom_index, buf, PAGE_SIZE); +} + +static ssize_t eeprom_eeprom_read(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, + char *buf, loff_t offset, size_t count) +{ + struct switch_obj *eeprom_obj; + ssize_t rd_len; + unsigned int eeprom_index; + + check_p(g_eeprom_drv); + check_p(g_eeprom_drv->read_eeprom_data); + + eeprom_obj = to_switch_obj(kobj); + eeprom_index = eeprom_obj->index; + mem_clear(buf, count); + rd_len = g_eeprom_drv->read_eeprom_data(eeprom_index, buf, offset, count); + if (rd_len < 0) { + EEPROM_ERR("read eeprom%u eeprom data error, offset: 0x%llx, read len: %lu, ret: %ld.\n", + eeprom_index, offset, count, rd_len); + return rd_len; + } + + EEPROM_DBG("read eeprom%u eeprom data success, offset:0x%llx, read len:%lu, really read len:%ld.\n", + eeprom_index, offset, count, rd_len); + + return rd_len; +} + +static ssize_t eeprom_eeprom_write(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, + char *buf, loff_t offset, size_t count) +{ + struct switch_obj *eeprom_obj; + ssize_t wr_len; + unsigned int eeprom_index; + + check_p(g_eeprom_drv); + check_p(g_eeprom_drv->write_eeprom_data); + + eeprom_obj = to_switch_obj(kobj); + eeprom_index = eeprom_obj->index; + wr_len = g_eeprom_drv->write_eeprom_data(eeprom_index, buf, offset, count); + if (wr_len < 0) { + EEPROM_ERR("write eeprom%u eeprom data error, offset: 0x%llx, read len: %lu, ret: %ld.\n", + eeprom_index, offset, count, wr_len); + return wr_len; + } + + EEPROM_DBG("write eeprom%u eeprom data success, offset:0x%llx, write len:%lu, really write len:%ld.\n", + eeprom_index, offset, count, wr_len); + + return wr_len; +} + +/************************************eeprom* signal attrs*******************************************/ +static struct switch_attribute eeprom_alias_attr = __ATTR(alias, S_IRUGO | S_IWUSR, eeprom_alias_show, NULL); +static struct switch_attribute eeprom_tag_attr = __ATTR(tag, S_IRUGO | S_IWUSR, eeprom_tag_show, NULL); +static struct switch_attribute eeprom_size_attr = __ATTR(size, S_IRUGO, eeprom_size_show, NULL); +static struct switch_attribute eeprom_type_attr = __ATTR(type, S_IRUGO | S_IWUSR, eeprom_type_show, NULL); + +static struct attribute *eeprom_signal_attrs[] = { + &eeprom_alias_attr.attr, + &eeprom_tag_attr.attr, + &eeprom_size_attr.attr, + &eeprom_type_attr.attr, + NULL, +}; + +static struct attribute_group eeprom_signal_attr_group = { + .attrs = eeprom_signal_attrs, +}; + +/*******************************eeprom dir and attrs*******************************************/ +static struct switch_attribute eeprom_number_attr = __ATTR(number, S_IRUGO, eeprom_number_show, NULL); + +static struct attribute *eeprom_dir_attrs[] = { + &eeprom_number_attr.attr, + NULL, +}; + +static struct attribute_group eeprom_eeprom_attr_group = { + .attrs = eeprom_dir_attrs, +}; + +/* create eeprom* eeprom attributes */ +static int eeprom_sub_single_create_eeprom_attrs(unsigned int index) +{ + int ret, eeprom_size; + struct eeprom_obj_s *curr_eeprom; + + check_p(g_eeprom_drv->get_eeprom_size); + eeprom_size = g_eeprom_drv->get_eeprom_size(index); + if (eeprom_size <= 0) { + EEPROM_ERR("Invalid eeprom size, eeprom index: %u, eeprom_size: %d\n", + index, eeprom_size); + return -EINVAL; + } + + curr_eeprom = &g_eeprom.eeprom[index - 1]; + sysfs_bin_attr_init(&curr_eeprom->bin); + curr_eeprom->bin.attr.name = "data"; + curr_eeprom->bin.attr.mode = 0644; + curr_eeprom->bin.read = eeprom_eeprom_read; + curr_eeprom->bin.write = eeprom_eeprom_write; + curr_eeprom->bin.size = eeprom_size; + + ret = sysfs_create_bin_file(&curr_eeprom->eeprom_obj->kobj, &curr_eeprom->bin); + if (ret) { + EEPROM_ERR("eeprom%u, create eeprom bin error, ret: %d. \n", index, ret); + return -EBADRQC; + } + + EEPROM_DBG("eeprom%u, create bin file success, eeprom size: %d.\n", index, eeprom_size); + curr_eeprom->eeprom_creat_bin_flag = 1; + return 0; +} + +static int eeprom_sub_single_create_kobj(struct kobject *parent, unsigned int index) +{ + struct eeprom_obj_s *curr_eeprom; + char eeprom_dir_name[DIR_NAME_MAX_LEN]; + + curr_eeprom = &g_eeprom.eeprom[index - 1]; + mem_clear(eeprom_dir_name, sizeof(eeprom_dir_name)); + snprintf(eeprom_dir_name, sizeof(eeprom_dir_name), "eeprom%d", index); + curr_eeprom->eeprom_obj = switch_kobject_create(eeprom_dir_name, parent); + if (!curr_eeprom->eeprom_obj) { + EEPROM_ERR("create eeprom%d object error! \n", index); + return -EBADRQC; + } + curr_eeprom->eeprom_obj->index = index; + if (sysfs_create_group(&curr_eeprom->eeprom_obj->kobj, &eeprom_signal_attr_group) != 0) { + switch_kobject_delete(&curr_eeprom->eeprom_obj); + return -EBADRQC; + } + + EEPROM_DBG("create eeprom%d dir and attrs success\n", index); + return 0; +} + +/* remove eeprom directory and attributes */ +static void eeprom_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct eeprom_obj_s *curr_eeprom; + + curr_eeprom = &g_eeprom.eeprom[index - 1]; + if (curr_eeprom->eeprom_obj) { + if (curr_eeprom->eeprom_creat_bin_flag) { + sysfs_remove_bin_file(&curr_eeprom->eeprom_obj->kobj, &curr_eeprom->bin); + curr_eeprom->eeprom_creat_bin_flag = 0; + } + sysfs_remove_group(&curr_eeprom->eeprom_obj->kobj, &eeprom_signal_attr_group); + switch_kobject_delete(&curr_eeprom->eeprom_obj); + } + + return; +} + +static int eeprom_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index) +{ + int ret; + + ret = eeprom_sub_single_create_kobj(parent, index); + if (ret < 0) { + EEPROM_ERR("create eeprom%d dir error.\n", index); + return ret; + } + + ret = eeprom_sub_single_create_eeprom_attrs(index); + if (ret < 0) { + eeprom_sub_single_remove_kobj_and_attrs(index); + EEPROM_ERR("create eeprom%d data error.\n", index); + return ret; + } + return 0; +} + +static int eeprom_sub_create_kobj_and_attrs(struct kobject *parent, int eeprom_num) +{ + unsigned int eeprom_index, i; + + g_eeprom.eeprom = kzalloc(sizeof(struct eeprom_obj_s) * eeprom_num, GFP_KERNEL); + if (!g_eeprom.eeprom) { + EEPROM_ERR("kzalloc g_eeprom.eeprom error, eeprom number = %d.\n", eeprom_num); + return -ENOMEM; + } + + for (eeprom_index = 1; eeprom_index <= eeprom_num; eeprom_index++) { + if (eeprom_sub_single_create_kobj_and_attrs(parent, eeprom_index) != 0) { + goto error; + } + } + return 0; +error: + for (i = eeprom_index; i > 0; i--) { + eeprom_sub_single_remove_kobj_and_attrs(i); + } + kfree(g_eeprom.eeprom); + g_eeprom.eeprom = NULL; + return -EBADRQC; +} + +/* create eeprom directory and attributes */ +static int eeprom_sub_create(void) +{ + int ret; + + ret = eeprom_sub_create_kobj_and_attrs(&g_eeprom_obj->kobj, g_eeprom.eeprom_number); + return ret; +} + +/* delete eeprom directory and attributes */ +static void eeprom_sub_remove(void) +{ + unsigned int eeprom_index; + + if (g_eeprom.eeprom) { + for (eeprom_index = g_eeprom.eeprom_number; eeprom_index > 0; eeprom_index--) { + eeprom_sub_single_remove_kobj_and_attrs(eeprom_index); + } + kfree(g_eeprom.eeprom); + g_eeprom.eeprom = NULL; + } + g_eeprom.eeprom_number = 0; + return; +} + +/* create eeprom directory and attributes */ +static int eeprom_eeprom_create(void) +{ + g_eeprom_obj = switch_kobject_create("eeprom", NULL); + if (!g_eeprom_obj) { + EEPROM_ERR("switch_kobject_create eeprom error!\n"); + return -ENOMEM; + } + g_eeprom_obj->index = 0; + if (sysfs_create_group(&g_eeprom_obj->kobj, &eeprom_eeprom_attr_group) != 0) { + switch_kobject_delete(&g_eeprom_obj); + EEPROM_ERR("create eeprom dir attrs error!\n"); + return -EBADRQC; + } + return 0; +} + +/* delete eeprom directory and attributes */ +static void eeprom_eeprom_remove(void) +{ + if (g_eeprom_obj) { + sysfs_remove_group(&g_eeprom_obj->kobj, &eeprom_eeprom_attr_group); + switch_kobject_delete(&g_eeprom_obj); + } + + return; +} + +int s3ip_sysfs_eeprom_drivers_register(struct s3ip_sysfs_eeprom_drivers_s *drv) +{ + int ret, eeprom_num; + + EEPROM_INFO("s3ip_sysfs_eeprom_drivers_register...\n"); + if (g_eeprom_drv) { + EEPROM_ERR("g_eeprom_drv is not NULL, can't register\n"); + return -EPERM; + } + + check_p(drv); + check_p(drv->get_eeprom_number); + g_eeprom_drv = drv; + + eeprom_num = g_eeprom_drv->get_eeprom_number(); + if (eeprom_num <= 0) { + EEPROM_ERR("eeprom number: %d, don't need to create eeprom dirs and attrs.\n", eeprom_num); + g_eeprom_drv = NULL; + return -EINVAL; + } + + mem_clear(&g_eeprom, sizeof(struct eeprom_s)); + g_eeprom.eeprom_number = eeprom_num; + ret = eeprom_eeprom_create(); + if (ret < 0) { + EEPROM_ERR("create eeprom root dir and attrs failed, ret: %d\n", ret); + g_eeprom_drv = NULL; + return ret; + } + ret = eeprom_sub_create(); + if (ret < 0) { + EEPROM_ERR("create eeprom sub dir and attrs failed, ret: %d\n", ret); + eeprom_eeprom_remove(); + g_eeprom_drv = NULL; + return ret; + } + EEPROM_INFO("s3ip_sysfs_eeprom_drivers_register success\n"); + return ret; +} + +void s3ip_sysfs_eeprom_drivers_unregister(void) +{ + if (g_eeprom_drv) { + eeprom_sub_remove(); + eeprom_eeprom_remove(); + g_eeprom_drv = NULL; + EEPROM_DBG("s3ip_sysfs_eeprom_drivers_unregister success.\n"); + } + return; +} + +EXPORT_SYMBOL(s3ip_sysfs_eeprom_drivers_register); +EXPORT_SYMBOL(s3ip_sysfs_eeprom_drivers_unregister); +module_param(g_eeprom_loglevel, int, 0644); +MODULE_PARM_DESC(g_eeprom_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/fan_sysfs.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/fan_sysfs.c new file mode 100644 index 000000000000..e1b9b56d3ab5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/fan_sysfs.c @@ -0,0 +1,777 @@ +/* + * An fan_sysfs driver for fan sysfs devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#include "switch.h" +#include "fan_sysfs.h" + +static int g_fan_loglevel = 0; +static bool g_fan_status_debug = 0; + +#define FAN_INFO(fmt, args...) do { \ + if (g_fan_loglevel & INFO) { \ + printk(KERN_INFO "[FAN_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define FAN_ERR(fmt, args...) do { \ + if (g_fan_loglevel & ERR) { \ + printk(KERN_ERR "[FAN_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define FAN_DBG(fmt, args...) do { \ + if (g_fan_loglevel & DBG) { \ + printk(KERN_DEBUG "[FAN_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct motor_obj_s { + struct switch_obj *obj; +}; + +struct fan_obj_s { + unsigned int motor_number; + struct motor_obj_s *motor; + struct switch_obj *obj; +}; + +struct fan_s { + unsigned int fan_number; + struct fan_obj_s *fan; +}; + +static struct fan_s g_fan; +static struct switch_obj *g_fan_obj = NULL; +static struct s3ip_sysfs_fan_drivers_s *g_fan_drv = NULL; + +static ssize_t fan_number_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", g_fan.fan_number); +} + +static ssize_t fan_motor_number_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int index; + + index = obj->index; + FAN_DBG("fan_motor_number_show, fan index: %u\n", index); + + return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_fan.fan[index - 1].motor_number); +} + +static ssize_t fan_model_name_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int fan_index; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_model_name); + + fan_index = obj->index; + FAN_DBG("fan index: %u\n", fan_index); + return g_fan_drv->get_fan_model_name(fan_index, buf, PAGE_SIZE); +} + +static ssize_t fan_vendor_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int fan_index; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_vendor); + + fan_index = obj->index; + FAN_DBG("fan index: %u\n", fan_index); + return g_fan_drv->get_fan_vendor(fan_index, buf, PAGE_SIZE); +} + +static ssize_t fan_sn_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int fan_index; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_serial_number); + + fan_index = obj->index; + FAN_DBG("fan index: %u\n", fan_index); + return g_fan_drv->get_fan_serial_number(fan_index, buf, PAGE_SIZE); +} + +static ssize_t fan_pn_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int fan_index; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_part_number); + + fan_index = obj->index; + FAN_DBG("fan index: %u\n", fan_index); + return g_fan_drv->get_fan_part_number(fan_index, buf, PAGE_SIZE); +} + +static ssize_t fan_hw_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int fan_index; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_hardware_version); + + fan_index = obj->index; + FAN_DBG("fan index: %u\n", fan_index); + return g_fan_drv->get_fan_hardware_version(fan_index, buf, PAGE_SIZE); +} + +static ssize_t fan_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int fan_index; + int ret, res; + char debug_file_buf[DEBUG_FILE_SIZE]; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_status); + + fan_index = obj->index; + FAN_DBG("fan index: %u\n", fan_index); + ret = g_fan_drv->get_fan_status(fan_index, buf, PAGE_SIZE); + if (ret < 0) { + FAN_ERR("get fan%u status failed, ret: %d\n", fan_index, ret); + return ret; + } + + if (g_fan_status_debug) { + FAN_INFO("s3ip sysfs fan status debug is enable\n"); + + if ((strncmp(buf, SWITCH_DEV_NO_SUPPORT, strlen(SWITCH_DEV_NO_SUPPORT)) == 0) || (strncmp(buf, SWITCH_DEV_ERROR, strlen(SWITCH_DEV_ERROR)) == 0)) { + FAN_DBG("fan%d status sysfs unsupport or error\n", fan_index); + return ret; + } + + if (strcmp(buf, FAN_ABSENT_STR) == 0) { + FAN_DBG("fan%d absent, return act value\n", fan_index); + return ret; + } + + mem_clear(debug_file_buf, sizeof(debug_file_buf)); + res = dev_debug_file_read(SINGLE_FAN_STATUS_DEBUG_FILE, fan_index, debug_file_buf, sizeof(debug_file_buf)); + if (res) { + FAN_ERR("fan%u status debug file read failed, ret: %d\n", fan_index, res); + return ret; + } + + if ((strcmp(debug_file_buf, FAN_ABSENT_STR) == 0) || (strcmp(debug_file_buf, FAN_OK_STR) == 0) || (strcmp(debug_file_buf, FAN_NOTOK_STR) == 0)) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s", debug_file_buf); + } else { + FAN_ERR("fan%d status debug file value err, value: %s, not 0 1 or 2\n", fan_index, debug_file_buf); + return ret; + } + } + return ret; +} + +static ssize_t fan_present_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int fan_index; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_present); + + fan_index = obj->index; + FAN_DBG("fan index: %u\n", fan_index); + return g_fan_drv->get_fan_present(fan_index, buf, PAGE_SIZE); +} + +static ssize_t fan_led_status_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int fan_index; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_led_status); + + fan_index = obj->index; + FAN_DBG("fan index: %u\n", fan_index); + return g_fan_drv->get_fan_led_status(fan_index, buf, PAGE_SIZE); +} + +static ssize_t fan_led_status_store(struct switch_obj *obj, struct switch_attribute *attr, + const char *buf, size_t count) +{ + unsigned int fan_index; + int ret, led_status; + + check_p(g_fan_drv); + check_p(g_fan_drv->set_fan_led_status); + + fan_index = obj->index; + ret = kstrtoint(buf, 0, &led_status); + if (ret != 0) { + FAN_ERR("invaild fan led status ret: %d, buf: %s.\n", ret, buf); + return -EINVAL; + } + FAN_DBG("fan index: %u, led_status: %d\n", fan_index, led_status); + ret = g_fan_drv->set_fan_led_status(fan_index, led_status); + if (ret < 0) { + FAN_ERR("set fan%u led_status: %d failed, ret: %d\n", fan_index, led_status, ret); + return ret; + } + FAN_DBG("set fan%u led_status: %d success\n", fan_index, led_status); + return count; +} + +static ssize_t fan_motor_status_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int fan_index, motor_index; + struct switch_obj *p_obj; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_motor_status); + + p_obj = to_switch_obj(obj->kobj.parent); + fan_index = p_obj->index; + motor_index = obj->index; + FAN_DBG("fan index: %u, motor index: %d\n", fan_index, motor_index); + return g_fan_drv->get_fan_motor_status(fan_index, motor_index, buf, PAGE_SIZE); +} + +static ssize_t fan_motor_speed_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int fan_index, motor_index; + struct switch_obj *p_obj; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_motor_speed); + + p_obj = to_switch_obj(obj->kobj.parent); + fan_index = p_obj->index; + motor_index = obj->index; + FAN_DBG("fan index: %u, motor index: %d\n", fan_index, motor_index); + return g_fan_drv->get_fan_motor_speed(fan_index, motor_index, buf, PAGE_SIZE); +} + +static ssize_t fan_motor_speed_tolerance_show(struct switch_obj *obj, + struct switch_attribute *attr, char *buf) +{ + unsigned int fan_index, motor_index; + struct switch_obj *p_obj; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_motor_speed_tolerance); + + p_obj = to_switch_obj(obj->kobj.parent); + fan_index = p_obj->index; + motor_index = obj->index; + FAN_DBG("fan index: %u, motor index: %d\n", fan_index, motor_index); + return g_fan_drv->get_fan_motor_speed_tolerance(fan_index, motor_index, buf, PAGE_SIZE); +} + +static ssize_t fan_motor_speed_target_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int fan_index, motor_index; + struct switch_obj *p_obj; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_motor_speed_target); + + p_obj = to_switch_obj(obj->kobj.parent); + fan_index = p_obj->index; + motor_index = obj->index; + FAN_DBG("fan index: %u, motor index: %d\n", fan_index, motor_index); + return g_fan_drv->get_fan_motor_speed_target(fan_index, motor_index, buf, PAGE_SIZE); +} + +static ssize_t fan_motor_speed_max_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int fan_index, motor_index; + struct switch_obj *p_obj; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_motor_speed_max); + + p_obj = to_switch_obj(obj->kobj.parent); + fan_index = p_obj->index; + motor_index = obj->index; + FAN_DBG("fan index: %u, motor index: %d\n", fan_index, motor_index); + return g_fan_drv->get_fan_motor_speed_max(fan_index, motor_index, buf, PAGE_SIZE); +} + +static ssize_t fan_motor_speed_min_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int fan_index, motor_index; + struct switch_obj *p_obj; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_motor_speed_min); + + p_obj = to_switch_obj(obj->kobj.parent); + fan_index = p_obj->index; + motor_index = obj->index; + FAN_DBG("fan index: %u, motor index: %d\n", fan_index, motor_index); + return g_fan_drv->get_fan_motor_speed_min(fan_index, motor_index, buf, PAGE_SIZE); +} + +ssize_t fan_ratio_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int fan_index; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_ratio); + + fan_index = obj->index; + FAN_DBG("fan index: %u\n", fan_index); + return g_fan_drv->get_fan_ratio(fan_index, buf, PAGE_SIZE); +} + +static ssize_t fan_ratio_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int fan_index; + int ret, ratio; + + check_p(g_fan_drv); + check_p(g_fan_drv->set_fan_ratio); + + fan_index = obj->index; + + ret = kstrtoint(buf, 0, &ratio); + if (ret != 0) { + FAN_ERR("invaild fan ratio ret: %d, buf: %s.\n", ret, buf); + return -EINVAL; + } + + if (ratio < 0 || ratio > 100) { + FAN_ERR("param invalid, can not set ratio: %d.\n", ratio); + return -EINVAL; + } + FAN_DBG("fan index: %u, ratio: %d\n", fan_index, ratio); + ret = g_fan_drv->set_fan_ratio(fan_index, ratio); + if (ret < 0) { + FAN_ERR("set fan%u ratio: %d failed, ret: %d\n", fan_index, ratio, ret); + return ret; + } + FAN_DBG("set fan%u, ratio: %d success\n", fan_index, ratio); + return count; +} + +ssize_t fan_direction_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int fan_index; + + check_p(g_fan_drv); + check_p(g_fan_drv->get_fan_direction); + + fan_index = obj->index; + FAN_DBG("fan index: %u\n", fan_index); + return g_fan_drv->get_fan_direction(fan_index, buf, PAGE_SIZE); +} + +/************************************fan dir and attrs*******************************************/ +static struct switch_attribute fan_number_att = __ATTR(number, S_IRUGO, fan_number_show, NULL); + +static struct attribute *fan_dir_attrs[] = { + &fan_number_att.attr, + NULL, +}; + +static struct attribute_group fan_root_attr_group = { + .attrs = fan_dir_attrs, +}; + +/*******************************fan1 fan2 dir and attrs*******************************************/ +static struct switch_attribute fan_model_name_attr = __ATTR(model_name, S_IRUGO, fan_model_name_show, NULL); +static struct switch_attribute fan_vendor_attr = __ATTR(vendor, S_IRUGO, fan_vendor_show, NULL); +static struct switch_attribute fan_sn_attr = __ATTR(serial_number, S_IRUGO, fan_sn_show, NULL); +static struct switch_attribute fan_pn_attr = __ATTR(part_number, S_IRUGO, fan_pn_show, NULL); +static struct switch_attribute fan_hw_attr = __ATTR(hardware_version, S_IRUGO, fan_hw_show, NULL); +static struct switch_attribute fan_num_motors_attr = __ATTR(motor_number, S_IRUGO, fan_motor_number_show, NULL); +static struct switch_attribute fan_status_attr = __ATTR(status, S_IRUGO, fan_status_show, NULL); +static struct switch_attribute fan_present_attr = __ATTR(present, S_IRUGO, fan_present_show, NULL); +static struct switch_attribute fan_led_status_attr = __ATTR(led_status, S_IRUGO | S_IWUSR, fan_led_status_show, fan_led_status_store); +static struct switch_attribute fan_direction_attr = __ATTR(direction, S_IRUGO, fan_direction_show, NULL); +static struct switch_attribute fan_ratio_attr = __ATTR(ratio, S_IRUGO | S_IWUSR, fan_ratio_show, fan_ratio_store); + +static struct attribute *fan_attrs[] = { + &fan_model_name_attr.attr, + &fan_vendor_attr.attr, + &fan_sn_attr.attr, + &fan_pn_attr.attr, + &fan_hw_attr.attr, + &fan_num_motors_attr.attr, + &fan_status_attr.attr, + &fan_present_attr.attr, + &fan_led_status_attr.attr, + &fan_direction_attr.attr, + &fan_ratio_attr.attr, + NULL, +}; + +static struct attribute_group fan_attr_group = { + .attrs = fan_attrs, +}; + +/*******************************motor1 motor2 dir and attrs*******************************************/ +static struct switch_attribute motor_status_attr = __ATTR(status, S_IRUGO, fan_motor_status_show, NULL); +static struct switch_attribute motor_speed_attr = __ATTR(speed, S_IRUGO, fan_motor_speed_show, NULL); +static struct switch_attribute motor_speed_tolerance_attr = __ATTR(speed_tolerance, S_IRUGO, fan_motor_speed_tolerance_show, NULL); +static struct switch_attribute motor_speed_target_attr = __ATTR(speed_target, S_IRUGO, fan_motor_speed_target_show, NULL); +static struct switch_attribute motor_speed_max_attr = __ATTR(speed_max, S_IRUGO, fan_motor_speed_max_show, NULL); +static struct switch_attribute motor_speed_min_attr = __ATTR(speed_min, S_IRUGO, fan_motor_speed_min_show, NULL); + +static struct attribute *motor_attrs[] = { + &motor_status_attr.attr, + &motor_speed_attr.attr, + &motor_speed_tolerance_attr.attr, + &motor_speed_target_attr.attr, + &motor_speed_max_attr.attr, + &motor_speed_min_attr.attr, + NULL, +}; + +static struct attribute_group motor_attr_group = { + .attrs = motor_attrs, +}; + +static void fanindex_single_motor_remove_kobj_and_attrs(struct fan_obj_s *curr_fan, unsigned int motor_index) +{ + struct motor_obj_s *curr_motor; /* point to motor1 motor2...*/ + + curr_motor = &curr_fan->motor[motor_index - 1]; + if (curr_motor->obj) { + sysfs_remove_group(&curr_motor->obj->kobj, &motor_attr_group); + switch_kobject_delete(&curr_motor->obj); + FAN_DBG("delete fan%u motor%u dir and attrs success.\n", curr_fan->obj->index, + motor_index); + } + return; +} + +static int fanindex_single_motor_create_kobj_and_attrs(struct fan_obj_s *curr_fan, unsigned int motor_index) +{ + char name[8]; + struct motor_obj_s *curr_motor; /* point to motor1 motor2...*/ + + curr_motor = &curr_fan->motor[motor_index - 1]; + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "motor%u", motor_index); + curr_motor->obj = switch_kobject_create(name, &curr_fan->obj->kobj); + if (!curr_motor->obj) { + FAN_ERR("create fan%u, motor%u object error!\n", curr_fan->obj->index, motor_index); + return -ENOMEM; + } + + curr_motor->obj->index = motor_index; + if (sysfs_create_group(&curr_motor->obj->kobj, &motor_attr_group) != 0) { + FAN_ERR("create fan%u, motor%u attrs error.\n", curr_fan->obj->index, motor_index); + switch_kobject_delete(&curr_motor->obj); + return -EBADRQC; + } + FAN_DBG("create fan%u, motor%u dir and attrs success.\n", curr_fan->obj->index, motor_index); + return 0; +} + +/* create motor[1-n] directory and attributes in fan directory */ +static int fanindex_motor_create_kobj_and_attrs(struct fan_obj_s *curr_fan) +{ + unsigned int motor_index, i, motor_num; + + motor_num = curr_fan->motor_number; + curr_fan->motor = kzalloc(sizeof(struct motor_obj_s) * motor_num, GFP_KERNEL); + if (!curr_fan->motor) { + FAN_ERR("kzalloc motor error, fan index: %u, motor number: %d.\n", + curr_fan->obj->index, motor_num); + return -ENOMEM; + } + for (motor_index = 1; motor_index <= motor_num; motor_index++) { + if (fanindex_single_motor_create_kobj_and_attrs(curr_fan, motor_index) != 0) { + goto motor_error; + } + } + return 0; +motor_error: + for (i = motor_index; i > 0; i--) { + fanindex_single_motor_remove_kobj_and_attrs(curr_fan, i); + } + kfree(curr_fan->motor); + curr_fan->motor = NULL; + return -EBADRQC; +} + +/* delete motor[1-n] directory and attributes in fan directory */ +static void fanindex_motor_remove_kobj_and_attrs(struct fan_obj_s *curr_fan) +{ + unsigned int motor_index, motor_num; + + if (curr_fan->motor) { + motor_num = curr_fan->motor_number; + for (motor_index = motor_num; motor_index > 0; motor_index--) { + fanindex_single_motor_remove_kobj_and_attrs(curr_fan, motor_index); + } + kfree(curr_fan->motor); + curr_fan->motor = NULL; + } + + return; +} + +/* create motor[1-n] directory and attributes */ +static int fan_motor_create(void) +{ + int fan_num, motor_num; + unsigned int fan_index, i; + struct fan_obj_s *curr_fan; /* point to fan1 fan2...*/ + + fan_num = g_fan.fan_number; + if (fan_num <= 0) { + FAN_DBG("fan number: %d, skip to create motor* dirs and attrs.\n", fan_num); + return 0; + } + + check_p(g_fan_drv->get_fan_motor_number); + + for (fan_index = 1; fan_index <= fan_num; fan_index++) { + motor_num = g_fan_drv->get_fan_motor_number(fan_index); + if (motor_num <= 0) { + FAN_DBG("fan%u motor number: %d, don't need to create motor* dirs and attrs.\n", + fan_index, motor_num); + continue; + } + curr_fan = &g_fan.fan[fan_index - 1]; + curr_fan->motor_number = motor_num; + if (fanindex_motor_create_kobj_and_attrs(curr_fan) != 0) { + goto error; + } + } + return 0; +error: + for (i = fan_index; i > 0; i--) { + curr_fan = &g_fan.fan[i - 1]; + fanindex_motor_remove_kobj_and_attrs(curr_fan); + } + return -EBADRQC; +} + +/* delete motor[1-n] directory and attributes */ +static void fan_motor_remove(void) +{ + unsigned int fan_index; + struct fan_obj_s *curr_fan; + + if (g_fan.fan) { + for (fan_index = g_fan.fan_number; fan_index > 0; fan_index--) { + curr_fan = &g_fan.fan[fan_index - 1]; + fanindex_motor_remove_kobj_and_attrs(curr_fan); + curr_fan->motor_number = 0; + } + } + return; +} + +static int fan_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct fan_obj_s *curr_fan; + + curr_fan = &g_fan.fan[index - 1]; + if (curr_fan->obj) { + sysfs_remove_group(&curr_fan->obj->kobj, &fan_attr_group); + switch_kobject_delete(&curr_fan->obj); + FAN_DBG("delete fan%u dir and attrs success.\n", index); + } + return 0; +} + +static int fan_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index) +{ + char name[8]; + struct fan_obj_s *curr_fan; + + curr_fan = &g_fan.fan[index - 1]; + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "fan%u", index); + curr_fan->obj = switch_kobject_create(name, parent); + if (!curr_fan->obj) { + FAN_ERR("create %s object error!\n", name); + return -ENOMEM; + } + + curr_fan->obj->index = index; + if (sysfs_create_group(&curr_fan->obj->kobj, &fan_attr_group) != 0) { + FAN_ERR("create %s attrs error.\n", name); + switch_kobject_delete(&curr_fan->obj); + return -EBADRQC; + } + FAN_DBG("create %s dir and attrs success.\n", name); + return 0; +} + +/* create fan[1-n] directory and attributes */ +static int fan_sub_create_kobj_and_attrs(struct kobject *parent, int fan_num) +{ + unsigned int fan_index, i; + + g_fan.fan = kzalloc(sizeof(struct fan_obj_s) * fan_num, GFP_KERNEL); + if (!g_fan.fan) { + FAN_ERR("kzalloc fan.fan error, fan number: %d.\n", fan_num); + return -ENOMEM; + } + + for (fan_index = 1; fan_index <= fan_num; fan_index++) { + if (fan_sub_single_create_kobj_and_attrs(parent, fan_index) != 0) { + goto error; + } + } + return 0; +error: + for (i = fan_index; i > 0; i--) { + fan_sub_single_remove_kobj_and_attrs(i); + } + kfree(g_fan.fan); + g_fan.fan = NULL; + return -EBADRQC; +} + +static int fan_sub_create(void) +{ + int ret; + + ret = fan_sub_create_kobj_and_attrs(&g_fan_obj->kobj, g_fan.fan_number); + return ret; +} + +/* delete fan[1-n] directory and attributes */ +static void fan_sub_remove(void) +{ + unsigned int fan_index; + + if (g_fan.fan) { + for (fan_index = g_fan.fan_number; fan_index > 0; fan_index--) { + fan_sub_single_remove_kobj_and_attrs(fan_index); + } + kfree(g_fan.fan); + g_fan.fan = NULL; + } + g_fan.fan_number = 0; + + return; +} + +/* create fan directory and number attributes */ +static int fan_root_create(void) +{ + g_fan_obj = switch_kobject_create("fan", NULL); + if (!g_fan_obj) { + FAN_ERR("switch_kobject_create fan error!\n"); + return -ENOMEM; + } + + if (sysfs_create_group(&g_fan_obj->kobj, &fan_root_attr_group) != 0) { + switch_kobject_delete(&g_fan_obj); + FAN_ERR("create fan dir attrs error!\n"); + return -EBADRQC; + } + return 0; +} + +/* delete fan directory and number attributes */ +static void fan_root_remove(void) +{ + if (g_fan_obj) { + sysfs_remove_group(&g_fan_obj->kobj, &fan_root_attr_group); + switch_kobject_delete(&g_fan_obj); + FAN_DBG("delete fan dir and attrs success.\n"); + } + return; +} + +int s3ip_sysfs_fan_drivers_register(struct s3ip_sysfs_fan_drivers_s *drv) +{ + int ret, fan_num; + + FAN_INFO("s3ip_sysfs_fan_drivers_register...\n"); + if (g_fan_drv) { + FAN_ERR("g_fan_drv is not NULL, can't register\n"); + return -EPERM; + } + + check_p(drv); + check_p(drv->get_fan_number); + g_fan_drv = drv; + + fan_num = g_fan_drv->get_fan_number(); + if (fan_num <= 0) { + FAN_ERR("fan number: %d, don't need to create fan dirs and attrs.\n", fan_num); + g_fan_drv = NULL; + return -EINVAL; + } + + mem_clear(&g_fan, sizeof(struct fan_s)); + g_fan.fan_number = fan_num; + ret = fan_root_create(); + if (ret < 0) { + FAN_ERR("create fan root dir and attrs failed, ret: %d\n", ret); + g_fan_drv = NULL; + return ret; + } + + ret = fan_sub_create(); + if (ret < 0) { + FAN_ERR("create fan sub dir and attrs failed, ret: %d\n", ret); + fan_root_remove(); + g_fan_drv = NULL; + return ret; + } + + ret = fan_motor_create(); + if (ret < 0) { + FAN_ERR("create fan motor dir and attrs failed, ret: %d\n", ret); + fan_sub_remove(); + fan_root_remove(); + g_fan_drv = NULL; + return ret; + } + FAN_INFO("s3ip_sysfs_fan_drivers_register success.\n"); + return 0; +} + +void s3ip_sysfs_fan_drivers_unregister(void) +{ + if (g_fan_drv) { + fan_motor_remove(); + fan_sub_remove(); + fan_root_remove(); + g_fan_drv = NULL; + FAN_DBG("s3ip_sysfs_fan_drivers_unregister success.\n"); + } + return; +} + +EXPORT_SYMBOL(s3ip_sysfs_fan_drivers_register); +EXPORT_SYMBOL(s3ip_sysfs_fan_drivers_unregister); +module_param(g_fan_loglevel, int, 0644); +MODULE_PARM_DESC(g_fan_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); +module_param(g_fan_status_debug, bool, 0644); +MODULE_PARM_DESC(g_fan_status_debug, "the fan present debug switch(0: disable, 1:enable, defalut: 0).\n"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/fpga_sysfs.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/fpga_sysfs.c new file mode 100644 index 000000000000..d0ec8dfc62f7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/fpga_sysfs.c @@ -0,0 +1,345 @@ +/* + * An fpga_sysfs driver for fpga sysfs devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#include "switch.h" +#include "fpga_sysfs.h" + +static int g_fpga_loglevel = 0; + +#define FPGA_INFO(fmt, args...) do { \ + if (g_fpga_loglevel & INFO) { \ + printk(KERN_INFO "[FPGA_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define FPGA_ERR(fmt, args...) do { \ + if (g_fpga_loglevel & ERR) { \ + printk(KERN_ERR "[FPGA_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define FPGA_DBG(fmt, args...) do { \ + if (g_fpga_loglevel & DBG) { \ + printk(KERN_DEBUG "[FPGA_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct fpga_obj_s { + struct switch_obj *obj; +}; + +struct fpga_s { + unsigned int fpga_number; + struct fpga_obj_s *fpga; +}; + +static struct fpga_s g_fpga; +static struct switch_obj *g_fpga_obj = NULL; +static struct s3ip_sysfs_fpga_drivers_s *g_fpga_drv = NULL; + +static ssize_t fpga_number_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_fpga.fpga_number); +} + +static ssize_t fpga_alias_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int fpga_index; + + check_p(g_fpga_drv); + check_p(g_fpga_drv->get_main_board_fpga_alias); + + fpga_index = obj->index; + FPGA_DBG("fpga index: %u\n", fpga_index); + return g_fpga_drv->get_main_board_fpga_alias(fpga_index, buf, PAGE_SIZE); +} + +static ssize_t fpga_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int fpga_index; + + check_p(g_fpga_drv); + check_p(g_fpga_drv->get_main_board_fpga_type); + + fpga_index = obj->index; + FPGA_DBG("fpga index: %u\n", fpga_index); + return g_fpga_drv->get_main_board_fpga_type(fpga_index, buf, PAGE_SIZE); +} + +static ssize_t fpga_fw_version_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int fpga_index; + + check_p(g_fpga_drv); + check_p(g_fpga_drv->get_main_board_fpga_firmware_version); + + fpga_index = obj->index; + FPGA_DBG("fpga index: %u\n", fpga_index); + return g_fpga_drv->get_main_board_fpga_firmware_version(fpga_index, buf, PAGE_SIZE); +} + +static ssize_t fpga_board_version_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int fpga_index; + + check_p(g_fpga_drv); + check_p(g_fpga_drv->get_main_board_fpga_board_version); + + fpga_index = obj->index; + FPGA_DBG("fpga index: %u\n", fpga_index); + return g_fpga_drv->get_main_board_fpga_board_version(fpga_index, buf, PAGE_SIZE); +} + +static ssize_t fpga_test_reg_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int fpga_index; + + check_p(g_fpga_drv); + check_p(g_fpga_drv->get_main_board_fpga_test_reg); + + fpga_index = obj->index; + FPGA_DBG("fpga index: %u\n", fpga_index); + return g_fpga_drv->get_main_board_fpga_test_reg(fpga_index, buf, PAGE_SIZE); +} + +static ssize_t fpga_test_reg_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int fpga_index, value; + int ret; + + check_p(g_fpga_drv); + check_p(g_fpga_drv->set_main_board_fpga_test_reg); + + fpga_index = obj->index; + sscanf(buf, "0x%x", &value); + ret = g_fpga_drv->set_main_board_fpga_test_reg(fpga_index, value); + if (ret < 0) { + FPGA_ERR("set fpga%u test reg failed, value:0x%x, ret: %d.\n", fpga_index, value, ret); + return ret; + } + FPGA_DBG("set fpga%u test reg success, value: 0x%x.\n", fpga_index, value); + return count; +} + +/************************************fpga dir and attrs*******************************************/ +static struct switch_attribute fpga_number_att = __ATTR(number, S_IRUGO, fpga_number_show, NULL); + +static struct attribute *fpga_dir_attrs[] = { + &fpga_number_att.attr, + NULL, +}; + +static struct attribute_group fpga_root_attr_group = { + .attrs = fpga_dir_attrs, +}; + +/*******************************fpga[1-n] dir and attrs*******************************************/ +static struct switch_attribute fpga_alias_attr = __ATTR(alias, S_IRUGO, fpga_alias_show, NULL); +static struct switch_attribute fpga_type_attr = __ATTR(type, S_IRUGO, fpga_type_show, NULL); +static struct switch_attribute fpga_fw_version_attr = __ATTR(firmware_version, S_IRUGO, fpga_fw_version_show, NULL); +static struct switch_attribute fpga_board_version_attr = __ATTR(board_version, S_IRUGO, fpga_board_version_show, NULL); +static struct switch_attribute fpga_test_reg_attr = __ATTR(reg_test, S_IRUGO | S_IWUSR, fpga_test_reg_show, fpga_test_reg_store); + +static struct attribute *fpga_attrs[] = { + &fpga_alias_attr.attr, + &fpga_type_attr.attr, + &fpga_fw_version_attr.attr, + &fpga_board_version_attr.attr, + &fpga_test_reg_attr.attr, + NULL, +}; + +static struct attribute_group fpga_attr_group = { + .attrs = fpga_attrs, +}; + +static int fpga_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct fpga_obj_s *curr_fpga; + + curr_fpga = &g_fpga.fpga[index - 1]; + if (curr_fpga->obj) { + sysfs_remove_group(&curr_fpga->obj->kobj, &fpga_attr_group); + switch_kobject_delete(&curr_fpga->obj); + FPGA_DBG("delete fpga%u dir and attrs success.\n", index); + } + return 0; +} + +static int fpga_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index) +{ + char name[8]; + struct fpga_obj_s *curr_fpga; + + curr_fpga = &g_fpga.fpga[index - 1]; + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "fpga%u", index); + curr_fpga->obj = switch_kobject_create(name, parent); + if (!curr_fpga->obj) { + FPGA_ERR("create %s object error!\n", name); + return -EBADRQC; + } + curr_fpga->obj->index = index; + if (sysfs_create_group(&curr_fpga->obj->kobj, &fpga_attr_group) != 0) { + FPGA_ERR("create %s attrs error.\n", name); + switch_kobject_delete(&curr_fpga->obj); + return -EBADRQC; + } + FPGA_DBG("create %s dir and attrs success.\n", name); + return 0; +} + +static int fpga_sub_create_kobj_and_attrs(struct kobject *parent, int fpga_num) +{ + unsigned int fpga_index, i; + + g_fpga.fpga = kzalloc(sizeof(struct fpga_obj_s) * fpga_num, GFP_KERNEL); + if (!g_fpga.fpga) { + FPGA_ERR("kzalloc g_fpga.fpga error, fpga number = %d.\n", fpga_num); + return -ENOMEM; + } + + for (fpga_index = 1; fpga_index <= fpga_num; fpga_index++) { + if (fpga_sub_single_create_kobj_and_attrs(parent, fpga_index) != 0) { + goto error; + } + } + return 0; +error: + for (i = fpga_index; i > 0; i--) { + fpga_sub_single_remove_kobj_and_attrs(i); + } + kfree(g_fpga.fpga); + g_fpga.fpga = NULL; + return -EBADRQC; +} + +/* create fpga[1-n] directory and attributes*/ +static int fpga_sub_create(void) +{ + int ret; + + ret = fpga_sub_create_kobj_and_attrs(&g_fpga_obj->kobj, g_fpga.fpga_number); + return ret; +} + +/* delete fpga[1-n] directory and attributes*/ +static void fpga_sub_remove(void) +{ + unsigned int fpga_index; + + if (g_fpga.fpga) { + for (fpga_index = g_fpga.fpga_number; fpga_index > 0; fpga_index--) { + fpga_sub_single_remove_kobj_and_attrs(fpga_index); + } + kfree(g_fpga.fpga); + g_fpga.fpga = NULL; + } + g_fpga.fpga_number = 0; + return; +} + +/* create fpga directory and number attributes */ +static int fpga_root_create(void) +{ + g_fpga_obj = switch_kobject_create("fpga", NULL); + if (!g_fpga_obj) { + FPGA_ERR("switch_kobject_create fpga error!\n"); + return -ENOMEM; + } + + if (sysfs_create_group(&g_fpga_obj->kobj, &fpga_root_attr_group) != 0) { + switch_kobject_delete(&g_fpga_obj); + FPGA_ERR("create fpga dir attrs error!\n"); + return -EBADRQC; + } + return 0; +} + +/* delete fpga directory and number attributes */ +static void fpga_root_remove(void) +{ + if (g_fpga_obj) { + sysfs_remove_group(&g_fpga_obj->kobj, &fpga_root_attr_group); + switch_kobject_delete(&g_fpga_obj); + } + + return; +} + +int s3ip_sysfs_fpga_drivers_register(struct s3ip_sysfs_fpga_drivers_s *drv) +{ + int ret, fpga_num; + + FPGA_INFO("s3ip_sysfs_fpga_drivers_register...\n"); + if (g_fpga_drv) { + FPGA_ERR("g_fpga_drv is not NULL, can't register\n"); + return -EPERM; + } + + check_p(drv); + check_p(drv->get_main_board_fpga_number); + g_fpga_drv = drv; + + fpga_num = g_fpga_drv->get_main_board_fpga_number(); + if (fpga_num <= 0) { + FPGA_ERR("fpga number: %d, don't need to create fpga dirs and attrs.\n", fpga_num); + g_fpga_drv = NULL; + return -EINVAL; + } + + mem_clear(&g_fpga, sizeof(struct fpga_s)); + g_fpga.fpga_number = fpga_num; + ret = fpga_root_create(); + if (ret < 0) { + FPGA_ERR("create fpga root dir and attrs failed, ret: %d\n", ret); + g_fpga_drv = NULL; + return ret; + } + ret = fpga_sub_create(); + if (ret < 0) { + FPGA_ERR("create fpga sub dir and attrs failed, ret: %d\n", ret); + fpga_root_remove(); + g_fpga_drv = NULL; + return ret; + } + FPGA_INFO("s3ip_sysfs_fpga_drivers_register success\n"); + return 0; +} + +void s3ip_sysfs_fpga_drivers_unregister(void) +{ + if (g_fpga_drv) { + fpga_sub_remove(); + fpga_root_remove(); + g_fpga_drv = NULL; + FPGA_DBG("s3ip_sysfs_fpga_drivers_unregister success.\n"); + } + + return; +} + +EXPORT_SYMBOL(s3ip_sysfs_fpga_drivers_register); +EXPORT_SYMBOL(s3ip_sysfs_fpga_drivers_unregister); +module_param(g_fpga_loglevel, int, 0644); +MODULE_PARM_DESC(g_fpga_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/cpld_sysfs.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/cpld_sysfs.h new file mode 100644 index 000000000000..2638b18c6f4c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/cpld_sysfs.h @@ -0,0 +1,36 @@ +/* + * A header definition for cpld_sysfs driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _CPLD_SYSFS_H_ +#define _CPLD_SYSFS_H_ + +struct s3ip_sysfs_cpld_drivers_s { + int (*get_main_board_cpld_number)(void); + ssize_t (*get_main_board_cpld_alias)(unsigned int cpld_index, char *buf, size_t count); + ssize_t (*get_main_board_cpld_type)(unsigned int cpld_index, char *buf, size_t count); + ssize_t (*get_main_board_cpld_firmware_version)(unsigned int cpld_index, char *buf, size_t count); + ssize_t (*get_main_board_cpld_board_version)(unsigned int cpld_index, char *buf, size_t count); + ssize_t (*get_main_board_cpld_test_reg)(unsigned int cpld_index, char *buf, size_t count); + int (*set_main_board_cpld_test_reg)(unsigned int cpld_index, unsigned int value); +}; + +extern int s3ip_sysfs_cpld_drivers_register(struct s3ip_sysfs_cpld_drivers_s *drv); +extern void s3ip_sysfs_cpld_drivers_unregister(void); +#endif /*_CPLD_SYSFS_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/curr_sensor_sysfs.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/curr_sensor_sysfs.h new file mode 100644 index 000000000000..fc9bb4948a14 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/curr_sensor_sysfs.h @@ -0,0 +1,38 @@ +/* + * A header definition for curr_sensor_sysfs driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _CURR_SENSOR_SYSFS_H_ +#define _CURR_SENSOR_SYSFS_H_ + +struct s3ip_sysfs_curr_sensor_drivers_s { + int (*get_main_board_curr_number)(void); + ssize_t (*get_main_board_curr_alias)(unsigned int curr_index, char *buf, size_t count); + ssize_t (*get_main_board_curr_type)(unsigned int curr_index, char *buf, size_t count); + ssize_t (*get_main_board_curr_max)(unsigned int curr_index, char *buf, size_t count); + int (*set_main_board_curr_max)(unsigned int curr_index, const char *buf, size_t count); + ssize_t (*get_main_board_curr_min)(unsigned int curr_index, char *buf, size_t count); + int (*set_main_board_curr_min)(unsigned int curr_index, const char *buf, size_t count); + ssize_t (*get_main_board_curr_value)(unsigned int curr_index, char *buf, size_t count); + ssize_t (*get_main_board_curr_monitor_flag)(unsigned int curr_index, char *buf, size_t count); +}; + +extern int s3ip_sysfs_curr_sensor_drivers_register(struct s3ip_sysfs_curr_sensor_drivers_s *drv); +extern void s3ip_sysfs_curr_sensor_drivers_unregister(void); +#endif /*_CURR_SENSOR_SYSFS_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/eeprom_sysfs.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/eeprom_sysfs.h new file mode 100644 index 000000000000..5ebb79afdc9a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/eeprom_sysfs.h @@ -0,0 +1,36 @@ +/* + * A header definition for eeprom_sysfs driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _EEPROM_SYSFS_H_ +#define _EEPROM_SYSFS_H_ + +struct s3ip_sysfs_eeprom_drivers_s { + int (*get_eeprom_number)(void); + ssize_t (*get_eeprom_alias)(unsigned int e2_index, char *buf, size_t count); + ssize_t (*get_eeprom_tag)(unsigned int e2_index, char *buf, size_t count); + ssize_t (*get_eeprom_type)(unsigned int e2_index, char *buf, size_t count); + int (*get_eeprom_size)(unsigned int e2_index); + ssize_t (*read_eeprom_data)(unsigned int e2_index, char *buf, loff_t offset, size_t count); + ssize_t (*write_eeprom_data)(unsigned int e2_index, char *buf, loff_t offset, size_t count); +}; + +extern int s3ip_sysfs_eeprom_drivers_register(struct s3ip_sysfs_eeprom_drivers_s *drv); +extern void s3ip_sysfs_eeprom_drivers_unregister(void); +#endif /*_EEPROM_SYSFS_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/fan_sysfs.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/fan_sysfs.h new file mode 100644 index 000000000000..f89afabd86bd --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/fan_sysfs.h @@ -0,0 +1,53 @@ +/* + * A header definition for fan_sysfs driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _FAN_SYSFS_H_ +#define _FAN_SYSFS_H_ + +struct s3ip_sysfs_fan_drivers_s { + int (*get_fan_number)(void); + int (*get_fan_motor_number)(unsigned int fan_index); + ssize_t (*get_fan_model_name)(unsigned int fan_index, char *buf, size_t count); + ssize_t (*get_fan_vendor)(unsigned int fan_index, char *buf, size_t count); + ssize_t (*get_fan_serial_number)(unsigned int fan_index, char *buf, size_t count); + ssize_t (*get_fan_part_number)(unsigned int fan_index, char *buf, size_t count); + ssize_t (*get_fan_hardware_version)(unsigned int fan_index, char *buf, size_t count); + ssize_t (*get_fan_status)(unsigned int fan_index, char *buf, size_t count); + ssize_t (*get_fan_present)(unsigned int fan_index, char *buf, size_t count); + ssize_t (*get_fan_led_status)(unsigned int fan_index, char *buf, size_t count); + int (*set_fan_led_status)(unsigned int fan_index, int status); + ssize_t (*get_fan_direction)(unsigned int fan_index, char *buf, size_t count); + ssize_t (*get_fan_motor_status)(unsigned int fan_index, unsigned int motor_index, char *buf, size_t count); + ssize_t (*get_fan_motor_speed)(unsigned int fan_index, unsigned int motor_index, char *buf, size_t count); + ssize_t (*get_fan_motor_speed_tolerance)(unsigned int fan_index, unsigned int motor_index, char *buf, size_t count); + ssize_t (*get_fan_motor_speed_target)(unsigned int fan_index, unsigned int motor_index, char *buf, size_t count); + ssize_t (*get_fan_motor_speed_max)(unsigned int fan_index, unsigned int motor_index, char *buf, size_t count); + ssize_t (*get_fan_motor_speed_min)(unsigned int fan_index, unsigned int motor_index, char *buf, size_t count); + ssize_t (*get_fan_ratio)(unsigned int fan_index, char *buf, size_t count); + int (*set_fan_ratio)(unsigned int fan_index, int ratio); +}; + +extern int s3ip_sysfs_fan_drivers_register(struct s3ip_sysfs_fan_drivers_s *drv); +extern void s3ip_sysfs_fan_drivers_unregister(void); +#define SINGLE_FAN_STATUS_DEBUG_FILE "/etc/sonic/.status_fan_%d" +#define FAN_ABSENT_STR "0\n" +#define FAN_OK_STR "1\n" +#define FAN_NOTOK_STR "2\n" +#endif /*_FAN_SYSFS_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/fpga_sysfs.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/fpga_sysfs.h new file mode 100644 index 000000000000..5335a5b0fa4c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/fpga_sysfs.h @@ -0,0 +1,36 @@ +/* + * A header definition for fpga_sysfs driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _FPGA_SYSFS_H_ +#define _FPGA_SYSFS_H_ + +struct s3ip_sysfs_fpga_drivers_s { + int (*get_main_board_fpga_number)(void); + ssize_t (*get_main_board_fpga_alias)(unsigned int fpga_index, char *buf, size_t count); + ssize_t (*get_main_board_fpga_type)(unsigned int fpga_index, char *buf, size_t count); + ssize_t (*get_main_board_fpga_firmware_version)(unsigned int fpga_index, char *buf, size_t count); + ssize_t (*get_main_board_fpga_board_version)(unsigned int fpga_index, char *buf, size_t count); + ssize_t (*get_main_board_fpga_test_reg)(unsigned int fpga_index, char *buf, size_t count); + int (*set_main_board_fpga_test_reg)(unsigned int fpga_index, unsigned int value); +}; + +extern int s3ip_sysfs_fpga_drivers_register(struct s3ip_sysfs_fpga_drivers_s *drv); +extern void s3ip_sysfs_fpga_drivers_unregister(void); +#endif /*_FPGA_SYSFS_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/psu_sysfs.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/psu_sysfs.h new file mode 100644 index 000000000000..c89de1cea6a2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/psu_sysfs.h @@ -0,0 +1,73 @@ +/* + * A header definition for psu_sysfs driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _PSU_SYSFS_H_ +#define _PSU_SYSFS_H_ + +struct s3ip_sysfs_psu_drivers_s { + int (*get_psu_number)(void); + int (*get_psu_temp_number)(unsigned int psu_index); + ssize_t (*get_psu_model_name)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_vendor)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_date)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_status)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_hw_status)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_alarm)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_serial_number)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_part_number)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_hardware_version)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_type)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_in_curr)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_in_vol)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_in_power)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_out_curr)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_out_vol)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_out_power)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_out_max_power)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_present_status)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_status_pmbus)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_in_status)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_out_status)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_fan_speed)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_fan_ratio)(unsigned int psu_index, char *buf, size_t count); + int (*set_psu_fan_ratio)(unsigned int psu_index, int ratio); + ssize_t (*get_psu_fan_direction)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_led_status)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_fan_speed_cal)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_temp_alias)(unsigned int psu_index, unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_psu_temp_type)(unsigned int psu_index, unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_psu_temp_max)(unsigned int psu_index, unsigned int temp_index, char *buf, size_t count); + int (*set_psu_temp_max)(unsigned int psu_index, unsigned int temp_index, const char *buf, size_t count); + ssize_t (*get_psu_temp_min)(unsigned int psu_index, unsigned int temp_index, char *buf, size_t count); + int (*set_psu_temp_min)(unsigned int psu_index, unsigned int temp_index, const char *buf, size_t count); + ssize_t (*get_psu_temp_value)(unsigned int psu_index, unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_psu_attr_threshold)(unsigned int psu_index, unsigned int type, char *buf, size_t count); + int (*get_psu_eeprom_size)(unsigned int psu_index); + ssize_t (*read_psu_eeprom_data)(unsigned int psu_index, char *buf, loff_t offset, size_t count); + ssize_t (*get_psu_blackbox_info)(unsigned int psu_index, char *buf, size_t count); + ssize_t (*get_psu_pmbus_info)(unsigned int psu_index, char *buf, size_t count); + int (*clear_psu_blackbox)(unsigned int psu_index, uint8_t value); +}; + +extern int s3ip_sysfs_psu_drivers_register(struct s3ip_sysfs_psu_drivers_s *drv); +extern void s3ip_sysfs_psu_drivers_unregister(void); +#define SINGLE_PSU_PRESENT_DEBUG_FILE "/etc/sonic/.present_psu_%d" + +#endif /*_PSU_SYSFS_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/slot_sysfs.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/slot_sysfs.h new file mode 100644 index 000000000000..e5cba548f224 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/slot_sysfs.h @@ -0,0 +1,80 @@ +/* + * A header definition for slot_sysfs driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _SLOT_SYSFS_H_ +#define _SLOT_SYSFS_H_ + +struct s3ip_sysfs_slot_drivers_s { + int (*get_slot_number)(void); + int (*get_slot_temp_number)(unsigned int slot_index); + int (*get_slot_vol_number)(unsigned int slot_index); + int (*get_slot_curr_number)(unsigned int slot_index); + int (*get_slot_cpld_number)(unsigned int slot_index); + int (*get_slot_fpga_number)(unsigned int slot_index); + ssize_t (*get_slot_model_name)(unsigned int slot_index, char *buf, size_t count); + ssize_t (*get_slot_vendor)(unsigned int slot_index, char *buf, size_t count); + ssize_t (*get_slot_serial_number)(unsigned int slot_index, char *buf, size_t count); + ssize_t (*get_slot_part_number)(unsigned int slot_index, char *buf, size_t count); + ssize_t (*get_slot_hardware_version)(unsigned int slot_index, char *buf, size_t count); + ssize_t (*get_slot_status)(unsigned int slot_index, char *buf, size_t count); + ssize_t (*get_slot_led_status)(unsigned int slot_index, char *buf, size_t count); + int (*set_slot_led_status)(unsigned int slot_index, int status); + ssize_t (*get_slot_power_status)(unsigned int slot_index, char *buf, size_t count); + int (*set_slot_power_status)(unsigned int slot_index, int status); + ssize_t (*get_slot_temp_alias)(unsigned int slot_index, unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_slot_temp_type)(unsigned int slot_index, unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_slot_temp_max)(unsigned int slot_index, unsigned int temp_index, char *buf, size_t count); + int (*set_slot_temp_max)(unsigned int slot_index, unsigned int temp_index, const char *buf, size_t count); + ssize_t (*get_slot_temp_min)(unsigned int slot_index, unsigned int temp_index, char *buf, size_t count); + int (*set_slot_temp_min)(unsigned int slot_index, unsigned int temp_index, const char *buf, size_t count); + ssize_t (*get_slot_temp_value)(unsigned int slot_index, unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_slot_vol_alias)(unsigned int slot_index, unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_slot_vol_type)(unsigned int slot_index, unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_slot_vol_max)(unsigned int slot_index, unsigned int vol_index, char *buf, size_t count); + int (*set_slot_vol_max)(unsigned int slot_index, unsigned int vol_index, const char *buf, size_t count); + ssize_t (*get_slot_vol_min)(unsigned int slot_index, unsigned int vol_index, char *buf, size_t count); + int (*set_slot_vol_min)(unsigned int slot_index, unsigned int vol_index, const char *buf, size_t count); + ssize_t (*get_slot_vol_range)(unsigned int slot_index, unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_slot_vol_nominal_value)(unsigned int slot_index, unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_slot_vol_value)(unsigned int slot_index, unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_slot_curr_alias)(unsigned int slot_index, unsigned int curr_index, char *buf, size_t count); + ssize_t (*get_slot_curr_type)(unsigned int slot_index, unsigned int curr_index, char *buf, size_t count); + ssize_t (*get_slot_curr_max)(unsigned int slot_index, unsigned int curr_index, char *buf, size_t count); + int (*set_slot_curr_max)(unsigned int slot_index, unsigned int curr_index, const char *buf, size_t count); + ssize_t (*get_slot_curr_min)(unsigned int slot_index, unsigned int curr_index, char *buf, size_t count); + int (*set_slot_curr_min)(unsigned int slot_index, unsigned int curr_index, const char *buf, size_t count); + ssize_t (*get_slot_curr_value)(unsigned int slot_index, unsigned int curr_index, char *buf, size_t count); + ssize_t (*get_slot_fpga_alias)(unsigned int slot_index, unsigned int fpga_index, char *buf, size_t count); + ssize_t (*get_slot_fpga_type)(unsigned int slot_index, unsigned int fpga_index, char *buf, size_t count); + ssize_t (*get_slot_fpga_firmware_version)(unsigned int slot_index, unsigned int fpga_index, char *buf, size_t count); + ssize_t (*get_slot_fpga_board_version)(unsigned int slot_index, unsigned int fpga_index, char *buf, size_t count); + ssize_t (*get_slot_fpga_test_reg)(unsigned int slot_index, unsigned int fpga_index, char *buf, size_t count); + int (*set_slot_fpga_test_reg)(unsigned int slot_index, unsigned int fpga_index, unsigned int value); + ssize_t (*get_slot_cpld_alias)(unsigned int slot_index, unsigned int cpld_index, char *buf, size_t count); + ssize_t (*get_slot_cpld_type)(unsigned int slot_index, unsigned int cpld_index, char *buf, size_t count); + ssize_t (*get_slot_cpld_firmware_version)(unsigned int slot_index, unsigned int cpld_index, char *buf, size_t count); + ssize_t (*get_slot_cpld_board_version)(unsigned int slot_index, unsigned int cpld_index, char *buf, size_t count); + ssize_t (*get_slot_cpld_test_reg)(unsigned int slot_index, unsigned int cpld_index, char *buf, size_t count); + int (*set_slot_cpld_test_reg)(unsigned int slot_index, unsigned int cpld_index, unsigned int value); +}; + +extern int s3ip_sysfs_slot_drivers_register(struct s3ip_sysfs_slot_drivers_s *drv); +extern void s3ip_sysfs_slot_drivers_unregister(void); +#endif /*_SLOT_SYSFS_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/switch.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/switch.h new file mode 100644 index 000000000000..2f7e1ef2f8a1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/switch.h @@ -0,0 +1,96 @@ +/* + * A header definition for switch driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _SWITCH_H_ +#define _SWITCH_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "switch_driver.h" +#include "wb_module.h" + +#define DIR_NAME_MAX_LEN (64) +#define DEBUG_FILE_SIZE (64) +#define DEV_PRESEN_STR "1\n" +#define DEV_ABSENT_STR "0\n" +#define mem_clear(data, size) memset((data), 0, (size)) + +enum LOG_LEVEL { + INFO = 0x1, + ERR = 0x2, + DBG = 0x4, + ALL = 0xf +}; + +extern int g_switch_loglevel; + +#define check_pfun(p) do { \ + if (p == NULL) { \ + if (g_switch_loglevel & ERR) { \ + printk(KERN_ERR "%s, %s is NULL.\n", __FUNCTION__, #p); \ + } \ + return -WB_SYSFS_RV_UNSUPPORT; \ + } \ +} while (0) + +#define check_p(p) check_pfun(p) + +#define to_switch_obj(x) container_of(x, struct switch_obj, kobj) +#define to_switch_attr(x) container_of(x, struct switch_attribute, attr) +#define to_switch_device_attr(x) container_of(x, struct switch_device_attribute, switch_attr) + +#define SWITCH_ATTR(_name, _mode, _show, _store, _type) \ + { .switch_attr = __ATTR(_name, _mode, _show, _store), \ + .type = _type } + +#define SWITCH_DEVICE_ATTR(_name, _mode, _show, _store, _type) \ +struct switch_device_attribute switch_dev_attr_##_name \ + = SWITCH_ATTR(_name, _mode, _show, _store, _type) + +struct switch_obj { + struct kobject kobj; + unsigned int index; +}; + +/* a custom attribute that works just for a struct switch_obj. */ +struct switch_attribute { + struct attribute attr; + ssize_t (*show)(struct switch_obj *foo, struct switch_attribute *attr, char *buf); + ssize_t (*store)(struct switch_obj *foo, struct switch_attribute *attr, const char *buf, size_t count); +}; + +struct switch_device_attribute { + struct switch_attribute switch_attr; + int type; +}; + +struct switch_obj *switch_kobject_create(const char *name, struct kobject *parent); +void switch_kobject_delete(struct switch_obj **obj); +int dev_debug_file_read(char *file_name, unsigned int dev_index, char *buf, int size); + +#endif /* _SWITCH_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/syseeprom_sysfs.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/syseeprom_sysfs.h new file mode 100644 index 000000000000..7ce272ad6112 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/syseeprom_sysfs.h @@ -0,0 +1,32 @@ +/* + * A header definition for syseeprom_sysfs driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _SYSEEPROM_SYSFS_H_ +#define _SYSEEPROM_SYSFS_H_ + +struct s3ip_sysfs_syseeprom_drivers_s { + int (*get_syseeprom_size)(void); + ssize_t (*read_syseeprom_data)(char *buf, loff_t offset, size_t count); + ssize_t (*write_syseeprom_data)(char *buf, loff_t offset, size_t count); +}; + +extern int s3ip_sysfs_syseeprom_drivers_register(struct s3ip_sysfs_syseeprom_drivers_s *drv); +extern void s3ip_sysfs_syseeprom_drivers_unregister(void); +#endif /*_SYSEEPROM_SYSFS_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/sysled_sysfs.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/sysled_sysfs.h new file mode 100644 index 000000000000..5eaf3af7057e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/sysled_sysfs.h @@ -0,0 +1,39 @@ +/* + * A header definition for sysled_sysfs driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _SYSLED_SYSFS_H_ +#define _SYSLED_SYSFS_H_ + +struct s3ip_sysfs_sysled_drivers_s { + ssize_t (*get_sys_led_status)(char *buf, size_t count); + int (*set_sys_led_status)(int status); + ssize_t (*get_bmc_led_status)(char *buf, size_t count); + int (*set_bmc_led_status)(int status); + ssize_t (*get_sys_fan_led_status)(char *buf, size_t count); + int (*set_sys_fan_led_status)(int status); + ssize_t (*get_sys_psu_led_status)(char *buf, size_t count); + int (*set_sys_psu_led_status)(int status); + ssize_t (*get_id_led_status)(char *buf, size_t count); + int (*set_id_led_status)(int status); +}; + +extern int s3ip_sysfs_sysled_drivers_register(struct s3ip_sysfs_sysled_drivers_s *drv); +extern void s3ip_sysfs_sysled_drivers_unregister(void); +#endif /*_SYSLED_SYSFS_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/system_sysfs.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/system_sysfs.h new file mode 100644 index 000000000000..a5edf5e107b8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/system_sysfs.h @@ -0,0 +1,54 @@ +/* + * A header definition for system_sysfs driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _SYSTEM_SYSFS_H_ +#define _SYSTEM_SYSFS_H_ + +struct s3ip_sysfs_system_drivers_s { + ssize_t (*get_system_value)(unsigned int type, int *value, char *buf, size_t count); + ssize_t (*set_system_value)(unsigned int type, int value); + ssize_t (*get_system_port_power_status)(unsigned int type, char *buf, size_t count); +}; + +extern int s3ip_sysfs_system_drivers_register(struct s3ip_sysfs_system_drivers_s *drv); +extern void s3ip_sysfs_system_drivers_unregister(void); + +/* system api type */ +typedef enum wb_plat_system_type_e { + WB_SYSTEM_BMC_READY = 0x0000, /* bmc ready */ + WB_SYSTEM_SOL_ACTIVE = 0x0100, /* sol active */ + WB_SYSTEM_PSU_RESET = 0x0200, /* psu reset */ + WB_SYSTEM_CPU_BOARD_CTRL = 0x0300, /* cpu board control */ + WB_SYSTEM_CPU_BOARD_STATUS = 0x0400, /* cpu board status */ + WB_SYSTEM_BIOS_UPGRADE = 0x0500, /* bios upgrade */ + WB_SYSTEM_BIOS_SWITCH = 0x0600, /* bios switch */ + WB_SYSTEM_BIOS_VIEW = 0x0700, /* bios flash view */ + WB_SYSTEM_BIOS_BOOT_OK = 0x0800, /* bios boot status */ + WB_SYSTEM_BIOS_FAIL_RECORD = 0x0900, /* bios startup failure record */ + WB_SYSTEM_BMC_RESET = 0x0a00, /* bmc reset */ + WB_SYSTEM_MAC_BOARD_RESET = 0x0b00, /* mac board reset */ + WB_SYSTEM_MAC_PWR_CTRL = 0x0c00, /* mac power on/off */ + WB_SYSTEM_EMMC_PWR_CTRL = 0x0d00, /* emmc power on/off */ + WB_SYSTEM_PORT_PWR_CTL = 0x0e00, /* power power on/off*/ + WB_SYSTEM_BMC_VIEW = 0x0f00, /* bmc view */ + WB_SYSTEM_BMC_SWITCH = 0x1000, /* bmc switch */ +} wb_plat_system_type_t; + +#endif /*_SYSTEM_SYSFS_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/temp_sensor_sysfs.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/temp_sensor_sysfs.h new file mode 100644 index 000000000000..dc6138388b34 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/temp_sensor_sysfs.h @@ -0,0 +1,42 @@ +/* + * A header definition for temp_sensor_sysfs driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _TEMP_SENSOR_SYSFS_H_ +#define _TEMP_SENSOR_SYSFS_H_ + +struct s3ip_sysfs_temp_sensor_drivers_s { + int (*get_main_board_temp_number)(void); + ssize_t (*get_main_board_temp_alias)(unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_main_board_temp_type)(unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_main_board_temp_max)(unsigned int temp_index, char *buf, size_t count); + int (*set_main_board_temp_max)(unsigned int temp_index, const char *buf, size_t count); + ssize_t (*get_main_board_temp_min)(unsigned int temp_index, char *buf, size_t count); + int (*set_main_board_temp_min)(unsigned int temp_index, const char *buf, size_t count); + ssize_t (*get_main_board_temp_high)(unsigned int temp_index, char *buf, size_t count); + int (*set_main_board_temp_high)(unsigned int temp_index, const char *buf, size_t count); + ssize_t (*get_main_board_temp_low)(unsigned int temp_index, char *buf, size_t count); + int (*set_main_board_temp_low)(unsigned int temp_index, const char *buf, size_t count); + ssize_t (*get_main_board_temp_value)(unsigned int temp_index, char *buf, size_t count); + ssize_t (*get_main_board_temp_monitor_flag)(unsigned int temp_index, char *buf, size_t count); +}; + +extern int s3ip_sysfs_temp_sensor_drivers_register(struct s3ip_sysfs_temp_sensor_drivers_s *drv); +extern void s3ip_sysfs_temp_sensor_drivers_unregister(void); +#endif /*_TEMP_SENSOR_SYSFS_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/transceiver_sysfs.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/transceiver_sysfs.h new file mode 100644 index 000000000000..a4fcb485d37a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/transceiver_sysfs.h @@ -0,0 +1,50 @@ +/* + * A header definition for transceiver_sysfs driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _TRANSCEIVER_SYSFS_H_ +#define _TRANSCEIVER_SYSFS_H_ + +struct s3ip_sysfs_transceiver_drivers_s { + int (*get_eth_number)(void); + ssize_t (*get_transceiver_power_on_status)(char *buf, size_t count); + int (*set_transceiver_power_on_status)(int status); + ssize_t (*get_transceiver_present_status)(char *buf, size_t count); + ssize_t (*get_eth_power_on_status)(unsigned int eth_index, char *buf, size_t count); + int (*set_eth_power_on_status)(unsigned int eth_index, int status); + ssize_t (*get_eth_tx_fault_status)(unsigned int eth_index, char *buf, size_t count); + ssize_t (*get_eth_tx_disable_status)(unsigned int eth_index, char *buf, size_t count); + int (*set_eth_tx_disable_status)(unsigned int eth_index, int status); + ssize_t (*get_eth_present_status)(unsigned int eth_index, char *buf, size_t count); + ssize_t (*get_eth_rx_los_status)(unsigned int eth_index, char *buf, size_t count); + ssize_t (*get_eth_reset_status)(unsigned int eth_index, char *buf, size_t count); + int (*set_eth_reset_status)(unsigned int eth_index, int status); + ssize_t (*get_eth_low_power_mode_status)(unsigned int eth_index, char *buf, size_t count); + ssize_t (*get_eth_interrupt_status)(unsigned int eth_index, char *buf, size_t count); + int (*get_eth_eeprom_size)(unsigned int eth_index); + ssize_t (*read_eth_eeprom_data)(unsigned int eth_index, char *buf, loff_t offset, size_t count); + ssize_t (*write_eth_eeprom_data)(unsigned int eth_index, char *buf, loff_t offset, size_t count); + ssize_t (*get_eth_optoe_type)(unsigned int sff_index, int *optoe_type, char *buf, size_t count); + ssize_t (*set_eth_optoe_type)(unsigned int sff_index, int optoe_type); +}; + +extern int s3ip_sysfs_sff_drivers_register(struct s3ip_sysfs_transceiver_drivers_s *drv); +extern void s3ip_sysfs_sff_drivers_unregister(void); +#define SINGLE_TRANSCEIVER_PRESENT_DEBUG_FILE "/etc/sonic/.present_eth_%d" +#endif /*_TRANSCEIVER_SYSFS_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/vol_sensor_sysfs.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/vol_sensor_sysfs.h new file mode 100644 index 000000000000..f13d4a2057e2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/vol_sensor_sysfs.h @@ -0,0 +1,40 @@ +/* + * A header definition for vol_sensor_sysfs driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _VOL_SENSOR_SYSFS_H_ +#define _VOL_SENSOR_SYSFS_H_ + +struct s3ip_sysfs_vol_sensor_drivers_s { + int (*get_main_board_vol_number)(void); + ssize_t (*get_main_board_vol_alias)(unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_main_board_vol_type)(unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_main_board_vol_max)(unsigned int vol_index, char *buf, size_t count); + int (*set_main_board_vol_max)(unsigned int vol_index, const char *buf, size_t count); + ssize_t (*get_main_board_vol_min)(unsigned int vol_index, char *buf, size_t count); + int (*set_main_board_vol_min)(unsigned int vol_index, const char *buf, size_t count); + ssize_t (*get_main_board_vol_range)(unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_main_board_vol_nominal_value)(unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_main_board_vol_value)(unsigned int vol_index, char *buf, size_t count); + ssize_t (*get_main_board_vol_monitor_flag)(unsigned int vol_index, char *buf, size_t count); +}; + +extern int s3ip_sysfs_vol_sensor_drivers_register(struct s3ip_sysfs_vol_sensor_drivers_s *drv); +extern void s3ip_sysfs_vol_sensor_drivers_unregister(void); +#endif /*_VOL_SENSOR_SYSFS_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/watchdog_sysfs.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/watchdog_sysfs.h new file mode 100644 index 000000000000..ac9e7666aee8 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/include/watchdog_sysfs.h @@ -0,0 +1,36 @@ +/* + * A header definition for watchdog_sysfs driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _WATCHDOG_SYSFS_H_ +#define _WATCHDOG_SYSFS_H_ + +struct s3ip_sysfs_watchdog_drivers_s { + ssize_t (*get_watchdog_identify)(char *buf, size_t count); + ssize_t (*get_watchdog_timeleft)(char *buf, size_t count); + ssize_t (*get_watchdog_timeout)(char *buf, size_t count); + int (*set_watchdog_timeout)(int value); + ssize_t (*get_watchdog_enable_status)(char *buf, size_t count); + int (*set_watchdog_enable_status)(int value); + int (*set_watchdog_reset)(int value); +}; + +extern int s3ip_sysfs_watchdog_drivers_register(struct s3ip_sysfs_watchdog_drivers_s *drv); +extern void s3ip_sysfs_watchdog_drivers_unregister(void); +#endif /*_WATCHDOG_SYSFS_H_ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/psu_sysfs.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/psu_sysfs.c new file mode 100644 index 000000000000..ecb6ca30e6d4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/psu_sysfs.c @@ -0,0 +1,1180 @@ +/* + * An psu_sysfs driver for psu sysfs devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#include "switch.h" +#include "psu_sysfs.h" + +static int g_psu_loglevel = 0; +static bool g_psu_present_debug = 0; + +#define PSU_INFO(fmt, args...) do { \ + if (g_psu_loglevel & INFO) { \ + printk(KERN_INFO "[PSU_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define PSU_ERR(fmt, args...) do { \ + if (g_psu_loglevel & ERR) { \ + printk(KERN_ERR "[PSU_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define PSU_DBG(fmt, args...) do { \ + if (g_psu_loglevel & DBG) { \ + printk(KERN_DEBUG "[PSU_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct temp_obj_s { + struct switch_obj *obj; +}; + +struct psu_obj_s { + unsigned int temp_number; + struct temp_obj_s *temp; + struct switch_obj *obj; + struct bin_attribute bin; + int psu_creat_bin_flag; +}; + +struct psu_s { + unsigned int psu_number; + struct psu_obj_s *psu; +}; + +static struct psu_s g_psu; +static struct switch_obj *g_psu_obj = NULL; +static struct s3ip_sysfs_psu_drivers_s *g_psu_drv = NULL; + +static ssize_t psu_number_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", g_psu.psu_number); +} + +static ssize_t psu_temp_number_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int index; + + index = obj->index; + PSU_DBG("psu index: %u\n",index); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_psu.psu[index - 1].temp_number); +} + +static ssize_t psu_model_name_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_model_name); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_model_name(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_vendor_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_vendor); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_vendor(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_date_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_date); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_date(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_hw_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_hardware_version); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_hardware_version(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_sn_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_serial_number); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_serial_number(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_pn_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_part_number); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_part_number(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_type); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_type(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_in_curr_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_in_curr); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_in_curr(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_in_vol_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_in_vol); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_in_vol(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_in_power_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_in_power); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_in_power(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_out_curr_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_out_curr); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_out_curr(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_out_vol_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_out_vol); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_out_vol(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_out_power_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_out_power); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_out_power(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_out_max_power_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_out_max_power); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_out_max_power(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_present_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + int ret, res; + char debug_file_buf[DEBUG_FILE_SIZE]; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_present_status); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + ret = g_psu_drv->get_psu_present_status(psu_index, buf, PAGE_SIZE); + if (ret < 0) { + PSU_ERR("get psu%u present status failed, ret: %d\n", psu_index, ret); + return ret; + } + + if (g_psu_present_debug) { + PSU_INFO("s3ip sysfs psu present debug is enable\n"); + if (strcmp(buf, DEV_ABSENT_STR) == 0) { + PSU_DBG("psu%d absent, return act value\n", psu_index); + return ret; + } + + if ((strncmp(buf, SWITCH_DEV_NO_SUPPORT, strlen(SWITCH_DEV_NO_SUPPORT)) == 0) || (strncmp(buf, SWITCH_DEV_ERROR, strlen(SWITCH_DEV_ERROR)) == 0)) { + PSU_DBG("psu%d status sysfs unsupport or error\n", psu_index); + return ret; + } + + mem_clear(debug_file_buf, sizeof(debug_file_buf)); + res = dev_debug_file_read(SINGLE_PSU_PRESENT_DEBUG_FILE, psu_index, debug_file_buf, sizeof(debug_file_buf)); + if (res) { + PSU_ERR("psu%u present debug file read failed, ret: %d\n", psu_index, res); + return ret; + } + + if ((strcmp(debug_file_buf, DEV_PRESEN_STR) == 0) || (strcmp(debug_file_buf, DEV_ABSENT_STR) == 0)) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s", debug_file_buf); + } else { + PSU_ERR("psu%d present debug file value err, value: %s, not 0 or 1\n", psu_index, debug_file_buf); + return ret; + } + } + + return ret; +} + +static ssize_t get_psu_status_pmbus_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_status_pmbus); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_status_pmbus(psu_index, buf, PAGE_SIZE); +} + +static ssize_t get_psu_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_status); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_status(psu_index, buf, PAGE_SIZE); +} + +static ssize_t get_psu_hw_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_hw_status); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_hw_status(psu_index, buf, PAGE_SIZE); +} + +static ssize_t get_psu_alarm_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_alarm); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_alarm(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_out_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_out_status); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_out_status(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_in_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_in_status); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_in_status(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_fan_speed_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_fan_speed); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_fan_speed(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_fan_speed_cal_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_fan_speed_cal); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_fan_speed_cal(psu_index, buf, PAGE_SIZE); +} + +ssize_t psu_fan_ratio_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_fan_ratio); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_fan_ratio(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_fan_ratio_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int psu_index; + int ret, ratio; + + check_p(g_psu_drv); + check_p(g_psu_drv->set_psu_fan_ratio); + + psu_index = obj->index; + ret = kstrtoint(buf, 0, &ratio); + if (ret != 0) { + PSU_ERR("invaild psu fan ratio ret: %d, buf: %s.\n", ret, buf); + return -EINVAL; + } + if (ratio < 0 || ratio > 100) { + PSU_ERR("param invalid, can not set ratio: %d.\n", ratio); + return -EINVAL; + } + PSU_DBG("psu index: %u, ratio: %d\n", psu_index, ratio); + ret = g_psu_drv->set_psu_fan_ratio(psu_index, ratio); + if (ret < 0) { + PSU_ERR("set psu%u ratio: %d failed, ret: %d\n", + psu_index, ratio, ret); + return ret; + } + PSU_DBG("set psu%u, ratio: %d success\n", psu_index, ratio); + return count; +} + +static ssize_t psu_fan_direction_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_fan_direction); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_fan_direction(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_led_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_led_status); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_led_status(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_temp_value_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index, temp_index; + struct switch_obj *p_obj; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_temp_value); + + p_obj = to_switch_obj(obj->kobj.parent); + psu_index = p_obj->index; + temp_index = obj->index; + + PSU_DBG("psu index: %u, temp index: %u\n", psu_index, temp_index); + return g_psu_drv->get_psu_temp_value(psu_index, temp_index, buf, PAGE_SIZE); +} + +static ssize_t psu_temp_alias_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index, temp_index; + struct switch_obj *p_obj; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_temp_alias); + + p_obj = to_switch_obj(obj->kobj.parent); + psu_index = p_obj->index; + temp_index = obj->index; + + PSU_DBG("psu index: %u, temp index: %u\n", psu_index, temp_index); + return g_psu_drv->get_psu_temp_alias(psu_index, temp_index, buf, PAGE_SIZE); +} + +static ssize_t psu_temp_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index, temp_index; + struct switch_obj *p_obj; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_temp_type); + + p_obj = to_switch_obj(obj->kobj.parent); + psu_index = p_obj->index; + temp_index = obj->index; + + PSU_DBG("psu index: %u, temp index: %u\n", psu_index, temp_index); + return g_psu_drv->get_psu_temp_type(psu_index, temp_index, buf, PAGE_SIZE); +} + +static ssize_t psu_temp_max_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index, temp_index; + struct switch_obj *p_obj; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_temp_max); + + p_obj = to_switch_obj(obj->kobj.parent); + psu_index = p_obj->index; + temp_index = obj->index; + + PSU_DBG("psu index: %u, temp index: %u\n", psu_index, temp_index); + return g_psu_drv->get_psu_temp_max(psu_index, temp_index, buf, PAGE_SIZE); +} + +static ssize_t psu_temp_max_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int psu_index, temp_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_psu_drv); + check_p(g_psu_drv->set_psu_temp_max); + + p_obj = to_switch_obj(obj->kobj.parent); + psu_index = p_obj->index; + temp_index = obj->index; + ret = g_psu_drv->set_psu_temp_max(psu_index, temp_index, buf, count); + if (ret < 0) { + PSU_ERR("set psu%u temp%u max threshold failed, value: %s, count: %lu, ret: %d\n", + psu_index, temp_index, buf, count, ret); + return ret; + } + PSU_DBG("set psu%u temp%u max threshold success, value: %s, count: %lu, ret: %d\n", + psu_index, temp_index, buf, count, ret); + return count; +} + +static ssize_t psu_temp_min_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index, temp_index; + struct switch_obj *p_obj; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_temp_min); + + p_obj = to_switch_obj(obj->kobj.parent); + psu_index = p_obj->index; + temp_index = obj->index; + + PSU_DBG("psu index: %u, temp index: %u\n", psu_index, temp_index); + return g_psu_drv->get_psu_temp_min(psu_index, temp_index, buf, PAGE_SIZE); +} + +static ssize_t psu_temp_min_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int psu_index, temp_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_psu_drv); + check_p(g_psu_drv->set_psu_temp_min); + + p_obj = to_switch_obj(obj->kobj.parent); + psu_index = p_obj->index; + temp_index = obj->index; + ret = g_psu_drv->set_psu_temp_min(psu_index, temp_index, buf, count); + if (ret < 0) { + PSU_ERR("set psu%u temp%u min threshold failed, value: %s, count: %lu, ret: %d\n", + psu_index, temp_index, buf, count, ret); + return ret; + } + PSU_DBG("set psu%u temp%u min threshold success, value: %s, count: %lu, ret: %d\n", + psu_index, temp_index, buf, count, ret); + return count; +} + +static ssize_t psu_attr_threshold_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int psu_index; + struct switch_device_attribute *tmp_attr; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_attr_threshold); + + psu_index = obj->index; + tmp_attr = to_switch_device_attr(attr); + check_p(tmp_attr); + return g_psu_drv->get_psu_attr_threshold(psu_index, tmp_attr->type, buf, PAGE_SIZE); +} + +static ssize_t psu_eeprom_read(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, + char *buf, loff_t offset, size_t count) +{ + struct switch_obj *psu_obj; + ssize_t rd_len; + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->read_psu_eeprom_data); + + psu_obj = to_switch_obj(kobj); + psu_index = psu_obj->index; + mem_clear(buf, count); + rd_len = g_psu_drv->read_psu_eeprom_data(psu_index, buf, offset, count); + if (rd_len < 0) { + PSU_ERR("read psu%u eeprom data error, offset: 0x%llx, read len: %lu, ret: %ld.\n", + psu_index, offset, count, rd_len); + return rd_len; + } + + PSU_DBG("read psu%u eeprom data success, offset:0x%llx, read len:%lu, really read len:%ld.\n", + psu_index, offset, count, rd_len); + + return rd_len; +} + +static ssize_t psu_blackbox_info_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_blackbox_info); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_blackbox_info(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_pmbus_info_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int psu_index; + + check_p(g_psu_drv); + check_p(g_psu_drv->get_psu_pmbus_info); + + psu_index = obj->index; + PSU_DBG("psu index: %u\n", psu_index); + return g_psu_drv->get_psu_pmbus_info(psu_index, buf, PAGE_SIZE); +} + +static ssize_t psu_clear_blackbox_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int psu_index; + int ret; + uint8_t vaule; + + check_p(g_psu_drv); + check_p(g_psu_drv->clear_psu_blackbox); + + psu_index = obj->index; + ret = kstrtou8(buf, 0, &vaule); + if (ret != 0) { + PSU_ERR("Invaild value ret: %d, buf: %s.\n", ret, buf); + return -EINVAL; + } + if (vaule != 1) { + PSU_ERR("Invaild value: %u, only support write 1 to clear psu blackbox information\n", vaule); + return -EINVAL; + } + PSU_DBG("psu index: %u, clear psu blackbox information\n", psu_index); + ret = g_psu_drv->clear_psu_blackbox(psu_index, vaule); + if (ret < 0) { + PSU_ERR("clear psu%u blackbox information failed, ret: %d\n", + psu_index, ret); + return ret; + } + PSU_DBG("clear psu%u blackbox information success\n", psu_index); + return count; +} + +/************************************psu dir and attrs*******************************************/ +static struct switch_attribute psu_number_att = __ATTR(number, S_IRUGO, psu_number_show, NULL); + +static struct attribute *psu_dir_attrs[] = { + &psu_number_att.attr, + NULL, +}; + +static struct attribute_group psu_root_attr_group = { + .attrs = psu_dir_attrs, +}; + +/*******************************psu[1-n] dir and attrs*******************************************/ +static struct switch_attribute psu_model_name_attr = __ATTR(model_name, S_IRUGO, psu_model_name_show, NULL); +static struct switch_attribute psu_vendor_attr = __ATTR(vendor, S_IRUGO, psu_vendor_show, NULL); +static struct switch_attribute psu_date_attr = __ATTR(date, S_IRUGO, psu_date_show, NULL); +static struct switch_attribute psu_hw_attr = __ATTR(hardware_version, S_IRUGO, psu_hw_show, NULL); +static struct switch_attribute psu_sn_attr = __ATTR(serial_number, S_IRUGO, psu_sn_show, NULL); +static struct switch_attribute psu_pn_attr = __ATTR(part_number, S_IRUGO, psu_pn_show, NULL); +static struct switch_attribute psu_type_attr = __ATTR(type, S_IRUGO, psu_type_show, NULL); +static struct switch_attribute psu_in_curr_attr = __ATTR(in_curr, S_IRUGO, psu_in_curr_show, NULL); +static struct switch_attribute psu_in_vol_attr = __ATTR(in_vol, S_IRUGO, psu_in_vol_show, NULL); +static struct switch_attribute psu_in_power_attr = __ATTR(in_power, S_IRUGO, psu_in_power_show, NULL); +static struct switch_attribute psu_out_curr_attr = __ATTR(out_curr, S_IRUGO, psu_out_curr_show, NULL); +static struct switch_attribute psu_out_vol_attr = __ATTR(out_vol, S_IRUGO, psu_out_vol_show, NULL); +static struct switch_attribute psu_out_power_attr = __ATTR(out_power, S_IRUGO, psu_out_power_show, NULL); +static struct switch_attribute psu_out_max_power_attr = __ATTR(out_max_power, S_IRUGO, psu_out_max_power_show, NULL); +static struct switch_attribute psu_num_temps_attr = __ATTR(num_temp_sensors, S_IRUGO, psu_temp_number_show, NULL); +static struct switch_attribute psu_present_attr = __ATTR(present, S_IRUGO, psu_present_status_show, NULL); +static struct switch_attribute status_fr_pmbus_attr = __ATTR(status_fr_pmbus, S_IRUGO, get_psu_status_pmbus_show, NULL); +static struct switch_attribute psu_status_attr = __ATTR(status, S_IRUGO, get_psu_status_show, NULL); +static struct switch_attribute psu_hw_status_attr = __ATTR(hw_status, S_IRUGO, get_psu_hw_status_show, NULL); +static struct switch_attribute psu_alarm_attr = __ATTR(alarm, S_IRUGO, get_psu_alarm_show, NULL); +static struct switch_attribute psu_out_status_attr = __ATTR(out_status, S_IRUGO, psu_out_status_show, NULL); +static struct switch_attribute psu_in_status_attr = __ATTR(in_status, S_IRUGO, psu_in_status_show, NULL); +static struct switch_attribute psu_fan_speed_attr = __ATTR(fan_speed, S_IRUGO, psu_fan_speed_show, NULL); +static struct switch_attribute psu_fan_ratio_attr = __ATTR(fan_ratio, S_IRUGO | S_IWUSR, psu_fan_ratio_show, psu_fan_ratio_store); +static struct switch_attribute psu_fan_direction_attr = __ATTR(fan_direction, S_IRUGO, psu_fan_direction_show, NULL); +static struct switch_attribute psu_led_status_attr = __ATTR(led_status, S_IRUGO, psu_led_status_show, NULL); +static struct switch_attribute psu_fan_speed_cal_attr = __ATTR(fan_speed_cal, S_IRUGO, psu_fan_speed_cal_show, NULL); +static struct switch_attribute psu_blackbox_info_attr = __ATTR(blackbox_info, S_IRUGO, psu_blackbox_info_show, NULL); +static struct switch_attribute psu_pmbus_info_attr = __ATTR(pmbus_info, S_IRUGO, psu_pmbus_info_show, NULL); +static struct switch_attribute psu_clear_blackbox_attr = __ATTR(clear_blackbox, S_IWUSR, NULL, psu_clear_blackbox_store); +static SWITCH_DEVICE_ATTR(in_vol_max, S_IRUGO, psu_attr_threshold_show, NULL, PSU_IN_VOL_MAX); +static SWITCH_DEVICE_ATTR(in_vol_min, S_IRUGO, psu_attr_threshold_show, NULL, PSU_IN_VOL_MIN); +static SWITCH_DEVICE_ATTR(in_curr_max, S_IRUGO, psu_attr_threshold_show, NULL, PSU_IN_CURR_MAX); +static SWITCH_DEVICE_ATTR(in_curr_min, S_IRUGO, psu_attr_threshold_show, NULL, PSU_IN_CURR_MIN); +static SWITCH_DEVICE_ATTR(in_power_max, S_IRUGO, psu_attr_threshold_show, NULL, PSU_IN_POWER_MAX); +static SWITCH_DEVICE_ATTR(in_power_min, S_IRUGO, psu_attr_threshold_show, NULL, PSU_IN_POWER_MIN); +static SWITCH_DEVICE_ATTR(out_vol_max, S_IRUGO, psu_attr_threshold_show, NULL, PSU_OUT_VOL_MAX); +static SWITCH_DEVICE_ATTR(out_vol_min, S_IRUGO, psu_attr_threshold_show, NULL, PSU_OUT_VOL_MIN); +static SWITCH_DEVICE_ATTR(out_curr_max, S_IRUGO, psu_attr_threshold_show, NULL, PSU_OUT_CURR_MAX); +static SWITCH_DEVICE_ATTR(out_curr_min, S_IRUGO, psu_attr_threshold_show, NULL, PSU_OUT_CURR_MIN); +static SWITCH_DEVICE_ATTR(out_power_max, S_IRUGO, psu_attr_threshold_show, NULL, PSU_OUT_POWER_MAX); +static SWITCH_DEVICE_ATTR(out_power_min, S_IRUGO, psu_attr_threshold_show, NULL, PSU_OUT_POWER_MIN); +static SWITCH_DEVICE_ATTR(fan_speed_max, S_IRUGO, psu_attr_threshold_show, NULL, PSU_FAN_SPEED_MAX); +static SWITCH_DEVICE_ATTR(fan_speed_min, S_IRUGO, psu_attr_threshold_show, NULL, PSU_FAN_SPEED_MIN); + +static struct attribute *psu_attrs[] = { + &psu_model_name_attr.attr, + &psu_vendor_attr.attr, + &psu_date_attr.attr, + &psu_hw_attr.attr, + &psu_sn_attr.attr, + &psu_pn_attr.attr, + &psu_type_attr.attr, + &psu_in_curr_attr.attr, + &psu_in_vol_attr.attr, + &psu_in_power_attr.attr, + &psu_out_curr_attr.attr, + &psu_out_vol_attr.attr, + &psu_out_power_attr.attr, + &psu_out_max_power_attr.attr, + &psu_num_temps_attr.attr, + &psu_present_attr.attr, + &status_fr_pmbus_attr.attr, + &psu_status_attr.attr, + &psu_hw_status_attr.attr, + &psu_alarm_attr.attr, + &psu_out_status_attr.attr, + &psu_in_status_attr.attr, + &psu_fan_speed_attr.attr, + &psu_fan_ratio_attr.attr, + &psu_fan_direction_attr.attr, + &psu_led_status_attr.attr, + &psu_fan_speed_cal_attr.attr, + &psu_blackbox_info_attr.attr, + &psu_pmbus_info_attr.attr, + &psu_clear_blackbox_attr.attr, + &switch_dev_attr_in_vol_max.switch_attr.attr, + &switch_dev_attr_in_vol_min.switch_attr.attr, + &switch_dev_attr_in_curr_max.switch_attr.attr, + &switch_dev_attr_in_curr_min.switch_attr.attr, + &switch_dev_attr_in_power_max.switch_attr.attr, + &switch_dev_attr_in_power_min.switch_attr.attr, + &switch_dev_attr_out_vol_max.switch_attr.attr, + &switch_dev_attr_out_vol_min.switch_attr.attr, + &switch_dev_attr_out_curr_max.switch_attr.attr, + &switch_dev_attr_out_curr_min.switch_attr.attr, + &switch_dev_attr_out_power_max.switch_attr.attr, + &switch_dev_attr_out_power_min.switch_attr.attr, + &switch_dev_attr_fan_speed_max.switch_attr.attr, + &switch_dev_attr_fan_speed_min.switch_attr.attr, + NULL, +}; + +static struct attribute_group psu_attr_group = { + .attrs = psu_attrs, +}; + +/*******************************psu temp[1-n] dir and attrs*******************************************/ +static struct switch_attribute psu_temp_alias_attr = __ATTR(alias, S_IRUGO, psu_temp_alias_show, NULL); +static struct switch_attribute psu_temp_type_attr = __ATTR(type, S_IRUGO, psu_temp_type_show, NULL); +static struct switch_attribute psu_temp_max_attr = __ATTR(max, S_IRUGO | S_IWUSR, psu_temp_max_show, psu_temp_max_store); +static struct switch_attribute psu_temp_min_attr = __ATTR(min, S_IRUGO | S_IWUSR, psu_temp_min_show, psu_temp_min_store); +static struct switch_attribute psu_temp_value_attr = __ATTR(value, S_IRUGO, psu_temp_value_show, NULL); + +static struct attribute *psu_temp_attrs[] = { + &psu_temp_alias_attr.attr, + &psu_temp_type_attr.attr, + &psu_temp_max_attr.attr, + &psu_temp_min_attr.attr, + &psu_temp_value_attr.attr, + NULL, +}; + +static struct attribute_group psu_temp_attr_group = { + .attrs = psu_temp_attrs, +}; + +static void psuindex_single_temp_remove_kobj_and_attrs(struct psu_obj_s *curr_psu, unsigned int temp_index) +{ + struct temp_obj_s *curr_temp; /* point to temp1 temp2...*/ + + curr_temp = &curr_psu->temp[temp_index - 1]; + if (curr_temp->obj) { + sysfs_remove_group(&curr_temp->obj->kobj, &psu_temp_attr_group); + switch_kobject_delete(&curr_temp->obj); + PSU_DBG("delete psu%u temp%u dir and attrs success.\n", curr_psu->obj->index, temp_index); + } + return; +} + +static int psuindex_single_temp_create_kobj_and_attrs(struct psu_obj_s *curr_psu, unsigned int temp_index) +{ + char name[DIR_NAME_MAX_LEN]; + struct temp_obj_s *curr_temp; /* point to temp1 temp2...*/ + + curr_temp = &curr_psu->temp[temp_index - 1]; + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "temp%u", temp_index); + curr_temp->obj = switch_kobject_create(name, &curr_psu->obj->kobj); + if (!curr_temp->obj) { + PSU_ERR("create psu%u, %s object error!\n", curr_psu->obj->index, name); + return -ENOMEM; + } + curr_temp->obj->index = temp_index; + if (sysfs_create_group(&curr_temp->obj->kobj, &psu_temp_attr_group) != 0) { + PSU_ERR("create psu%u, %s attrs error.\n", curr_psu->obj->index, name); + switch_kobject_delete(&curr_temp->obj); + return -EBADRQC; + } + PSU_DBG("create psu%u, %s success.\n", curr_psu->obj->index, name); + return 0; +} + +static int psuindex_temp_create_kobj_and_attrs(struct psu_obj_s *curr_psu) +{ + unsigned int temp_index, i, temp_num; + + temp_num = curr_psu->temp_number; + curr_psu->temp = kzalloc(sizeof(struct temp_obj_s) * temp_num, GFP_KERNEL); + if (!curr_psu->temp) { + PSU_ERR("kzalloc temp error, psu index: %u, temp number: %u.\n", + curr_psu->obj->index, temp_num); + return -ENOMEM; + } + for(temp_index = 1; temp_index <= temp_num; temp_index++) { + if(psuindex_single_temp_create_kobj_and_attrs(curr_psu, temp_index) != 0 ) { + goto temp_error; + } + } + return 0; +temp_error: + for(i = temp_index; i > 0; i--) { + psuindex_single_temp_remove_kobj_and_attrs(curr_psu, i); + } + kfree(curr_psu->temp); + curr_psu->temp = NULL; + return -EBADRQC; +} + +static void psuindex_temp_remove_kobj_and_attrs(struct psu_obj_s *curr_psu) +{ + unsigned int temp_index, temp_num; + + if (curr_psu->temp) { + temp_num = curr_psu->temp_number; + for (temp_index = temp_num; temp_index > 0; temp_index--) { + psuindex_single_temp_remove_kobj_and_attrs(curr_psu, temp_index); + } + kfree(curr_psu->temp); + curr_psu->temp = NULL; + } + return; +} + +/* create psu temp[1-n] directory and attributes*/ +static int psu_temp_create(void) +{ + int psu_num, temp_num; + unsigned int psu_index, i; + struct psu_obj_s *curr_psu; /* point to psu1 psu2...*/ + + psu_num = g_psu.psu_number; + if (psu_num <= 0) { + PSU_DBG("psu number: %d, skip to create temp* dirs and attrs.\n", psu_num); + return 0; + } + + check_p(g_psu_drv->get_psu_temp_number); + for(psu_index = 1; psu_index <= psu_num; psu_index++) { + temp_num = g_psu_drv->get_psu_temp_number(psu_index); + if (temp_num <= 0) { + PSU_DBG("psu%u temp number: %d, don't need to create temp* dirs and attrs.\n", + psu_index, temp_num); + continue; + } + curr_psu = &g_psu.psu[psu_index - 1]; + curr_psu->temp_number = temp_num; + if(psuindex_temp_create_kobj_and_attrs(curr_psu) != 0) { + goto error; + } + } + return 0; +error: + for(i = psu_index; i > 0; i--) { + curr_psu = &g_psu.psu[i - 1]; + psuindex_temp_remove_kobj_and_attrs(curr_psu); + } + return -EBADRQC; +} + +/* delete psu temp[1-n] directory and attributes*/ +static void psu_temp_remove(void) +{ + unsigned int psu_index; + struct psu_obj_s *curr_psu; + + if (g_psu.psu) { + for(psu_index = g_psu.psu_number; psu_index > 0; psu_index--) { + curr_psu = &g_psu.psu[psu_index - 1]; + psuindex_temp_remove_kobj_and_attrs(curr_psu); + curr_psu->temp_number = 0; + } + } + return; +} + +/* create psu* eeprom attributes */ +static int psu_sub_single_create_eeprom_attrs(unsigned int index) +{ + int ret, eeprom_size; + struct psu_obj_s *curr_psu; + + check_p(g_psu_drv->get_psu_eeprom_size); + eeprom_size = g_psu_drv->get_psu_eeprom_size(index); + if (eeprom_size <= 0) { + PSU_INFO("psu%u, eeprom_size: %d, don't need to creat eeprom attr.\n", + index, eeprom_size); + return 0; + } + + curr_psu = &g_psu.psu[index - 1]; + sysfs_bin_attr_init(&curr_psu->bin); + curr_psu->bin.attr.name = "eeprom"; + curr_psu->bin.attr.mode = 0444; + curr_psu->bin.read = psu_eeprom_read; + curr_psu->bin.size = eeprom_size; + + ret = sysfs_create_bin_file(&curr_psu->obj->kobj, &curr_psu->bin); + if (ret) { + PSU_ERR("psu%u, create eeprom bin error, ret: %d. \n", index, ret); + return -EBADRQC; + } + + PSU_DBG("psu%u, create bin file success, eeprom size:%d.\n", index, eeprom_size); + curr_psu->psu_creat_bin_flag = 1; + return 0; +} + +static int psu_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct psu_obj_s *curr_psu; + + curr_psu = &g_psu.psu[index - 1]; + if (curr_psu->obj) { + if (curr_psu->psu_creat_bin_flag) { + sysfs_remove_bin_file(&curr_psu->obj->kobj, &curr_psu->bin); + curr_psu->psu_creat_bin_flag = 0; + } + sysfs_remove_group(&curr_psu->obj->kobj, &psu_attr_group); + switch_kobject_delete(&curr_psu->obj); + PSU_DBG("delete psu%u dir and attrs success.\n", index); + } + return 0; +} + +static int psu_sub_single_create_kobj(struct kobject *parent, unsigned int index) +{ + char name[DIR_NAME_MAX_LEN]; + struct psu_obj_s *curr_psu; + + curr_psu = &g_psu.psu[index - 1]; + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "psu%u", index); + curr_psu->obj = switch_kobject_create(name, parent); + if (!curr_psu->obj) { + PSU_ERR("create %s object error!\n", name); + return -ENOMEM; + } + curr_psu->obj->index = index; + if (sysfs_create_group(&curr_psu->obj->kobj, &psu_attr_group) != 0) { + PSU_ERR("create %s attrs error.\n", name); + switch_kobject_delete(&curr_psu->obj); + return -EBADRQC; + } + PSU_DBG("create %s dir and attrs success.\n", name); + return 0; +} + + +static int psu_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index) +{ + int ret; + + ret = psu_sub_single_create_kobj(parent, index); + if (ret < 0) { + PSU_ERR("create psu%d dir error.\n", index); + return ret; + } + + psu_sub_single_create_eeprom_attrs(index); + return 0; +} + +static int psu_sub_create_kobj_and_attrs(struct kobject *parent, int psu_num) +{ + unsigned int psu_index, i; + + g_psu.psu = kzalloc(sizeof(struct psu_obj_s) * psu_num, GFP_KERNEL); + if (!g_psu.psu) { + PSU_ERR("kzalloc psu.psu error, psu number = %d.\n", psu_num); + return -ENOMEM; + } + + for (psu_index = 1; psu_index <= psu_num; psu_index++) { + if (psu_sub_single_create_kobj_and_attrs(parent, psu_index) != 0) { + goto error; + } + } + return 0; +error: + for (i = psu_index; i > 0; i--) { + psu_sub_single_remove_kobj_and_attrs(i); + } + kfree(g_psu.psu); + g_psu.psu = NULL; + return -EBADRQC; +} + +/* create psu[1-n] directory and attributes*/ +static int psu_sub_create(void) +{ + int ret; + + ret = psu_sub_create_kobj_and_attrs(&g_psu_obj->kobj, g_psu.psu_number); + return ret; +} + +/* delete psu[1-n] directory and attributes*/ +static void psu_sub_remove(void) +{ + unsigned int psu_index; + + if (g_psu.psu) { + for (psu_index = g_psu.psu_number; psu_index > 0; psu_index--) { + psu_sub_single_remove_kobj_and_attrs(psu_index); + } + kfree(g_psu.psu); + g_psu.psu = NULL; + } + g_psu.psu_number = 0; + return; +} + +/* create psu directory and number attributes*/ +static int psu_root_create(void) +{ + g_psu_obj = switch_kobject_create("psu", NULL); + if (!g_psu_obj) { + PSU_ERR("switch_kobject_create psu error!\n"); + return -ENOMEM; + } + + if (sysfs_create_group(&g_psu_obj->kobj, &psu_root_attr_group) != 0) { + switch_kobject_delete(&g_psu_obj); + PSU_ERR("create psu dir attrs error!\n"); + return -EBADRQC; + } + return 0; +} + +/* delete psu directory and number attributes*/ +static void psu_root_remove(void) +{ + if (g_psu_obj) { + sysfs_remove_group(&g_psu_obj->kobj, &psu_root_attr_group); + switch_kobject_delete(&g_psu_obj); + PSU_DBG("delete psu dir and attrs success.\n"); + } + return; +} + +int s3ip_sysfs_psu_drivers_register(struct s3ip_sysfs_psu_drivers_s *drv) +{ + int ret, psu_num; + + PSU_INFO("s3ip_sysfs_psu_drivers_register...\n"); + if (g_psu_drv) { + PSU_ERR("g_psu_drv is not NULL, can't register\n"); + return -EPERM; + } + + check_p(drv); + check_p(drv->get_psu_number); + g_psu_drv = drv; + + psu_num = g_psu_drv->get_psu_number(); + if (psu_num <= 0) { + PSU_ERR("psu number: %d, don't need to create psu dirs and attrs.\n", psu_num); + g_psu_drv = NULL; + return -EINVAL; + } + + mem_clear(&g_psu, sizeof(struct psu_s)); + g_psu.psu_number = psu_num; + ret = psu_root_create(); + if (ret < 0) { + PSU_ERR("create psu root dir and attrs failed, ret: %d\n", ret); + g_psu_drv = NULL; + return ret; + } + + ret = psu_sub_create(); + if (ret < 0) { + PSU_ERR("create psu sub dir and attrs failed, ret: %d\n", ret); + psu_root_remove(); + g_psu_drv = NULL; + return ret; + } + + ret = psu_temp_create(); + if (ret < 0) { + PSU_ERR("create psu temp dir and attrs failed, ret: %d\n", ret); + psu_sub_remove(); + psu_root_remove(); + g_psu_drv = NULL; + return ret; + } + PSU_INFO("s3ip_sysfs_psu_drivers_register success.\n"); + return 0; +} + +void s3ip_sysfs_psu_drivers_unregister(void) +{ + if (g_psu_drv) { + psu_temp_remove(); + psu_sub_remove(); + psu_root_remove(); + g_psu_drv = NULL; + PSU_DBG("s3ip_sysfs_psu_drivers_unregister success.\n"); + } + + return; +} + +EXPORT_SYMBOL(s3ip_sysfs_psu_drivers_register); +EXPORT_SYMBOL(s3ip_sysfs_psu_drivers_unregister); +module_param(g_psu_loglevel, int, 0644); +MODULE_PARM_DESC(g_psu_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); +module_param(g_psu_present_debug, bool, 0644); +MODULE_PARM_DESC(g_psu_present_debug, "the psu present debug switch(0: disable, 1:enable, defalut: 0).\n"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/slot_sysfs.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/slot_sysfs.c new file mode 100644 index 000000000000..eb3bde77b7dd --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/slot_sysfs.c @@ -0,0 +1,1955 @@ +/* + * An slot_sysfs driver for slot sysfs devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#include "switch.h" +#include "slot_sysfs.h" + +static int g_slot_loglevel = 0; + +#define SLOT_INFO(fmt, args...) do { \ + if (g_slot_loglevel & INFO) { \ + printk(KERN_INFO "[SLOT_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define SLOT_ERR(fmt, args...) do { \ + if (g_slot_loglevel & ERR) { \ + printk(KERN_ERR "[SLOT_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define SLOT_DBG(fmt, args...) do { \ + if (g_slot_loglevel & DBG) { \ + printk(KERN_DEBUG "[SLOT_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct slot_temp_obj_s { + struct switch_obj *obj; +}; + +struct slot_vol_obj_s { + struct switch_obj *obj; +}; + +struct slot_curr_obj_s { + struct switch_obj *obj; +}; + +struct slot_fpga_obj_s { + struct switch_obj *obj; +}; + +struct slot_cpld_obj_s { + struct switch_obj *obj; +}; + +struct slot_obj_s { + unsigned int temp_number; + unsigned int vol_number; + unsigned int curr_number; + unsigned int fpga_number; + unsigned int cpld_number; + struct slot_temp_obj_s *temp; + struct slot_vol_obj_s *vol; + struct slot_curr_obj_s *curr; + struct slot_fpga_obj_s *fpga; + struct slot_cpld_obj_s *cpld; + struct switch_obj *obj; +}; + +struct slot_s { + unsigned int slot_number; + struct slot_obj_s *slot; +}; + +static struct slot_s g_slot; +static struct switch_obj *g_slot_obj = NULL; +static struct s3ip_sysfs_slot_drivers_s *g_slot_drv = NULL; + +static ssize_t slot_number_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_slot.slot_number); +} + +static ssize_t slot_temp_number_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int index; + + index = obj->index; + return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_slot.slot[index - 1].temp_number); +} + +static ssize_t slot_vol_number_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int index; + + index = obj->index; + return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_slot.slot[index - 1].vol_number); +} + +static ssize_t slot_curr_number_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int index; + + index = obj->index; + return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_slot.slot[index - 1].curr_number); +} + +static ssize_t slot_fpga_number_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int index; + + index = obj->index; + return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_slot.slot[index - 1].fpga_number); +} + +static ssize_t slot_cpld_number_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int index; + + index = obj->index; + return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_slot.slot[index - 1].cpld_number); +} + +static ssize_t slot_model_name_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int slot_index; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_model_name); + + slot_index = obj->index; + SLOT_DBG("slot index: %u\n", slot_index); + return g_slot_drv->get_slot_model_name(slot_index, buf, PAGE_SIZE); +} + +static ssize_t slot_vendor_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int slot_index; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_vendor); + + slot_index = obj->index; + SLOT_DBG("slot index: %u\n", slot_index); + return g_slot_drv->get_slot_vendor(slot_index, buf, PAGE_SIZE); +} +static ssize_t slot_sn_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int slot_index; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_serial_number); + + slot_index = obj->index; + SLOT_DBG("slot index: %u\n", slot_index); + return g_slot_drv->get_slot_serial_number(slot_index, buf, PAGE_SIZE); +} + +static ssize_t slot_pn_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_part_number); + + slot_index = obj->index; + SLOT_DBG("slot index: %u\n", slot_index); + return g_slot_drv->get_slot_part_number(slot_index, buf, PAGE_SIZE); +} + +static ssize_t slot_hw_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_hardware_version); + + slot_index = obj->index; + SLOT_DBG("slot index: %u\n", slot_index); + return g_slot_drv->get_slot_hardware_version(slot_index, buf, PAGE_SIZE); +} + +static ssize_t slot_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_status); + + slot_index = obj->index; + SLOT_DBG("slot index: %u\n", slot_index); + return g_slot_drv->get_slot_status(slot_index, buf, PAGE_SIZE); +} + +static ssize_t slot_led_status_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int slot_index; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_led_status); + + slot_index = obj->index; + SLOT_DBG("slot index: %u\n", slot_index); + return g_slot_drv->get_slot_led_status(slot_index, buf, PAGE_SIZE); +} + +static ssize_t slot_led_status_store(struct switch_obj *obj, struct switch_attribute *attr, + const char *buf, size_t count) +{ + unsigned int slot_index; + int ret, led_status; + + check_p(g_slot_drv); + check_p(g_slot_drv->set_slot_led_status); + + slot_index = obj->index; + ret = kstrtoint(buf, 0, &led_status); + if (ret != 0) { + SLOT_ERR("invaild slot led status ret: %d, buf: %s.\n", ret, buf); + return -EINVAL; + } + SLOT_DBG("slot index: %u, led_status: %d\n", slot_index, led_status); + ret = g_slot_drv->set_slot_led_status(slot_index, led_status); + if (ret < 0) { + SLOT_ERR("set slot%u led_status: %d failed, ret: %d\n", slot_index, led_status, ret); + return -EIO; + } + SLOT_DBG("set slot%u led_status: %d success\n", slot_index, led_status); + return count; +} + +/*************************************slot temp*************************************************/ +static ssize_t slot_temp_value_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, temp_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_temp_value); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + temp_index = obj->index; + + SLOT_DBG("slot index: %u, temp index: %u\n", slot_index, temp_index); + return g_slot_drv->get_slot_temp_value(slot_index, temp_index, buf, PAGE_SIZE); +} + +static ssize_t slot_temp_alias_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, temp_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_temp_alias); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + temp_index = obj->index; + + SLOT_DBG("slot index: %u, temp index: %u\n", slot_index, temp_index); + return g_slot_drv->get_slot_temp_alias(slot_index, temp_index, buf, PAGE_SIZE); +} + +static ssize_t slot_temp_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, temp_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_temp_type); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + temp_index = obj->index; + + SLOT_DBG("slot index: %u, temp index: %u\n", slot_index, temp_index); + return g_slot_drv->get_slot_temp_type(slot_index, temp_index, buf, PAGE_SIZE); +} + +static ssize_t slot_temp_max_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, temp_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_temp_max); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + temp_index = obj->index; + + SLOT_DBG("slot index: %u, temp index: %u\n", slot_index, temp_index); + return g_slot_drv->get_slot_temp_max(slot_index, temp_index, buf, PAGE_SIZE); +} + +static ssize_t slot_temp_max_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int slot_index, temp_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->set_slot_temp_max); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + temp_index = obj->index; + ret = g_slot_drv->set_slot_temp_max(slot_index, temp_index, buf, count); + if (ret < 0) { + SLOT_ERR("set slot%u temp%u max threshold failed, value: %s, count: %lu, ret: %d\n", + slot_index, temp_index, buf, count, ret); + return ret; + } + SLOT_DBG("set slot%u temp%u max threshold success, value: %s, count: %lu, ret: %d\n", + slot_index, temp_index, buf, count, ret); + return count; +} + +static ssize_t slot_temp_min_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, temp_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_temp_min); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + temp_index = obj->index; + + SLOT_DBG("slot index: %u, temp index: %u\n", slot_index, temp_index); + return g_slot_drv->get_slot_temp_min(slot_index, temp_index, buf, PAGE_SIZE); +} + +static ssize_t slot_temp_min_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int slot_index, temp_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->set_slot_temp_min); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + temp_index = obj->index; + ret = g_slot_drv->set_slot_temp_min(slot_index, temp_index, buf, count); + if (ret < 0) { + SLOT_ERR("set slot%u temp%u min threshold failed, value: %s, count: %lu, ret: %d\n", + slot_index, temp_index, buf, count, ret); + return ret; + } + SLOT_DBG("set slot%u temp%u min threshold success, value: %s, count: %lu, ret: %d\n", + slot_index, temp_index, buf, count, ret); + return count; +} +/**********************************end of slot temp**********************************************/ + +/*************************************slot vol*************************************************/ +static ssize_t slot_vol_value_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, vol_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_vol_value); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + vol_index = obj->index; + + SLOT_DBG("slot index: %u, vol index: %u\n", slot_index, vol_index); + return g_slot_drv->get_slot_vol_value(slot_index, vol_index, buf, PAGE_SIZE); +} + +static ssize_t slot_vol_alias_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, vol_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_vol_alias); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + vol_index = obj->index; + + SLOT_DBG("slot index: %u, vol index: %u\n", slot_index, vol_index); + return g_slot_drv->get_slot_vol_alias(slot_index, vol_index, buf, PAGE_SIZE); +} + +static ssize_t slot_vol_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, vol_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_vol_type); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + vol_index = obj->index; + + SLOT_DBG("slot index: %u, vol index: %u\n", slot_index, vol_index); + return g_slot_drv->get_slot_vol_type(slot_index, vol_index, buf, PAGE_SIZE); +} + +static ssize_t slot_vol_max_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, vol_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_vol_max); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + vol_index = obj->index; + + SLOT_DBG("slot index: %u, vol index: %u\n", slot_index, vol_index); + return g_slot_drv->get_slot_vol_max(slot_index, vol_index, buf, PAGE_SIZE); +} + +static ssize_t slot_vol_max_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int slot_index, vol_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->set_slot_vol_max); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + vol_index = obj->index; + ret = g_slot_drv->set_slot_vol_max(slot_index, vol_index, buf, count); + if (ret < 0) { + SLOT_ERR("set slot%u vol%u max threshold failed, value: %s, count: %lu, ret: %d\n", + slot_index, vol_index, buf, count, ret); + return ret; + } + SLOT_DBG("set slot%u vol%u max threshold success, value: %s, count: %lu, ret: %d\n", + slot_index, vol_index, buf, count, ret); + return count; +} + +static ssize_t slot_vol_min_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, vol_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_vol_min); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + vol_index = obj->index; + + SLOT_DBG("slot index: %u, vol index: %u\n", slot_index, vol_index); + return g_slot_drv->get_slot_vol_min(slot_index, vol_index, buf, PAGE_SIZE); +} + +static ssize_t slot_vol_min_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int slot_index, vol_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->set_slot_vol_min); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + vol_index = obj->index; + ret = g_slot_drv->set_slot_vol_min(slot_index, vol_index, buf, count); + if (ret < 0) { + SLOT_ERR("set slot%u vol%u min threshold failed, value: %s, count: %lu, ret: %d\n", + slot_index, vol_index, buf, count, ret); + return ret; + } + SLOT_DBG("set slot%u vol%u min threshold success, value: %s, count: %lu, ret: %d\n", + slot_index, vol_index, buf, count, ret); + return count; +} + +static ssize_t slot_vol_range_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, vol_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_vol_range); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + vol_index = obj->index; + + SLOT_DBG("slot index: %u, vol index: %u\n", slot_index, vol_index); + return g_slot_drv->get_slot_vol_range(slot_index, vol_index, buf, PAGE_SIZE); +} + +static ssize_t slot_vol_nominal_value_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, vol_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_vol_nominal_value); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + vol_index = obj->index; + + SLOT_DBG("slot index: %u, vol index: %u\n", slot_index, vol_index); + return g_slot_drv->get_slot_vol_nominal_value(slot_index, vol_index, buf, PAGE_SIZE); +} +/**********************************end of slot vol**********************************************/ +/*************************************slot curr*************************************************/ +static ssize_t slot_curr_value_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, curr_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_curr_value); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + curr_index = obj->index; + + SLOT_DBG("slot index: %u, curr index: %u\n", slot_index, curr_index); + return g_slot_drv->get_slot_curr_value(slot_index, curr_index, buf, PAGE_SIZE); +} + +static ssize_t slot_curr_alias_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, curr_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_curr_alias); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + curr_index = obj->index; + + SLOT_DBG("slot index: %u, curr index: %u\n", slot_index, curr_index); + return g_slot_drv->get_slot_curr_alias(slot_index, curr_index, buf, PAGE_SIZE); +} + +static ssize_t slot_curr_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, curr_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_curr_type); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + curr_index = obj->index; + + SLOT_DBG("slot index: %u, curr index: %u\n", slot_index, curr_index); + return g_slot_drv->get_slot_curr_type(slot_index, curr_index, buf, PAGE_SIZE); +} + +static ssize_t slot_curr_max_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, curr_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_curr_max); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + curr_index = obj->index; + + SLOT_DBG("slot index: %u, curr index: %u\n", slot_index, curr_index); + return g_slot_drv->get_slot_curr_max(slot_index, curr_index, buf, PAGE_SIZE); +} + +static ssize_t slot_curr_max_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int slot_index, curr_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->set_slot_curr_max); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + curr_index = obj->index; + return g_slot_drv->set_slot_curr_max(slot_index, curr_index, buf, count); + if (ret < 0) { + SLOT_ERR("set slot%u curr%u max threshold failed, value: %s, count: %lu, ret: %d\n", + slot_index, curr_index, buf, count, ret); + return ret; + } + SLOT_DBG("set slot%u curr%u max threshold success, value: %s, count: %lu, ret: %d\n", + slot_index, curr_index, buf, count, ret); + return count; +} + +static ssize_t slot_curr_min_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, curr_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_curr_min); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + curr_index = obj->index; + + SLOT_DBG("slot index: %u, curr index: %u\n", slot_index, curr_index); + return g_slot_drv->get_slot_curr_min(slot_index, curr_index, buf, PAGE_SIZE); +} + +static ssize_t slot_curr_min_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int slot_index, curr_index; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->set_slot_curr_min); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + curr_index = obj->index; + ret = g_slot_drv->set_slot_curr_min(slot_index, curr_index, buf, count); + if (ret < 0) { + SLOT_ERR("set slot%u curr%u min threshold failed, value: %s, count: %lu, ret: %d\n", + slot_index, curr_index, buf, count, ret); + return ret; + } + SLOT_DBG("set slot%u curr%u min threshold success, value: %s, count: %lu, ret: %d\n", + slot_index, curr_index, buf, count, ret); + return count; +} +/**********************************end of slot curr**********************************************/ +/*************************************slot fpga*************************************************/ +static ssize_t slot_fpga_alias_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, fpga_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_fpga_alias); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + fpga_index = obj->index; + + SLOT_DBG("slot index: %u, fpga index: %u\n", slot_index, fpga_index); + return g_slot_drv->get_slot_fpga_alias(slot_index, fpga_index, buf, PAGE_SIZE); +} + +static ssize_t slot_fpga_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, fpga_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_fpga_type); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + fpga_index = obj->index; + + SLOT_DBG("slot index: %u, fpga index: %u\n", slot_index, fpga_index); + return g_slot_drv->get_slot_fpga_type(slot_index, fpga_index, buf, PAGE_SIZE); +} + +static ssize_t slot_fpga_fw_version_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int slot_index, fpga_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_fpga_firmware_version); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + fpga_index = obj->index; + + SLOT_DBG("slot index: %u, fpga index: %u\n", slot_index, fpga_index); + return g_slot_drv->get_slot_fpga_firmware_version(slot_index, fpga_index, buf, PAGE_SIZE); +} + +static ssize_t slot_fpga_board_version_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int slot_index, fpga_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_fpga_board_version); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + fpga_index = obj->index; + + SLOT_DBG("slot index: %u, fpga index: %u\n", slot_index, fpga_index); + return g_slot_drv->get_slot_fpga_board_version(slot_index, fpga_index, buf, PAGE_SIZE); +} + +static ssize_t slot_fpga_test_reg_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int slot_index, fpga_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_fpga_test_reg); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + fpga_index = obj->index; + + SLOT_DBG("slot index: %u, fpga index: %u\n", slot_index, fpga_index); + return g_slot_drv->get_slot_fpga_test_reg(slot_index, fpga_index, buf, PAGE_SIZE); +} + +static ssize_t slot_fpga_test_reg_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int slot_index, fpga_index, value; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->set_slot_fpga_test_reg); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + fpga_index = obj->index; + sscanf(buf, "0x%x", &value); + ret = g_slot_drv->set_slot_fpga_test_reg(slot_index, fpga_index, value); + if (ret < 0) { + SLOT_ERR("set slot%u fpga%u test reg failed, value:0x%x, ret: %d.\n", + slot_index, fpga_index, value, ret); + return ret; + } + SLOT_DBG("set slot%u fpga%u test reg success, value: 0x%x.\n", slot_index, fpga_index, value); + return count; +} +/**********************************end of slot fpga**********************************************/ +/*************************************slot cpld*************************************************/ +static ssize_t slot_cpld_alias_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, cpld_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_cpld_alias); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + cpld_index = obj->index; + + SLOT_DBG("slot index: %u, cpld index: %u\n", slot_index, cpld_index); + return g_slot_drv->get_slot_cpld_alias(slot_index, cpld_index, buf, PAGE_SIZE); +} + +static ssize_t slot_cpld_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int slot_index, cpld_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_cpld_type); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + cpld_index = obj->index; + + SLOT_DBG("slot index: %u, cpld index: %u\n", slot_index, cpld_index); + return g_slot_drv->get_slot_cpld_type(slot_index, cpld_index, buf, PAGE_SIZE); +} + +static ssize_t slot_cpld_fw_version_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int slot_index, cpld_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_cpld_firmware_version); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + cpld_index = obj->index; + + SLOT_DBG("slot index: %u, cpld index: %u\n", slot_index, cpld_index); + return g_slot_drv->get_slot_cpld_firmware_version(slot_index, cpld_index, buf, PAGE_SIZE); +} + +static ssize_t slot_cpld_board_version_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int slot_index, cpld_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_cpld_board_version); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + cpld_index = obj->index; + + SLOT_DBG("slot index: %u, cpld index: %u\n", slot_index, cpld_index); + return g_slot_drv->get_slot_cpld_board_version(slot_index, cpld_index, buf, PAGE_SIZE); +} + +static ssize_t slot_cpld_test_reg_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int slot_index, cpld_index; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_cpld_test_reg); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + cpld_index = obj->index; + + SLOT_DBG("slot index: %u, cpld index: %u\n", slot_index, cpld_index); + return g_slot_drv->get_slot_cpld_test_reg(slot_index, cpld_index, buf, PAGE_SIZE); +} + +static ssize_t slot_cpld_test_reg_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int slot_index, cpld_index, value; + int ret; + struct switch_obj *p_obj; + + check_p(g_slot_drv); + check_p(g_slot_drv->set_slot_cpld_test_reg); + + p_obj = to_switch_obj(obj->kobj.parent); + slot_index = p_obj->index; + cpld_index = obj->index; + sscanf(buf, "0x%x", &value); + ret = g_slot_drv->set_slot_cpld_test_reg(slot_index, cpld_index, value); + if (ret < 0) { + SLOT_ERR("set slot%u cpld%u test reg failed, value:0x%x, ret: %d.\n", + slot_index, cpld_index, value, ret); + return ret; + } + SLOT_DBG("set slot%u cpld%u test reg success, value: 0x%x.\n", slot_index, cpld_index, value); + return count; +} + +static ssize_t slot_power_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int slot_index; + + check_p(g_slot_drv); + check_p(g_slot_drv->get_slot_power_status); + + slot_index = obj->index; + SLOT_DBG("slot index: %u\n", slot_index); + return g_slot_drv->get_slot_power_status(slot_index, buf, PAGE_SIZE); +} + +static ssize_t slot_power_store(struct switch_obj *obj, struct switch_attribute *attr, + const char *buf, size_t count) +{ + unsigned int slot_index; + int ret, power; + + check_p(g_slot_drv); + check_p(g_slot_drv->set_slot_power_status); + + slot_index = obj->index; + ret = kstrtoint(buf, 0, &power); + if (ret != 0) { + SLOT_ERR("invaild slot power status ret: %d, buf: %s.\n", ret, buf); + return -EINVAL; + } + SLOT_DBG("slot index: %u, power: %d\n", slot_index, power); + ret = g_slot_drv->set_slot_power_status(slot_index, power); + if (ret < 0) { + SLOT_ERR("set slot%u power: %d failed, ret: %d\n", slot_index, power, ret); + return ret; + } + SLOT_DBG("set slot%u power: %d success\n", slot_index, power); + return count; +} +/**********************************end of slot cpld**********************************************/ +/**********************************slot dir and attrs********************************************/ +static struct switch_attribute slot_number_attr = __ATTR(number, S_IRUGO, slot_number_show, NULL); + +static struct attribute *slot_dir_attrs[] = { + &slot_number_attr.attr, + NULL, +}; + +static struct attribute_group slot_root_attr_group = { + .attrs = slot_dir_attrs, +}; + +/*******************************slot[1-n] dir and attrs*******************************************/ +static struct switch_attribute slot_model_name_attr = __ATTR(model_name, S_IRUGO, slot_model_name_show, NULL); +static struct switch_attribute slot_vendor_attr = __ATTR(vendor, S_IRUGO, slot_vendor_show, NULL); +static struct switch_attribute slot_hw_attr = __ATTR(hardware_version, S_IRUGO, slot_hw_show, NULL); +static struct switch_attribute slot_sn_attr = __ATTR(serial_number, S_IRUGO, slot_sn_show, NULL); +static struct switch_attribute slot_pn_attr = __ATTR(part_number, S_IRUGO, slot_pn_show, NULL); +static struct switch_attribute slot_status_attr = __ATTR(status, S_IRUGO, slot_status_show, NULL); +static struct switch_attribute slot_led_status_attr = __ATTR(led_status, S_IRUGO | S_IWUSR, slot_led_status_show, slot_led_status_store); +static struct switch_attribute slot_power_on_attr = __ATTR(power_on, S_IRUGO | S_IWUSR, slot_power_show, slot_power_store); +static struct switch_attribute num_temp_sensors_attr = __ATTR(num_temp_sensors, S_IRUGO, slot_temp_number_show, NULL); +static struct switch_attribute num_vol_sensors_attr = __ATTR(num_vol_sensors, S_IRUGO, slot_vol_number_show, NULL); +static struct switch_attribute num_curr_sensors_attr = __ATTR(num_curr_sensors, S_IRUGO, slot_curr_number_show, NULL); +static struct switch_attribute num_fpga_attr = __ATTR(num_fpgas, S_IRUGO, slot_fpga_number_show, NULL); +static struct switch_attribute num_cpld_attr = __ATTR(num_cplds, S_IRUGO, slot_cpld_number_show, NULL); + +static struct attribute *slot_attrs[] = { + &slot_model_name_attr.attr, + &slot_vendor_attr.attr, + &slot_power_on_attr.attr, + &slot_hw_attr.attr, + &slot_sn_attr.attr, + &slot_pn_attr.attr, + &slot_status_attr.attr, + &slot_led_status_attr.attr, + &num_temp_sensors_attr.attr, + &num_vol_sensors_attr.attr, + &num_curr_sensors_attr.attr, + &num_fpga_attr.attr, + &num_cpld_attr.attr, + NULL, +}; + +static struct attribute_group slot_attr_group = { + .attrs = slot_attrs, +}; + +/*******************************slot temp[1-n] dir and attrs*******************************************/ +static struct switch_attribute slot_temp_alias_attr = __ATTR(alias, S_IRUGO, slot_temp_alias_show, NULL); +static struct switch_attribute slot_temp_type_attr = __ATTR(type, S_IRUGO, slot_temp_type_show, NULL); +static struct switch_attribute slot_temp_max_attr = __ATTR(max, S_IRUGO | S_IWUSR, slot_temp_max_show, slot_temp_max_store); +static struct switch_attribute slot_temp_min_attr = __ATTR(min, S_IRUGO | S_IWUSR, slot_temp_min_show, slot_temp_min_store); +static struct switch_attribute slot_temp_value_attr = __ATTR(value, S_IRUGO, slot_temp_value_show, NULL); + +static struct attribute *slot_temp_attrs[] = { + &slot_temp_alias_attr.attr, + &slot_temp_type_attr.attr, + &slot_temp_max_attr.attr, + &slot_temp_min_attr.attr, + &slot_temp_value_attr.attr, + NULL, +}; + +static struct attribute_group slot_temp_attr_group = { + .attrs = slot_temp_attrs, +}; + +/*******************************slot vol[1-n] dir and attrs*******************************************/ +static struct switch_attribute slot_vol_alias_attr = __ATTR(alias, S_IRUGO, slot_vol_alias_show, NULL); +static struct switch_attribute slot_vol_type_attr = __ATTR(type, S_IRUGO, slot_vol_type_show, NULL); +static struct switch_attribute slot_vol_max_attr = __ATTR(max, S_IRUGO | S_IWUSR, slot_vol_max_show, slot_vol_max_store); +static struct switch_attribute slot_vol_min_attr = __ATTR(min, S_IRUGO | S_IWUSR, slot_vol_min_show, slot_vol_min_store); +static struct switch_attribute slot_vol_value_attr = __ATTR(value, S_IRUGO, slot_vol_value_show, NULL); +static struct switch_attribute slot_vol_range_attr = __ATTR(range, S_IRUGO, slot_vol_range_show, NULL); +static struct switch_attribute slot_vol_nominal_value_attr = __ATTR(nominal_value, S_IRUGO, slot_vol_nominal_value_show, NULL); + +static struct attribute *slot_vol_attrs[] = { + &slot_vol_alias_attr.attr, + &slot_vol_type_attr.attr, + &slot_vol_max_attr.attr, + &slot_vol_min_attr.attr, + &slot_vol_value_attr.attr, + &slot_vol_range_attr.attr, + &slot_vol_nominal_value_attr.attr, + NULL, +}; + +static struct attribute_group slot_vol_attr_group = { + .attrs = slot_vol_attrs, +}; + +/*******************************slot curr[1-n] dir and attrs*******************************************/ +static struct switch_attribute slot_curr_alias_attr = __ATTR(alias, S_IRUGO, slot_curr_alias_show, NULL); +static struct switch_attribute slot_curr_type_attr = __ATTR(type, S_IRUGO, slot_curr_type_show, NULL); +static struct switch_attribute slot_curr_max_attr = __ATTR(max, S_IRUGO | S_IWUSR, slot_curr_max_show, slot_curr_max_store); +static struct switch_attribute slot_curr_min_attr = __ATTR(min, S_IRUGO | S_IWUSR, slot_curr_min_show, slot_curr_min_store); +static struct switch_attribute slot_curr_value_attr = __ATTR(value, S_IRUGO, slot_curr_value_show, NULL); + +static struct attribute *slot_curr_attrs[] = { + &slot_curr_alias_attr.attr, + &slot_curr_type_attr.attr, + &slot_curr_max_attr.attr, + &slot_curr_min_attr.attr, + &slot_curr_value_attr.attr, + NULL, +}; + +static struct attribute_group slot_curr_attr_group = { + .attrs = slot_curr_attrs, +}; + +/*******************************slot fpga[1-n] dir and attrs*******************************************/ +static struct switch_attribute slot_fpga_alias_attr = __ATTR(alias, S_IRUGO, slot_fpga_alias_show, NULL); +static struct switch_attribute slot_fpga_type_attr = __ATTR(type, S_IRUGO, slot_fpga_type_show, NULL); +static struct switch_attribute slot_fpga_fw_version_attr = __ATTR(firmware_version, S_IRUGO, slot_fpga_fw_version_show, NULL); +static struct switch_attribute slot_fpga_board_version_attr = __ATTR(board_version, S_IRUGO, slot_fpga_board_version_show, NULL); +static struct switch_attribute slot_fpga_test_reg_attr = __ATTR(reg_test, S_IRUGO | S_IWUSR, slot_fpga_test_reg_show, slot_fpga_test_reg_store); + +static struct attribute *slot_fpga_attrs[] = { + &slot_fpga_alias_attr.attr, + &slot_fpga_type_attr.attr, + &slot_fpga_fw_version_attr.attr, + &slot_fpga_board_version_attr.attr, + &slot_fpga_test_reg_attr.attr, + NULL, +}; + +static struct attribute_group slot_fpga_attr_group = { + .attrs = slot_fpga_attrs, +}; + +/*******************************slot cpld[1-n] dir and attrs*******************************************/ +static struct switch_attribute slot_cpld_alias_attr = __ATTR(alias, S_IRUGO, slot_cpld_alias_show, NULL); +static struct switch_attribute slot_cpld_type_attr = __ATTR(type, S_IRUGO, slot_cpld_type_show, NULL); +static struct switch_attribute slot_cpld_fw_version_attr = __ATTR(firmware_version, S_IRUGO, slot_cpld_fw_version_show, NULL); +static struct switch_attribute slot_cpld_board_version_attr = __ATTR(board_version, S_IRUGO, slot_cpld_board_version_show, NULL); +static struct switch_attribute slot_cpld_test_reg_attr = __ATTR(reg_test, S_IRUGO | S_IWUSR, slot_cpld_test_reg_show, slot_cpld_test_reg_store); + +static struct attribute *slot_cpld_attrs[] = { + &slot_cpld_alias_attr.attr, + &slot_cpld_type_attr.attr, + &slot_cpld_fw_version_attr.attr, + &slot_cpld_board_version_attr.attr, + &slot_cpld_test_reg_attr.attr, + NULL, +}; + +static struct attribute_group slot_cpld_attr_group = { + .attrs = slot_cpld_attrs, +}; + +/***************************************slot cpld*****************************************/ +static void slotindex_single_cpld_remove_kobj_and_attrs(struct slot_obj_s *curr_slot, + unsigned int cpld_index) +{ + struct slot_cpld_obj_s *curr_cpld; + + curr_cpld = &curr_slot->cpld[cpld_index - 1]; + if (curr_cpld->obj) { + sysfs_remove_group(&curr_cpld->obj->kobj, &slot_cpld_attr_group); + switch_kobject_delete(&curr_cpld->obj); + SLOT_DBG("delete slot%u cpld%u dir and attrs success.\n", curr_slot->obj->index, + cpld_index); + } + return; +} + +static int slotindex_single_cpld_create_kobj_and_attrs(struct slot_obj_s *curr_slot, + unsigned int cpld_index) +{ + char name[DIR_NAME_MAX_LEN]; + struct slot_cpld_obj_s *curr_cpld; + + curr_cpld = &curr_slot->cpld[cpld_index - 1]; + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "cpld%u", cpld_index); + curr_cpld->obj = switch_kobject_create(name, &curr_slot->obj->kobj); + if (!curr_cpld->obj) { + SLOT_ERR("create slot%u %s object error!\n", curr_slot->obj->index, name); + return -ENOMEM; + } + curr_cpld->obj->index = cpld_index; + if (sysfs_create_group(&curr_cpld->obj->kobj, &slot_cpld_attr_group) != 0) { + SLOT_ERR("create slot%u %s attrs error.\n", curr_slot->obj->index, name); + switch_kobject_delete(&curr_cpld->obj); + return -EBADRQC; + } + SLOT_DBG("create slot%u %s success.\n", curr_slot->obj->index, name); + return 0; +} + +static void slotindex_cpld_remove_kobj_and_attrs(struct slot_obj_s *curr_slot) +{ + unsigned int cpld_index, cpld_num; + + if (curr_slot->cpld) { + cpld_num = curr_slot->cpld_number; + for (cpld_index = cpld_num; cpld_index > 0; cpld_index--) { + slotindex_single_cpld_remove_kobj_and_attrs(curr_slot, cpld_index); + } + kfree(curr_slot->cpld); + curr_slot->cpld = NULL; + } + return; +} + +static int slotindex_cpld_create_kobj_and_attrs(struct slot_obj_s *curr_slot) +{ + unsigned int cpld_index, i, cpld_num; + + cpld_num = curr_slot->cpld_number; + curr_slot->cpld = kzalloc(sizeof(struct slot_cpld_obj_s) * cpld_num, GFP_KERNEL); + if (!curr_slot->cpld) { + SLOT_ERR("kzalloc slot cpld error, slot index: %u, cpld number: %u.\n", + curr_slot->obj->index, cpld_num); + return -ENOMEM; + } + + for (cpld_index = 1; cpld_index <= cpld_num; cpld_index++) { + if (slotindex_single_cpld_create_kobj_and_attrs(curr_slot, cpld_index) != 0) { + goto error; + } + } + return 0; +error: + for (i = cpld_index; i > 0; i--) { + slotindex_single_cpld_remove_kobj_and_attrs(curr_slot, i); + } + kfree(curr_slot->cpld); + curr_slot->cpld = NULL; + return -EBADRQC; +} + +/* create slot cpld[1-n] directory and attributes*/ +static int slot_cpld_create(void) +{ + int cpld_num; + unsigned int slot_index, i; + struct slot_obj_s *curr_slot; + + check_p(g_slot_drv->get_slot_cpld_number); + for (slot_index = 1; slot_index <= g_slot.slot_number; slot_index++) { + cpld_num = g_slot_drv->get_slot_cpld_number(slot_index); + if (cpld_num <= 0) { + SLOT_DBG("slot%u cpld number: %d, don't need to create cpld* dirs and attrs.\n", + slot_index, cpld_num); + continue; + } + curr_slot = &g_slot.slot[slot_index - 1]; + curr_slot->cpld_number = cpld_num; + if (slotindex_cpld_create_kobj_and_attrs(curr_slot) != 0) { + goto error; + } + } + return 0; +error: + for (i = slot_index; i > 0; i--) { + curr_slot = &g_slot.slot[i - 1]; + slotindex_cpld_remove_kobj_and_attrs(curr_slot); + } + return -EBADRQC; +} + +/* delete slot cpld[1-n] directory and attributes*/ +static void slot_cpld_remove(void) +{ + unsigned int slot_index; + struct slot_obj_s *curr_slot; + + if (g_slot.slot) { + for (slot_index = g_slot.slot_number; slot_index > 0; slot_index--) { + curr_slot = &g_slot.slot[slot_index - 1]; + slotindex_cpld_remove_kobj_and_attrs(curr_slot); + curr_slot->cpld_number = 0; + } + } + return; +} +/************************************end of slot cpld**************************************/ +/***************************************slot fpga*****************************************/ +static void slotindex_single_fpga_remove_kobj_and_attrs(struct slot_obj_s *curr_slot, + unsigned int fpga_index) +{ + struct slot_fpga_obj_s *curr_fpga; + + curr_fpga = &curr_slot->fpga[fpga_index - 1]; + if (curr_fpga->obj) { + sysfs_remove_group(&curr_fpga->obj->kobj, &slot_fpga_attr_group); + switch_kobject_delete(&curr_fpga->obj); + SLOT_DBG("delete slot%u fpga%u dir and attrs success.\n", curr_slot->obj->index, + fpga_index); + } + return; +} + +static int slotindex_single_fpga_create_kobj_and_attrs(struct slot_obj_s *curr_slot, + unsigned int fpga_index) +{ + char name[DIR_NAME_MAX_LEN]; + struct slot_fpga_obj_s *curr_fpga; + + curr_fpga = &curr_slot->fpga[fpga_index - 1]; + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "fpga%u", fpga_index); + curr_fpga->obj = switch_kobject_create(name, &curr_slot->obj->kobj); + if (!curr_fpga->obj) { + SLOT_ERR("create slot%u %s object error!\n", curr_slot->obj->index, name); + return -ENOMEM; + } + curr_fpga->obj->index = fpga_index; + if (sysfs_create_group(&curr_fpga->obj->kobj, &slot_fpga_attr_group) != 0) { + SLOT_ERR("create slot%u %s attrs error.\n", curr_slot->obj->index, name); + switch_kobject_delete(&curr_fpga->obj); + return -EBADRQC; + } + SLOT_DBG("create slot%u %s success.\n", curr_slot->obj->index, name); + return 0; +} + +static void slotindex_fpga_remove_kobj_and_attrs(struct slot_obj_s *curr_slot) +{ + unsigned int fpga_index, fpga_num; + + if (curr_slot->fpga) { + fpga_num = curr_slot->fpga_number; + for (fpga_index = fpga_num; fpga_index > 0; fpga_index--) { + slotindex_single_fpga_remove_kobj_and_attrs(curr_slot, fpga_index); + } + kfree(curr_slot->fpga); + curr_slot->fpga = NULL; + } + return; +} + +static int slotindex_fpga_create_kobj_and_attrs(struct slot_obj_s *curr_slot) +{ + unsigned int fpga_index, i, fpga_num; + + fpga_num = curr_slot->fpga_number; + curr_slot->fpga = kzalloc(sizeof(struct slot_fpga_obj_s) * fpga_num, GFP_KERNEL); + if (!curr_slot->fpga) { + SLOT_ERR("kzalloc slot fpga error, slot index: %u, fpga number: %u.\n", + curr_slot->obj->index, fpga_num); + return -ENOMEM; + } + + for (fpga_index = 1; fpga_index <= fpga_num; fpga_index++) { + if (slotindex_single_fpga_create_kobj_and_attrs(curr_slot, fpga_index) != 0) { + goto error; + } + } + return 0; +error: + for (i = fpga_index; i > 0; i--) { + slotindex_single_fpga_remove_kobj_and_attrs(curr_slot, i); + } + kfree(curr_slot->fpga); + curr_slot->fpga = NULL; + return -EBADRQC; +} + +/* create slot fpga[1-n] directory and attributes*/ +static int slot_fpga_create(void) +{ + int fpga_num; + unsigned int slot_index, i; + struct slot_obj_s *curr_slot; + + check_p(g_slot_drv->get_slot_fpga_number); + for (slot_index = 1; slot_index <= g_slot.slot_number; slot_index++) { + fpga_num = g_slot_drv->get_slot_fpga_number(slot_index); + if (fpga_num <= 0) { + SLOT_DBG("slot%u fpga number: %d, don't need to create fpga* dirs and attrs.\n", + slot_index, fpga_num); + continue; + } + curr_slot = &g_slot.slot[slot_index - 1]; + curr_slot->fpga_number = fpga_num; + if (slotindex_fpga_create_kobj_and_attrs(curr_slot) != 0) { + goto error; + } + } + return 0; +error: + for (i = slot_index; i > 0; i--) { + curr_slot = &g_slot.slot[i - 1]; + slotindex_fpga_remove_kobj_and_attrs(curr_slot); + } + return -EBADRQC; +} + +/* delete slot fpga[1-n] directory and attributes*/ +static void slot_fpga_remove(void) +{ + unsigned int slot_index; + struct slot_obj_s *curr_slot; + + if (g_slot.slot) { + for (slot_index = g_slot.slot_number; slot_index > 0; slot_index--) { + curr_slot = &g_slot.slot[slot_index - 1]; + slotindex_fpga_remove_kobj_and_attrs(curr_slot); + curr_slot->fpga_number = 0; + } + } + return; +} +/************************************end of slot fpga**************************************/ +/*************************************slot current*****************************************/ +static void slotindex_single_curr_remove_kobj_and_attrs(struct slot_obj_s *curr_slot, + unsigned int curr_index) +{ + struct slot_curr_obj_s *curr; + + curr = &curr_slot->curr[curr_index - 1]; + if (curr->obj) { + sysfs_remove_group(&curr->obj->kobj, &slot_curr_attr_group); + switch_kobject_delete(&curr->obj); + SLOT_DBG("delete slot%u curr_sensor%u dir and attrs success.\n", curr_slot->obj->index, + curr_index); + } + return; +} + +static int slotindex_single_curr_create_kobj_and_attrs(struct slot_obj_s *curr_slot, + unsigned int curr_index) +{ + char name[DIR_NAME_MAX_LEN]; + struct slot_curr_obj_s *curr; + + curr = &curr_slot->curr[curr_index - 1]; + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "curr_sensor%u", curr_index); + curr->obj = switch_kobject_create(name, &curr_slot->obj->kobj); + if (!curr->obj) { + SLOT_ERR("create slot%u %s object error!\n", curr_slot->obj->index, name); + return -ENOMEM; + } + curr->obj->index = curr_index; + if (sysfs_create_group(&curr->obj->kobj, &slot_curr_attr_group) != 0) { + SLOT_ERR("create slot%u %s attrs error.\n", curr_slot->obj->index, name); + switch_kobject_delete(&curr->obj); + return -EBADRQC; + } + SLOT_DBG("create slot%u %s success.\n", curr_slot->obj->index, name); + return 0; +} + +static void slotindex_curr_remove_kobj_and_attrs(struct slot_obj_s *curr_slot) +{ + unsigned int curr_index, curr_num; + + if (curr_slot->curr) { + curr_num = curr_slot->curr_number; + for (curr_index = curr_num; curr_index > 0; curr_index--) { + slotindex_single_curr_remove_kobj_and_attrs(curr_slot, curr_index); + } + kfree(curr_slot->curr); + curr_slot->curr = NULL; + } + return; +} + +static int slotindex_curr_create_kobj_and_attrs(struct slot_obj_s *curr_slot) +{ + unsigned int curr_index, i, curr_num; + + curr_num = curr_slot->curr_number; + curr_slot->curr = kzalloc(sizeof(struct slot_curr_obj_s) * curr_num, GFP_KERNEL); + if (!curr_slot->curr) { + SLOT_ERR("kzalloc slot curr error, slot index: %u, curr number: %u.\n", + curr_slot->obj->index, curr_num); + return -ENOMEM; + } + + for (curr_index = 1; curr_index <= curr_num; curr_index++) { + if (slotindex_single_curr_create_kobj_and_attrs(curr_slot, curr_index) != 0) { + goto error; + } + } + return 0; +error: + for (i = curr_index; i > 0; i--) { + slotindex_single_curr_remove_kobj_and_attrs(curr_slot, i); + } + kfree(curr_slot->curr); + curr_slot->curr = NULL; + return -EBADRQC; +} + +/* create slot curr_snesor[1-n] directory and attributes*/ +static int slot_curr_create(void) +{ + int curr_num; + unsigned int slot_index, i; + struct slot_obj_s *curr_slot; + + check_p(g_slot_drv->get_slot_curr_number); + for (slot_index = 1; slot_index <= g_slot.slot_number; slot_index++) { + curr_num = g_slot_drv->get_slot_curr_number(slot_index); + if (curr_num <= 0) { + SLOT_DBG("slot%u curr number: %d, don't need to create curr_sensor* dirs and attrs.\n", + slot_index, curr_num); + continue; + } + curr_slot = &g_slot.slot[slot_index - 1]; + curr_slot->curr_number = curr_num; + if (slotindex_curr_create_kobj_and_attrs(curr_slot) != 0) { + goto error; + } + } + return 0; +error: + for (i = slot_index; i > 0; i--) { + curr_slot = &g_slot.slot[i - 1]; + slotindex_curr_remove_kobj_and_attrs(curr_slot); + } + return -EBADRQC; +} + +/* delete slot curr_sensor[1-n] directory and attributes*/ +static void slot_curr_remove(void) +{ + unsigned int slot_index; + struct slot_obj_s *curr_slot; + + if (g_slot.slot) { + for (slot_index = g_slot.slot_number; slot_index > 0; slot_index--) { + curr_slot = &g_slot.slot[slot_index - 1]; + slotindex_curr_remove_kobj_and_attrs(curr_slot); + curr_slot->curr_number = 0; + } + } + return; +} +/**********************************end of slot current************************************/ +/*************************************slot voltage****************************************/ +static void slotindex_single_vol_remove_kobj_and_attrs(struct slot_obj_s *curr_slot, + unsigned int vol_index) +{ + struct slot_vol_obj_s *curr_vol; + + curr_vol = &curr_slot->vol[vol_index - 1]; + if (curr_vol->obj) { + sysfs_remove_group(&curr_vol->obj->kobj, &slot_vol_attr_group); + switch_kobject_delete(&curr_vol->obj); + SLOT_DBG("delete slot%u vol_sensor%u dir and attrs success.\n", curr_slot->obj->index, + vol_index); + } + return; +} + +static int slotindex_single_vol_create_kobj_and_attrs(struct slot_obj_s *curr_slot, + unsigned int vol_index) +{ + char name[DIR_NAME_MAX_LEN]; + struct slot_vol_obj_s *curr_vol; + + curr_vol = &curr_slot->vol[vol_index - 1]; + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "vol_sensor%u", vol_index); + curr_vol->obj = switch_kobject_create(name, &curr_slot->obj->kobj); + if (!curr_vol->obj) { + SLOT_ERR("create slot%u %s object error!\n", curr_slot->obj->index, name); + return -ENOMEM; + } + curr_vol->obj->index = vol_index; + if (sysfs_create_group(&curr_vol->obj->kobj, &slot_vol_attr_group) != 0) { + SLOT_ERR("create slot%u %s attrs error.\n", curr_slot->obj->index, name); + switch_kobject_delete(&curr_vol->obj); + return -EBADRQC; + } + SLOT_DBG("create slot%u %s success.\n", curr_slot->obj->index, name); + return 0; +} + +static void slotindex_vol_remove_kobj_and_attrs(struct slot_obj_s *curr_slot) +{ + unsigned int vol_index, vol_num; + + if (curr_slot->vol) { + vol_num = curr_slot->vol_number; + for (vol_index = vol_num; vol_index > 0; vol_index--) { + slotindex_single_vol_remove_kobj_and_attrs(curr_slot, vol_index); + } + kfree(curr_slot->vol); + curr_slot->vol = NULL; + } + return; +} + +static int slotindex_vol_create_kobj_and_attrs(struct slot_obj_s *curr_slot) +{ + unsigned int vol_index, i, vol_num; + + vol_num = curr_slot->vol_number; + curr_slot->vol = kzalloc(sizeof(struct slot_vol_obj_s) * vol_num, GFP_KERNEL); + if (!curr_slot->vol) { + SLOT_ERR("kzalloc slot vol error, slot index: %u, vol number: %u.\n", + curr_slot->obj->index, vol_num); + return -ENOMEM; + } + + for (vol_index = 1; vol_index <= vol_num; vol_index++) { + if (slotindex_single_vol_create_kobj_and_attrs(curr_slot, vol_index) != 0) { + goto error; + } + } + return 0; +error: + for (i = vol_index; i > 0; i--) { + slotindex_single_vol_remove_kobj_and_attrs(curr_slot, i); + } + kfree(curr_slot->vol); + curr_slot->vol = NULL; + return -EBADRQC; +} + +/* create slot vol_snesor[1-n] directory and attributes*/ +static int slot_vol_create(void) +{ + int vol_num; + unsigned int slot_index, i; + struct slot_obj_s *curr_slot; + + check_p(g_slot_drv->get_slot_vol_number); + for (slot_index = 1; slot_index <= g_slot.slot_number; slot_index++) { + vol_num = g_slot_drv->get_slot_vol_number(slot_index); + if (vol_num <= 0) { + SLOT_DBG("slot%u vol number: %d, don't need to create vol_sensor* dirs and attrs.\n", + slot_index, vol_num); + continue; + } + curr_slot = &g_slot.slot[slot_index - 1]; + curr_slot->vol_number = vol_num; + if (slotindex_vol_create_kobj_and_attrs(curr_slot) != 0) { + goto error; + } + } + return 0; +error: + for (i = slot_index; i > 0; i--) { + curr_slot = &g_slot.slot[i - 1]; + slotindex_vol_remove_kobj_and_attrs(curr_slot); + } + return -EBADRQC; +} + +/* delete slot vol_sensor[1-n] directory and attributes*/ +static void slot_vol_remove(void) +{ + unsigned int slot_index; + struct slot_obj_s *curr_slot; + + if (g_slot.slot) { + for (slot_index = g_slot.slot_number; slot_index > 0; slot_index--) { + curr_slot = &g_slot.slot[slot_index - 1]; + slotindex_vol_remove_kobj_and_attrs(curr_slot); + curr_slot->vol_number = 0; + } + } + return; +} +/**********************************end of slot voltage************************************/ +/***************************************slot temp*****************************************/ +static void slotindex_single_temp_remove_kobj_and_attrs(struct slot_obj_s *curr_slot, + unsigned int temp_index) +{ + struct slot_temp_obj_s *curr_temp; + + curr_temp = &curr_slot->temp[temp_index - 1]; + if (curr_temp->obj) { + sysfs_remove_group(&curr_temp->obj->kobj, &slot_temp_attr_group); + switch_kobject_delete(&curr_temp->obj); + SLOT_DBG("delete slot%u temp_sensor%u dir and attrs success.\n", curr_slot->obj->index, + temp_index); + } + return; +} + +static int slotindex_single_temp_create_kobj_and_attrs(struct slot_obj_s *curr_slot, + unsigned int temp_index) +{ + char name[DIR_NAME_MAX_LEN]; + struct slot_temp_obj_s *curr_temp; + + curr_temp = &curr_slot->temp[temp_index - 1]; + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "temp_sensor%u", temp_index); + curr_temp->obj = switch_kobject_create(name, &curr_slot->obj->kobj); + if (!curr_temp->obj) { + SLOT_ERR("create slot%u %s object error!\n", curr_slot->obj->index, name); + return -ENOMEM; + } + curr_temp->obj->index = temp_index; + if (sysfs_create_group(&curr_temp->obj->kobj, &slot_temp_attr_group) != 0) { + SLOT_ERR("create slot%u %s attrs error.\n", curr_slot->obj->index, name); + switch_kobject_delete(&curr_temp->obj); + return -EBADRQC; + } + SLOT_DBG("create slot%u %s success.\n", curr_slot->obj->index, name); + return 0; +} + +static void slotindex_temp_remove_kobj_and_attrs(struct slot_obj_s *curr_slot) +{ + unsigned int temp_index, temp_num; + + if (curr_slot->temp) { + temp_num = curr_slot->temp_number; + for (temp_index = temp_num; temp_index > 0; temp_index--) { + slotindex_single_temp_remove_kobj_and_attrs(curr_slot, temp_index); + } + kfree(curr_slot->temp); + curr_slot->temp = NULL; + } + return; +} + +static int slotindex_temp_create_kobj_and_attrs(struct slot_obj_s *curr_slot) +{ + unsigned int temp_index, i, temp_num; + + temp_num = curr_slot->temp_number; + curr_slot->temp = kzalloc(sizeof(struct slot_temp_obj_s) * temp_num, GFP_KERNEL); + if (!curr_slot->temp) { + SLOT_ERR("kzalloc slot temp error, slot index: %u, temp number: %u.\n", + curr_slot->obj->index, temp_num); + return -ENOMEM; + } + + for (temp_index = 1; temp_index <= temp_num; temp_index++) { + if (slotindex_single_temp_create_kobj_and_attrs(curr_slot, temp_index) != 0) { + goto error; + } + } + return 0; +error: + for (i = temp_index; i > 0; i--) { + slotindex_single_temp_remove_kobj_and_attrs(curr_slot, i); + } + kfree(curr_slot->temp); + curr_slot->temp = NULL; + return -EBADRQC; +} + +/* create slot temp_sensor[1-n] directory and attributes*/ +static int slot_temp_create(void) +{ + int temp_num; + unsigned int slot_index, i; + struct slot_obj_s *curr_slot; + + check_p(g_slot_drv->get_slot_temp_number); + for (slot_index = 1; slot_index <= g_slot.slot_number; slot_index++) { + temp_num = g_slot_drv->get_slot_temp_number(slot_index); + if (temp_num <= 0) { + SLOT_DBG("slot%u temp number: %d, don't need to create temp_sensor* dirs and attrs.\n", + slot_index, temp_num); + continue; + } + curr_slot = &g_slot.slot[slot_index - 1]; + curr_slot->temp_number = temp_num; + if (slotindex_temp_create_kobj_and_attrs(curr_slot) != 0) { + goto error; + } + } + return 0; +error: + for (i = slot_index; i > 0; i--) { + curr_slot = &g_slot.slot[i - 1]; + slotindex_temp_remove_kobj_and_attrs(curr_slot); + } + return -EBADRQC; +} + +/* delete slot temp_sensor[1-n] directory and attributes*/ +static void slot_temp_remove(void) +{ + unsigned int slot_index; + struct slot_obj_s *curr_slot; + + if (g_slot.slot) { + for (slot_index = g_slot.slot_number; slot_index > 0; slot_index--) { + curr_slot = &g_slot.slot[slot_index - 1]; + slotindex_temp_remove_kobj_and_attrs(curr_slot); + curr_slot->temp_number = 0; + } + } + return; +} +/************************************end of slot temp**************************************/ + +static int slot_child_obj_create(void) +{ + int ret; + + if (g_slot.slot_number <= 0) { + SLOT_DBG("slot number: %u, skip to create slot child dirs and attrs.\n", + g_slot.slot_number); + return 0; + } + /* temp create */ + ret = slot_temp_create(); + if (ret < 0) { + goto temp_err; + } + /* Voltage create */ + ret = slot_vol_create(); + if(ret < 0) { + goto vol_err; + } + /* current create */ + ret = slot_curr_create(); + if(ret < 0) { + goto curr_err; + } + /* fpga create */ + ret = slot_fpga_create(); + if(ret < 0) { + goto fpga_err; + } + /* cplf create */ + ret = slot_cpld_create(); + if(ret < 0) { + goto cpld_err; + } + return 0; +cpld_err: + slot_fpga_remove(); +fpga_err: + slot_curr_remove(); +curr_err: + slot_vol_remove(); +vol_err: + slot_temp_remove(); +temp_err: + return ret; +} + +static void slot_child_obj_remove(void) +{ + slot_cpld_remove(); + slot_fpga_remove(); + slot_curr_remove(); + slot_vol_remove(); + slot_temp_remove(); + return; +} + +static void slot_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct slot_obj_s *curr_slot; + + curr_slot = &g_slot.slot[index - 1]; + if (curr_slot->obj) { + sysfs_remove_group(&curr_slot->obj->kobj, &slot_attr_group); + switch_kobject_delete(&curr_slot->obj); + SLOT_DBG("delete slot%u dir and attrs success.\n", index); + } + + return; +} + +static int slot_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index) +{ + char name[DIR_NAME_MAX_LEN]; + struct slot_obj_s * curr_slot; + + curr_slot = &g_slot.slot[index - 1]; + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "slot%u", index); + curr_slot->obj = switch_kobject_create(name, parent); + if (!curr_slot->obj) { + SLOT_ERR("create %s object error!\n", name); + return -EBADRQC; + } + curr_slot->obj->index = index; + if (sysfs_create_group(&curr_slot->obj->kobj, &slot_attr_group) != 0) { + SLOT_ERR("create %s attrs error.\n", name); + switch_kobject_delete(&curr_slot->obj); + return -EBADRQC; + } + SLOT_DBG("create %s dir and attrs success.\n", name); + return 0; +} + +static int slot_sub_create_kobj_and_attrs(struct kobject *parent, int slot_num) +{ + unsigned int slot_index, i; + + g_slot.slot = kzalloc(sizeof(struct slot_obj_s) * slot_num, GFP_KERNEL); + if (!g_slot.slot) { + SLOT_ERR("kzalloc slot.slot error, slot number = %d.\n", slot_num); + return -ENOMEM; + } + + for(slot_index = 1; slot_index <= slot_num; slot_index++) { + if(slot_sub_single_create_kobj_and_attrs(parent, slot_index) != 0 ) { + goto error; + } + } + return 0; +error: + for(i = slot_index; i > 0; i--) { + slot_sub_single_remove_kobj_and_attrs(i); + } + kfree(g_slot.slot); + g_slot.slot = NULL; + return -EBADRQC; +} + +/* create slot[1-n] directory and attributes*/ +static int slot_sub_create(void) +{ + int ret; + + ret = slot_sub_create_kobj_and_attrs(&g_slot_obj->kobj, g_slot.slot_number); + return ret; +} + +/* delete slot[1-n] directory and attributes*/ +static void slot_sub_remove(void) +{ + unsigned int slot_index; + + if (g_slot.slot) { + for (slot_index = g_slot.slot_number; slot_index > 0; slot_index--) { + slot_sub_single_remove_kobj_and_attrs(slot_index); + } + kfree(g_slot.slot); + g_slot.slot = NULL; + } + g_slot.slot_number = 0; + return; +} + +/* create slot directory and number attributes*/ +static int slot_root_create(void) +{ + g_slot_obj = switch_kobject_create("slot", NULL); + if (!g_slot_obj) { + SLOT_ERR("switch_kobject_create slot error!\n"); + return -ENOMEM; + } + + if (sysfs_create_group(&g_slot_obj->kobj, &slot_root_attr_group) != 0) { + switch_kobject_delete(&g_slot_obj); + SLOT_ERR("create slot dir attrs error!\n"); + return -EBADRQC; + } + return 0; +} + +/* delete slot directory and number attributes*/ +static void slot_root_remove(void) +{ + if (g_slot_obj) { + sysfs_remove_group(&g_slot_obj->kobj, &slot_root_attr_group); + switch_kobject_delete(&g_slot_obj); + } + + return; +} + +int s3ip_sysfs_slot_drivers_register(struct s3ip_sysfs_slot_drivers_s *drv) +{ + int ret, slot_num; + + SLOT_INFO("s3ip_sysfs_slot_drivers_register...\n"); + if (g_slot_drv) { + SLOT_ERR("g_slot_drv is not NULL, can't register\n"); + return -EPERM; + } + + check_p(drv); + check_p(drv->get_slot_number); + g_slot_drv = drv; + + slot_num = g_slot_drv->get_slot_number(); + if (slot_num <= 0) { + SLOT_ERR("slot number: %d, don't need to create slot dirs and attrs.\n", slot_num); + g_slot_drv = NULL; + return -EINVAL; + } + + mem_clear(&g_slot, sizeof(struct slot_s)); + g_slot.slot_number = slot_num; + ret = slot_root_create(); + if (ret < 0) { + SLOT_ERR("create slot root dir and attrs failed, ret: %d\n", ret); + g_slot_drv = NULL; + return ret; + } + + ret = slot_sub_create(); + if (ret < 0) { + SLOT_ERR("create slot sub dir and attrs failed, ret: %d\n", ret); + slot_root_remove(); + g_slot_drv = NULL; + return ret; + } + + ret = slot_child_obj_create(); + if (ret < 0) { + SLOT_ERR("create slot child dir and attrs failed, ret: %d\n", ret); + slot_sub_remove(); + slot_root_remove(); + g_slot_drv = NULL; + return ret; + } + SLOT_INFO("s3ip_sysfs_slot_drivers_register success.\n"); + return 0; +} + +void s3ip_sysfs_slot_drivers_unregister(void) +{ + if (g_slot_drv) { + slot_child_obj_remove(); + slot_sub_remove(); + slot_root_remove(); + g_slot_drv = NULL; + SLOT_DBG("s3ip_sysfs_slot_drivers_unregister success.\n"); + } + return; +} + +EXPORT_SYMBOL(s3ip_sysfs_slot_drivers_register); +EXPORT_SYMBOL(s3ip_sysfs_slot_drivers_unregister); +module_param(g_slot_loglevel, int, 0644); +MODULE_PARM_DESC(g_slot_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/switch.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/switch.c new file mode 100644 index 000000000000..c34d48e4caf5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/switch.c @@ -0,0 +1,309 @@ +/* + * An switch driver for switch devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "switch.h" +#include "syseeprom_sysfs.h" + +int g_switch_loglevel = 0; + +#define SWITCH_INFO(fmt, args...) do { \ + if (g_switch_loglevel & INFO) { \ + printk(KERN_INFO "[SWITCH][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define SWITCH_ERR(fmt, args...) do { \ + if (g_switch_loglevel & ERR) { \ + printk(KERN_ERR "[SWITCH][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define SWITCH_DBG(fmt, args...) do { \ + if (g_switch_loglevel & DBG) { \ + printk(KERN_DEBUG "[SWITCH][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct syseeprom_s { + struct bin_attribute bin; + int creat_eeprom_bin_flag; +}; + +static struct s3ip_sysfs_syseeprom_drivers_s *g_syseeprom_drv = NULL; +static struct kset *switch_kset; +static struct syseeprom_s g_syseeprom; + +static ssize_t switch_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) +{ + struct switch_attribute *attribute; + struct switch_obj *device; + + attribute = to_switch_attr(attr); + device = to_switch_obj(kobj); + + if (!attribute->show) { + return -ENOSYS; + } + + return attribute->show(device, attribute, buf); +} + +static ssize_t switch_attr_store(struct kobject *kobj, struct attribute *attr, const char *buf, + size_t len) +{ + struct switch_attribute *attribute; + struct switch_obj *obj; + + attribute = to_switch_attr(attr); + obj = to_switch_obj(kobj); + + if (!attribute->store) { + return -ENOSYS; + } + + return attribute->store(obj, attribute, buf, len); +} + +static const struct sysfs_ops switch_sysfs_ops = { + .show = switch_attr_show, + .store = switch_attr_store, +}; + +static void switch_obj_release(struct kobject *kobj) +{ + struct switch_obj *obj; + + obj = to_switch_obj(kobj); + kfree(obj); + return; +} + +static struct kobj_type switch_ktype = { + .sysfs_ops = &switch_sysfs_ops, + .release = switch_obj_release, +}; + +static ssize_t syseeprom_read(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, + char *buf, loff_t offset, size_t count) +{ + ssize_t rd_len; + + check_p(g_syseeprom_drv); + check_p(g_syseeprom_drv->read_syseeprom_data); + + mem_clear(buf, count); + rd_len = g_syseeprom_drv->read_syseeprom_data(buf, offset, count); + if (rd_len < 0) { + SWITCH_ERR("read syseeprom data error, offset: 0x%llx, read len: %lu, ret: %ld.\n", + offset, count, rd_len); + return rd_len; + } + SWITCH_DBG("read syseeprom data success, offset:0x%llx, read len:%lu, really read len:%ld.\n", + offset, count, rd_len); + return rd_len; +} + +static ssize_t syseeprom_write(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, + char *buf, loff_t offset, size_t count) +{ + ssize_t wr_len; + + check_p(g_syseeprom_drv); + check_p(g_syseeprom_drv->write_syseeprom_data); + + wr_len = g_syseeprom_drv->write_syseeprom_data(buf, offset, count); + if (wr_len < 0) { + SWITCH_ERR("write syseeprom data error, offset: 0x%llx, read len: %lu, ret: %ld.\n", + offset, count, wr_len); + return wr_len; + } + SWITCH_DBG("write syseeprom data success, offset:0x%llx, write len:%lu, really write len:%ld.\n", + offset, count, wr_len); + return wr_len; +} + +static int syseeprom_create_eeprom_attrs(void) +{ + int ret, eeprom_size; + + eeprom_size = g_syseeprom_drv->get_syseeprom_size(); + if (eeprom_size <= 0) { + SWITCH_ERR("syseeprom size: %d, invalid.\n", eeprom_size); + return -EINVAL; + } + + sysfs_bin_attr_init(&g_syseeprom.bin); + g_syseeprom.bin.attr.name = "syseeprom"; + g_syseeprom.bin.attr.mode = 0644; + g_syseeprom.bin.read = syseeprom_read; + g_syseeprom.bin.write = syseeprom_write; + g_syseeprom.bin.size = eeprom_size; + + ret = sysfs_create_bin_file(&switch_kset->kobj, &g_syseeprom.bin); + if (ret) { + SWITCH_ERR("create syseeprom bin error, ret: %d. \n", ret); + return -EBADRQC; + } + SWITCH_DBG("create syseeprom bin file success, eeprom size:%d.\n", eeprom_size); + g_syseeprom.creat_eeprom_bin_flag = 1; + return 0; +} + +static void syseeprom_remove_eeprom_attrs(void) +{ + if (g_syseeprom.creat_eeprom_bin_flag) { + sysfs_remove_bin_file(&switch_kset->kobj, &g_syseeprom.bin); + g_syseeprom.creat_eeprom_bin_flag = 0; + } + + return; +} + +int dev_debug_file_read(char *file_name, unsigned int dev_index, char *buf, int size) +{ + char file_path[DIR_NAME_MAX_LEN]; + loff_t pos; + struct file *filp; + int ret; + + mem_clear(file_path, sizeof(file_path)); + mem_clear(buf, size); + + sprintf(file_path, file_name, dev_index); + filp = filp_open(file_path, O_RDONLY, 0); + if (IS_ERR(filp)) { + SWITCH_ERR("dev_debug_file open failed, path=%s, ret=%d\n", file_path, ret); + filp = NULL; + ret = -ENOENT; + return ret; + } + + pos = 0; + ret = kernel_read(filp, buf, size - 1, &pos); + if (ret < 0) { + SWITCH_ERR("dev_debug_file kernel_read failed, path=%s, addr=0, size=%d, ret=%d\n", file_name, size - 1, ret); + filp_close(filp, NULL); + return ret; + } + + filp_close(filp, NULL); + filp = NULL; + return 0; +} + +int s3ip_sysfs_syseeprom_drivers_register(struct s3ip_sysfs_syseeprom_drivers_s *drv) +{ + int ret; + + SWITCH_INFO("s3ip_sysfs_syseeprom_drivers_register...\n"); + if (g_syseeprom_drv) { + SWITCH_ERR("g_syseeprom_drv is not NULL, can't register\n"); + return -EPERM; + } + + check_p(drv); + check_p(drv->get_syseeprom_size); + g_syseeprom_drv = drv; + + ret = syseeprom_create_eeprom_attrs(); + if (ret < 0) { + SWITCH_ERR("create syseeprom attributes failed, ret: %d\n", ret); + g_syseeprom_drv = NULL; + return ret; + } + SWITCH_INFO("s3ip_sysfs_syseeprom_drivers_register success.\n"); + return 0; +} + +void s3ip_sysfs_syseeprom_drivers_unregister(void) +{ + if (g_syseeprom_drv) { + syseeprom_remove_eeprom_attrs(); + g_syseeprom_drv = NULL; + SWITCH_DBG("s3ip_sysfs_syseeprom_drivers_unregister success.\n"); + } + + return; +} + +struct switch_obj *switch_kobject_create(const char *name, struct kobject *parent) +{ + struct switch_obj *obj; + int ret; + + obj = kzalloc(sizeof(*obj), GFP_KERNEL); + if (!obj) { + SWITCH_DBG("switch_kobject_create %s kzalloc error", name); + return NULL; + } + + obj->kobj.kset = switch_kset; + + ret = kobject_init_and_add(&obj->kobj, &switch_ktype, parent, "%s", name); + if (ret) { + kobject_put(&obj->kobj); + SWITCH_DBG("kobject_init_and_add %s error", name); + return NULL; + } + + return obj; +} + +void switch_kobject_delete(struct switch_obj **obj) +{ + if (*obj) { + SWITCH_DBG("%s delete %s.\n", (*obj)->kobj.parent->name, (*obj)->kobj.name); + kobject_put(&((*obj)->kobj)); + *obj = NULL; + } +} + +static int __init switch_init(void) +{ + SWITCH_INFO("switch_init...\n"); + + switch_kset = kset_create_and_add("s3ip", NULL, NULL); + if (!switch_kset) { + SWITCH_ERR("create switch_kset error.\n"); + return -ENOMEM; + } + + SWITCH_INFO("switch_init success.\n"); + return 0; +} + +static void __exit switch_exit(void) +{ + if (switch_kset) { + kset_unregister(switch_kset); + } + + SWITCH_INFO("switch_exit success.\n"); +} + +module_init(switch_init); +module_exit(switch_exit); +EXPORT_SYMBOL(s3ip_sysfs_syseeprom_drivers_register); +EXPORT_SYMBOL(s3ip_sysfs_syseeprom_drivers_unregister); +module_param(g_switch_loglevel, int, 0644); +MODULE_PARM_DESC(g_switch_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("sonic S3IP sysfs"); +MODULE_DESCRIPTION("switch driver"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/sysled_sysfs.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/sysled_sysfs.c new file mode 100644 index 000000000000..242fb20a8755 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/sysled_sysfs.c @@ -0,0 +1,289 @@ +/* + * An sysled_sysfs driver for sysled sysfs devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#include "switch.h" +#include "sysled_sysfs.h" + +static int g_sysled_loglevel = 0; + +#define SYSLED_INFO(fmt, args...) do { \ + if (g_sysled_loglevel & INFO) { \ + printk(KERN_INFO "[SYSLED_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define SYSLED_ERR(fmt, args...) do { \ + if (g_sysled_loglevel & ERR) { \ + printk(KERN_ERR "[SYSLED_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define SYSLED_DBG(fmt, args...) do { \ + if (g_sysled_loglevel & DBG) { \ + printk(KERN_DEBUG "[SYSLED_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static struct switch_obj *g_sysled_obj = NULL; +static struct s3ip_sysfs_sysled_drivers_s *g_sysled_drv = NULL; + +static ssize_t sys_led_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + check_p(g_sysled_drv); + check_p(g_sysled_drv->get_sys_led_status); + + return g_sysled_drv->get_sys_led_status(buf, PAGE_SIZE); +} + +static ssize_t sys_led_status_store(struct switch_obj *obj, struct switch_attribute *attr, + const char *buf, size_t count) +{ + int ret, value; + + check_p(g_sysled_drv); + check_p(g_sysled_drv->set_sys_led_status); + + ret = kstrtoint(buf, 0, &value); + if (ret != 0) { + SYSLED_ERR("invaild led status ret: %d, can't set sys led status\n", ret); + SYSLED_ERR("invaild led status buf: %s\n", buf); + return -EINVAL; + } + ret = g_sysled_drv->set_sys_led_status(value); + if (ret < 0) { + SYSLED_ERR("set sys led status %d faield, ret: %d\n", value, ret); + return ret; + } + SYSLED_DBG("set sys led status %d success\n", value); + return count; +} + +static ssize_t bmc_led_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + check_p(g_sysled_drv); + check_p(g_sysled_drv->get_bmc_led_status); + + return g_sysled_drv->get_bmc_led_status(buf, PAGE_SIZE); +} + +static ssize_t bmc_led_status_store(struct switch_obj *obj, struct switch_attribute *attr, + const char *buf, size_t count) +{ + int ret, value; + + check_p(g_sysled_drv); + check_p(g_sysled_drv->set_bmc_led_status); + + ret = kstrtoint(buf, 0, &value); + if (ret != 0) { + SYSLED_ERR("invaild led status ret: %d, can't set bmc led status\n", ret); + SYSLED_ERR("invaild led status buf: %s\n", buf); + return -EINVAL; + } + ret = g_sysled_drv->set_bmc_led_status(value); + if (ret < 0) { + SYSLED_ERR("set bmc led status %d faield, ret: %d\n", value, ret); + return ret; + } + SYSLED_DBG("set bmc led status %d success\n", value); + return count; +} + +static ssize_t sys_fan_led_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + check_p(g_sysled_drv); + check_p(g_sysled_drv->get_sys_fan_led_status); + + return g_sysled_drv->get_sys_fan_led_status(buf, PAGE_SIZE); +} + +static ssize_t sys_fan_led_status_store(struct switch_obj *obj, struct switch_attribute *attr, + const char *buf, size_t count) +{ + int ret, value; + + check_p(g_sysled_drv); + check_p(g_sysled_drv->set_sys_fan_led_status); + + ret = kstrtoint(buf, 0, &value); + if (ret != 0) { + SYSLED_ERR("invaild led status ret: %d, can't set sys fan led status\n", ret); + SYSLED_ERR("invaild led status buf: %s\n", buf); + return -EINVAL; + } + ret = g_sysled_drv->set_sys_fan_led_status(value); + if (ret < 0) { + SYSLED_ERR("set sys fan led status %d faield, ret: %d\n", value, ret); + return ret; + } + SYSLED_DBG("set sys fan led status %d success\n", value); + return count; +} + +static ssize_t sys_psu_led_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + check_p(g_sysled_drv); + check_p(g_sysled_drv->get_sys_psu_led_status); + + return g_sysled_drv->get_sys_psu_led_status(buf, PAGE_SIZE); +} + +static ssize_t sys_psu_led_status_store(struct switch_obj *obj, struct switch_attribute *attr, + const char *buf, size_t count) +{ + int ret, value; + + check_p(g_sysled_drv); + check_p(g_sysled_drv->set_sys_psu_led_status); + + ret = kstrtoint(buf, 0, &value); + if (ret != 0) { + SYSLED_ERR("invaild led status ret: %d, can't set sys psu led status\n", ret); + SYSLED_ERR("invaild led status buf: %s\n", buf); + return -EINVAL; + } + ret = g_sysled_drv->set_sys_psu_led_status(value); + if (ret < 0) { + SYSLED_ERR("set sys psu led status %d faield, ret: %d\n", value, ret); + return ret; + } + SYSLED_DBG("set sys psu led status %d success\n", value); + return count; +} + +static ssize_t id_led_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + check_p(g_sysled_drv); + check_p(g_sysled_drv->get_id_led_status); + + return g_sysled_drv->get_id_led_status(buf, PAGE_SIZE); +} + +static ssize_t id_led_status_store(struct switch_obj *obj, struct switch_attribute *attr, + const char *buf, size_t count) +{ + int ret, value; + + check_p(g_sysled_drv); + check_p(g_sysled_drv->set_id_led_status); + + ret = kstrtoint(buf, 0, &value); + if (ret != 0) { + SYSLED_ERR("invaild led status ret: %d, can't set id led status\n", ret); + SYSLED_ERR("invaild led status buf: %s\n", buf); + return -EINVAL; + } + ret = g_sysled_drv->set_id_led_status(value); + if (ret < 0) { + SYSLED_ERR("set id led status %d faield, ret: %d\n", value, ret); + return ret; + } + SYSLED_DBG("set id led status %d success\n", value); + return count; +} + +/************************************syseeprom dir and attrs*******************************************/ +static struct switch_attribute sys_led_attr = __ATTR(sys_led_status, S_IRUGO | S_IWUSR, sys_led_status_show, sys_led_status_store); +static struct switch_attribute bmc_led_attr = __ATTR(bmc_led_status, S_IRUGO | S_IWUSR, bmc_led_status_show, bmc_led_status_store); +static struct switch_attribute fan_led_attr = __ATTR(fan_led_status, S_IRUGO | S_IWUSR, sys_fan_led_status_show, sys_fan_led_status_store); +static struct switch_attribute psu_led_attr = __ATTR(psu_led_status, S_IRUGO | S_IWUSR, sys_psu_led_status_show, sys_psu_led_status_store); +static struct switch_attribute id_led_attr = __ATTR(id_led_status, S_IRUGO | S_IWUSR, id_led_status_show, id_led_status_store); + +static struct attribute *sysled_dir_attrs[] = { + &sys_led_attr.attr, + &bmc_led_attr.attr, + &fan_led_attr.attr, + &psu_led_attr.attr, + &id_led_attr.attr, + NULL, +}; + +static struct attribute_group sysled_attr_group = { + .attrs = sysled_dir_attrs, +}; + +/* create syseled directory and attributes*/ +static int sysled_root_create(void) +{ + g_sysled_obj = switch_kobject_create("sysled", NULL); + if (!g_sysled_obj) { + SYSLED_ERR("switch_kobject_create sysled error!\n"); + return -ENOMEM; + } + + if (sysfs_create_group(&g_sysled_obj->kobj, &sysled_attr_group) != 0) { + switch_kobject_delete(&g_sysled_obj); + SYSLED_ERR("create sysled dir attrs error!\n"); + return -EBADRQC; + } + + return 0; +} + +/* delete syseled directory and attributes*/ +static void sysled_root_remove(void) +{ + if (g_sysled_obj) { + sysfs_remove_group(&g_sysled_obj->kobj, &sysled_attr_group); + switch_kobject_delete(&g_sysled_obj); + } + + return; +} + +int s3ip_sysfs_sysled_drivers_register(struct s3ip_sysfs_sysled_drivers_s *drv) +{ + int ret; + + SYSLED_INFO("s3ip_sysfs_sysled_drivers_register...\n"); + if (g_sysled_drv) { + SYSLED_ERR("g_sysled_drv is not NULL, can't register\n"); + return -EPERM; + } + + check_p(drv); + g_sysled_drv = drv; + + ret = sysled_root_create(); + if (ret < 0) { + SYSLED_ERR("sysled create error.\n"); + g_sysled_drv = NULL; + return ret; + } + SYSLED_INFO("s3ip_sysfs_sysled_drivers_register success\n"); + return 0; +} + +void s3ip_sysfs_sysled_drivers_unregister(void) +{ + if (g_sysled_drv) { + sysled_root_remove(); + g_sysled_drv = NULL; + SYSLED_DBG("s3ip_sysfs_sysled_drivers_unregister success.\n"); + } + return; +} + +EXPORT_SYMBOL(s3ip_sysfs_sysled_drivers_register); +EXPORT_SYMBOL(s3ip_sysfs_sysled_drivers_unregister); +module_param(g_sysled_loglevel, int, 0644); +MODULE_PARM_DESC(g_sysled_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/system_sysfs.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/system_sysfs.c new file mode 100644 index 000000000000..dd1c3e859a1a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/system_sysfs.c @@ -0,0 +1,218 @@ +/* + * An system_sysfs driver for system sysfs devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#include "switch.h" +#include "system_sysfs.h" +#include "switch_driver.h" + +static int g_system_loglevel = 0; + +#define SYSTEM_INFO(fmt, args...) do { \ + if (g_system_loglevel & INFO) { \ + printk(KERN_INFO "[system][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define SYSTEM_ERR(fmt, args...) do { \ + if (g_system_loglevel & ERR) { \ + printk(KERN_ERR "[system][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define SYSTEM_DBG(fmt, args...) do { \ + if (g_system_loglevel & DBG) { \ + printk(KERN_DEBUG "[system][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct system_obj_s { + struct switch_obj *obj; +}; + +struct system_s { + unsigned int api_number; + struct system_obj_s *temp; +}; + +static struct s3ip_sysfs_system_drivers_s *g_system_drv = NULL; +static struct switch_obj *g_system_obj = NULL; + +static ssize_t system_value_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + int value; + struct switch_device_attribute *system_attr; + + check_p(g_system_drv); + check_p(g_system_drv->get_system_value); + + system_attr = to_switch_device_attr(attr); + check_p(system_attr); + SYSTEM_DBG("system_value_show type 0x%x \n", system_attr->type); + return g_system_drv->get_system_value(system_attr->type, &value, buf, PAGE_SIZE); +} + +static ssize_t system_value_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + int ret, value; + struct switch_device_attribute *system_attr; + + check_p(g_system_drv); + check_p(g_system_drv->set_system_value); + + system_attr = to_switch_device_attr(attr); + check_p(system_attr); + + ret = kstrtoint(buf, 0, &value); + if (ret) { + SYSTEM_ERR("system_value_store, input parameter: %s error. ret:%d\n", buf, ret); + return ret; + } + + if(value > 0xff) { + SYSTEM_ERR("system_value_store, input parameter bigger than 0xff: %d\n", value); + return -EINVAL; + } + SYSTEM_DBG("system_value_store, type: 0x%x. value=%d\n", system_attr->type, value); + ret = g_system_drv->set_system_value(system_attr->type, value); + if (ret < 0) { + /* ret=-999 if not support */ + SYSTEM_ERR("set system reg value: %d failed. ret:%d\n", value, ret); + return ret; + } + return count; +} + +static ssize_t system_port_port_status_value(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + struct switch_device_attribute *system_attr; + + check_p(g_system_drv); + check_p(g_system_drv->get_system_port_power_status); + + system_attr = to_switch_device_attr(attr); + check_p(system_attr); + SYSTEM_DBG("type 0x%x \n", system_attr->type); + return g_system_drv->get_system_port_power_status(system_attr->type, buf, PAGE_SIZE); +} + +/************************************system dir and attrs*******************************************/ +static SWITCH_DEVICE_ATTR(bmc_ready, S_IRUGO | S_IWUSR, system_value_show, system_value_store, WB_SYSTEM_BMC_READY); +static SWITCH_DEVICE_ATTR(sol_active, S_IRUGO | S_IWUSR, system_value_show, system_value_store, WB_SYSTEM_SOL_ACTIVE); +static SWITCH_DEVICE_ATTR(psu_reset, S_IWUSR, NULL, system_value_store, WB_SYSTEM_PSU_RESET); +static SWITCH_DEVICE_ATTR(cpu_board_ctrl, S_IWUSR, NULL, system_value_store, WB_SYSTEM_CPU_BOARD_CTRL); +static SWITCH_DEVICE_ATTR(cpu_board_status, S_IRUGO , system_value_show, NULL, WB_SYSTEM_CPU_BOARD_STATUS); +static SWITCH_DEVICE_ATTR(bios_switch, S_IWUSR, NULL, system_value_store, WB_SYSTEM_BIOS_SWITCH); +static SWITCH_DEVICE_ATTR(bios_view, S_IRUGO, system_value_show, NULL, WB_SYSTEM_BIOS_VIEW); +static SWITCH_DEVICE_ATTR(bios_boot_ok, S_IRUGO, system_value_show, NULL, WB_SYSTEM_BIOS_BOOT_OK); +static SWITCH_DEVICE_ATTR(bios_fail_record, S_IRUGO, system_value_show, NULL, WB_SYSTEM_BIOS_FAIL_RECORD); +static SWITCH_DEVICE_ATTR(bmc_reset, S_IWUSR, NULL, system_value_store, WB_SYSTEM_BMC_RESET); +static SWITCH_DEVICE_ATTR(mac_board_reset, S_IRUGO | S_IWUSR, system_value_show, system_value_store, WB_SYSTEM_MAC_BOARD_RESET); +static SWITCH_DEVICE_ATTR(mac_pwr_ctrl, S_IRUGO | S_IWUSR, system_value_show, system_value_store, WB_SYSTEM_MAC_PWR_CTRL); +static SWITCH_DEVICE_ATTR(emmc_pwr_ctrl, S_IRUGO | S_IWUSR, system_value_show, system_value_store, WB_SYSTEM_EMMC_PWR_CTRL); +static SWITCH_DEVICE_ATTR(port_pwr_ctl, S_IRUGO | S_IWUSR, system_port_port_status_value, system_value_store, WB_SYSTEM_PORT_PWR_CTL); +static SWITCH_DEVICE_ATTR(bmc_view, S_IRUGO, system_value_show, NULL, WB_SYSTEM_BMC_VIEW); +static SWITCH_DEVICE_ATTR(bmc_switch, S_IWUSR, NULL, system_value_store, WB_SYSTEM_BMC_SWITCH); + +static struct attribute *system_dir_attrs[] = { + &switch_dev_attr_bmc_ready.switch_attr.attr, + &switch_dev_attr_sol_active.switch_attr.attr, + &switch_dev_attr_psu_reset.switch_attr.attr, + &switch_dev_attr_cpu_board_ctrl.switch_attr.attr, + &switch_dev_attr_cpu_board_status.switch_attr.attr, + &switch_dev_attr_bios_switch.switch_attr.attr, + &switch_dev_attr_bios_view.switch_attr.attr, + &switch_dev_attr_bios_boot_ok.switch_attr.attr, + &switch_dev_attr_bios_fail_record.switch_attr.attr, + &switch_dev_attr_bmc_reset.switch_attr.attr, + &switch_dev_attr_mac_board_reset.switch_attr.attr, + &switch_dev_attr_mac_pwr_ctrl.switch_attr.attr, + &switch_dev_attr_emmc_pwr_ctrl.switch_attr.attr, + &switch_dev_attr_port_pwr_ctl.switch_attr.attr, + &switch_dev_attr_bmc_view.switch_attr.attr, + &switch_dev_attr_bmc_switch.switch_attr.attr, + NULL, +}; + +static struct attribute_group system_root_attr_group = { + .attrs = system_dir_attrs, +}; + +/* create system directory and number attributes */ +static int system_root_create(void) +{ + g_system_obj = switch_kobject_create("system", NULL); + if (!g_system_obj) { + SYSTEM_ERR("switch_kobject_create system error!\n"); + return -ENOMEM; + } + + if (sysfs_create_group(&g_system_obj->kobj, &system_root_attr_group) != 0) { + switch_kobject_delete(&g_system_obj); + SYSTEM_ERR("create system dir attrs error!\n"); + return -EBADRQC; + } + return 0; +} + +/* delete system directory and number attributes */ +static void system_root_remove(void) +{ + if (g_system_obj) { + sysfs_remove_group(&g_system_obj->kobj, &system_root_attr_group); + switch_kobject_delete(&g_system_obj); + } + + return; +} + +int s3ip_sysfs_system_drivers_register(struct s3ip_sysfs_system_drivers_s *drv) +{ + int ret; + + SYSTEM_INFO("s3ip_sysfs_system_drivers_register...\n"); + check_p(drv); + g_system_drv = drv; + ret = system_root_create(); + if (ret < 0) { + SYSTEM_ERR("create system root dir and attrs failed, ret: %d\n", ret); + return ret; + } + + SYSTEM_INFO("s3ip_sysfs_system_drivers_register success\n"); + return ret; +} + +void s3ip_sysfs_system_drivers_unregister(void) +{ + if (g_system_drv) { + system_root_remove(); + g_system_drv = NULL; + SYSTEM_DBG("s3ip_sysfs_system_drivers_unregister success.\n"); + } + return; +} + +EXPORT_SYMBOL(s3ip_sysfs_system_drivers_register); +EXPORT_SYMBOL(s3ip_sysfs_system_drivers_unregister); +module_param(g_system_loglevel, int, 0644); +MODULE_PARM_DESC(g_system_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/temp_sensor_sysfs.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/temp_sensor_sysfs.c new file mode 100644 index 000000000000..bfda43b47973 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/temp_sensor_sysfs.c @@ -0,0 +1,458 @@ +/* + * An temp_sensor_sysfs driver for temperature sysfs devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#include "switch.h" +#include "temp_sensor_sysfs.h" + +static int g_temp_sensor_loglevel = 0; + +#define TEMP_SENSOR_INFO(fmt, args...) do { \ + if (g_temp_sensor_loglevel & INFO) { \ + printk(KERN_INFO "[TEMP_SENSOR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define TEMP_SENSOR_ERR(fmt, args...) do { \ + if (g_temp_sensor_loglevel & ERR) { \ + printk(KERN_ERR "[TEMP_SENSOR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define TEMP_SENSOR_DBG(fmt, args...) do { \ + if (g_temp_sensor_loglevel & DBG) { \ + printk(KERN_DEBUG "[TEMP_SENSOR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct temp_sensor_obj_s { + struct switch_obj *obj; +}; + +struct temp_sensor_s { + unsigned int temp_number; + struct temp_sensor_obj_s *temp; +}; + +static struct s3ip_sysfs_temp_sensor_drivers_s *g_temp_sensor_drv = NULL; +static struct temp_sensor_s g_temp_sensor; +static struct switch_obj *g_temp_sensor_obj = NULL; + +static ssize_t temp_sensor_number_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_temp_sensor.temp_number); +} + +static ssize_t temp_sensor_value_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int temp_index; + + check_p(g_temp_sensor_drv); + check_p(g_temp_sensor_drv->get_main_board_temp_value); + + temp_index = obj->index; + TEMP_SENSOR_DBG("temp index: %u\n", temp_index); + return g_temp_sensor_drv->get_main_board_temp_value(temp_index, buf, PAGE_SIZE); +} + +static ssize_t temp_sensor_alias_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int temp_index; + + check_p(g_temp_sensor_drv); + check_p(g_temp_sensor_drv->get_main_board_temp_alias); + + temp_index = obj->index; + TEMP_SENSOR_DBG("temp index: %u\n", temp_index); + return g_temp_sensor_drv->get_main_board_temp_alias(temp_index, buf, PAGE_SIZE); +} + +static ssize_t temp_sensor_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int temp_index; + + check_p(g_temp_sensor_drv); + check_p(g_temp_sensor_drv->get_main_board_temp_type); + + temp_index = obj->index; + TEMP_SENSOR_DBG("temp index: %u\n", temp_index); + return g_temp_sensor_drv->get_main_board_temp_type(temp_index, buf, PAGE_SIZE); +} + +static ssize_t temp_sensor_max_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int temp_index; + + check_p(g_temp_sensor_drv); + check_p(g_temp_sensor_drv->get_main_board_temp_max); + + temp_index = obj->index; + TEMP_SENSOR_DBG("temp index: %u\n", temp_index); + return g_temp_sensor_drv->get_main_board_temp_max(temp_index, buf, PAGE_SIZE); +} + +static ssize_t temp_sensor_max_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int temp_index; + int ret; + + check_p(g_temp_sensor_drv); + check_p(g_temp_sensor_drv->set_main_board_temp_max); + + temp_index = obj->index; + TEMP_SENSOR_DBG("temp index: %u\n", temp_index); + ret = g_temp_sensor_drv->set_main_board_temp_max(temp_index, buf, count); + if (ret < 0) { + TEMP_SENSOR_ERR("set temp%u max threshold failed, value: %s, count: %lu, ret: %d\n", + temp_index, buf, count, ret); + return ret; + } + TEMP_SENSOR_DBG("set temp%u max threshold success, value: %s, count: %lu, ret: %d\n", + temp_index, buf, count, ret); + return count; +} + +static ssize_t temp_sensor_min_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int temp_index; + + check_p(g_temp_sensor_drv); + check_p(g_temp_sensor_drv->get_main_board_temp_min); + + temp_index = obj->index; + TEMP_SENSOR_DBG("temp index: %u\n", temp_index); + return g_temp_sensor_drv->get_main_board_temp_min(temp_index, buf, PAGE_SIZE); +} + +static ssize_t temp_sensor_min_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int temp_index; + int ret; + + check_p(g_temp_sensor_drv); + check_p(g_temp_sensor_drv->set_main_board_temp_min); + + temp_index = obj->index; + TEMP_SENSOR_DBG("temp index: %u\n", temp_index); + ret = g_temp_sensor_drv->set_main_board_temp_min(temp_index, buf, count); + if (ret < 0) { + TEMP_SENSOR_ERR("set temp%u min threshold failed, value: %s, count: %lu, ret: %d\n", + temp_index, buf, count, ret); + return ret; + } + TEMP_SENSOR_DBG("set temp%u min threshold success, value: %s, count: %lu, ret: %d\n", + temp_index, buf, count, ret); + return count; +} + +static ssize_t temp_sensor_high_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int temp_index; + + check_p(g_temp_sensor_drv); + check_p(g_temp_sensor_drv->get_main_board_temp_high); + + temp_index = obj->index; + TEMP_SENSOR_DBG("temp index: %u\n", temp_index); + return g_temp_sensor_drv->get_main_board_temp_high(temp_index, buf, PAGE_SIZE); +} + +static ssize_t temp_sensor_high_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int temp_index; + int ret; + + check_p(g_temp_sensor_drv); + check_p(g_temp_sensor_drv->set_main_board_temp_high); + + temp_index = obj->index; + TEMP_SENSOR_DBG("temp index: %u\n", temp_index); + ret = g_temp_sensor_drv->set_main_board_temp_high(temp_index, buf, count); + if (ret < 0) { + TEMP_SENSOR_ERR("set temp%u high threshold failed, value: %s, count: %lu, ret: %d\n", + temp_index, buf, count, ret); + return ret; + } + TEMP_SENSOR_DBG("set temp%u high threshold success, value: %s, count: %lu, ret: %d\n", + temp_index, buf, count, ret); + return count; +} + +static ssize_t temp_sensor_low_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int temp_index; + + check_p(g_temp_sensor_drv); + check_p(g_temp_sensor_drv->get_main_board_temp_low); + + temp_index = obj->index; + TEMP_SENSOR_DBG("temp index: %u\n", temp_index); + return g_temp_sensor_drv->get_main_board_temp_low(temp_index, buf, PAGE_SIZE); +} + +static ssize_t temp_sensor_low_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int temp_index; + int ret; + + check_p(g_temp_sensor_drv); + check_p(g_temp_sensor_drv->set_main_board_temp_low); + + temp_index = obj->index; + TEMP_SENSOR_DBG("temp index: %u\n", temp_index); + ret = g_temp_sensor_drv->set_main_board_temp_low(temp_index, buf, count); + if (ret < 0) { + TEMP_SENSOR_ERR("set temp%u low threshold failed, value: %s, count: %lu, ret: %d\n", + temp_index, buf, count, ret); + return ret; + } + TEMP_SENSOR_DBG("set temp%u low threshold success, value: %s, count: %lu, ret: %d\n", + temp_index, buf, count, ret); + return count; +} + +static ssize_t temp_sensor_monitor_flag_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int temp_index; + + check_p(g_temp_sensor_drv); + check_p(g_temp_sensor_drv->get_main_board_temp_monitor_flag); + + temp_index = obj->index; + TEMP_SENSOR_DBG("temp index: %u\n", temp_index); + return g_temp_sensor_drv->get_main_board_temp_monitor_flag(temp_index, buf, PAGE_SIZE); +} + +/************************************temp_sensor dir and attrs*******************************************/ +static struct switch_attribute num_temp_att = __ATTR(number, S_IRUGO, temp_sensor_number_show, NULL); + +static struct attribute *temp_sensor_dir_attrs[] = { + &num_temp_att.attr, + NULL, +}; + +static struct attribute_group temp_sensor_root_attr_group = { + .attrs = temp_sensor_dir_attrs, +}; + +/*******************************temp1 temp2 dir and attrs*******************************************/ +static struct switch_attribute temp_value_attr = __ATTR(value, S_IRUGO, temp_sensor_value_show, NULL); +static struct switch_attribute temp_alias_attr = __ATTR(alias, S_IRUGO, temp_sensor_alias_show, NULL); +static struct switch_attribute temp_type_attr = __ATTR(type, S_IRUGO, temp_sensor_type_show, NULL); +static struct switch_attribute temp_max_attr = __ATTR(max, S_IRUGO | S_IWUSR, temp_sensor_max_show, temp_sensor_max_store); +static struct switch_attribute temp_min_attr = __ATTR(min, S_IRUGO | S_IWUSR, temp_sensor_min_show, temp_sensor_min_store); +static struct switch_attribute temp_high_attr = __ATTR(high, S_IRUGO | S_IWUSR, temp_sensor_high_show, temp_sensor_high_store); +static struct switch_attribute temp_low_attr = __ATTR(low, S_IRUGO | S_IWUSR, temp_sensor_low_show, temp_sensor_low_store); +static struct switch_attribute temp_monitor_flag_attr = __ATTR(monitor_flag, S_IRUGO, temp_sensor_monitor_flag_show, NULL); + +static struct attribute *temp_sensor_attrs[] = { + &temp_value_attr.attr, + &temp_alias_attr.attr, + &temp_type_attr.attr, + &temp_max_attr.attr, + &temp_min_attr.attr, + &temp_high_attr.attr, + &temp_low_attr.attr, + &temp_monitor_flag_attr.attr, + NULL, +}; + +static struct attribute_group temp_sensor_attr_group = { + .attrs = temp_sensor_attrs, +}; + +static int temp_sensor_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index) +{ + char name[DIR_NAME_MAX_LEN]; + struct temp_sensor_obj_s *temp_sensor; + + temp_sensor = &g_temp_sensor.temp[index - 1]; + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "temp%u", index); + temp_sensor->obj = switch_kobject_create(name, parent); + if (!temp_sensor->obj) { + TEMP_SENSOR_ERR("create %s object error.\n", name); + return -ENOMEM; + } + temp_sensor->obj->index = index; + if (sysfs_create_group(&temp_sensor->obj->kobj, &temp_sensor_attr_group) != 0) { + TEMP_SENSOR_ERR("create %s attrs error.\n", name); + switch_kobject_delete(&temp_sensor->obj); + return -EBADRQC; + } + TEMP_SENSOR_DBG("create %s dir and attrs success.\n", name); + return 0; +} + +static void temp_sensor_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct temp_sensor_obj_s *temp_sensor; + + temp_sensor = &g_temp_sensor.temp[index - 1]; + if (temp_sensor->obj) { + sysfs_remove_group(&temp_sensor->obj->kobj, &temp_sensor_attr_group); + switch_kobject_delete(&temp_sensor->obj); + TEMP_SENSOR_DBG("delete temp%u dir and attrs success.\n", index); + } + + return; +} + +static int temp_sensor_sub_create_kobj_and_attrs(struct kobject *parent, int temp_num) +{ + unsigned int temp_index, i; + + g_temp_sensor.temp = kzalloc(sizeof(struct temp_sensor_obj_s) * temp_num, GFP_KERNEL); + if (!g_temp_sensor.temp) { + TEMP_SENSOR_ERR("kzalloc g_temp_sensor.temp error, temp number: %d.\n", temp_num); + return -ENOMEM; + } + + for (temp_index = 1; temp_index <= temp_num; temp_index++) { + if (temp_sensor_sub_single_create_kobj_and_attrs(parent, temp_index) != 0) { + goto error; + } + } + return 0; +error: + for (i = temp_index; i > 0; i--) { + temp_sensor_sub_single_remove_kobj_and_attrs(i); + } + kfree(g_temp_sensor.temp); + g_temp_sensor.temp = NULL; + return -EBADRQC; +} + +/* create temp[1-n] directory and attributes*/ +static int temp_sensor_sub_create(void) +{ + int ret; + + ret = temp_sensor_sub_create_kobj_and_attrs(&g_temp_sensor_obj->kobj, + g_temp_sensor.temp_number); + return ret; +} + +/* delete temp[1-n] directory and attributes*/ +static void temp_sensor_sub_remove(void) +{ + unsigned int temp_index; + + if (g_temp_sensor.temp) { + for (temp_index = g_temp_sensor.temp_number; temp_index > 0; temp_index--) { + temp_sensor_sub_single_remove_kobj_and_attrs(temp_index); + } + kfree(g_temp_sensor.temp); + g_temp_sensor.temp = NULL; + } + + return; +} + +/* create temp_sensor directory and number attributes */ +static int temp_sensor_root_create(void) +{ + g_temp_sensor_obj = switch_kobject_create("temp_sensor", NULL); + if (!g_temp_sensor_obj) { + TEMP_SENSOR_ERR("switch_kobject_create temp_sensor error!\n"); + return -ENOMEM; + } + + if (sysfs_create_group(&g_temp_sensor_obj->kobj, &temp_sensor_root_attr_group) != 0) { + switch_kobject_delete(&g_temp_sensor_obj); + TEMP_SENSOR_ERR("create temp_sensor dir attrs error!\n"); + return -EBADRQC; + } + return 0; +} + +/* delete temp_sensor directory and number attributes */ +static void temp_sensor_root_remove(void) +{ + if (g_temp_sensor_obj) { + sysfs_remove_group(&g_temp_sensor_obj->kobj, &temp_sensor_root_attr_group); + switch_kobject_delete(&g_temp_sensor_obj); + } + + return; +} + +int s3ip_sysfs_temp_sensor_drivers_register(struct s3ip_sysfs_temp_sensor_drivers_s *drv) +{ + int ret, temp_num; + + TEMP_SENSOR_INFO("s3ip_sysfs_temp_sensor_drivers_register...\n"); + if (g_temp_sensor_drv) { + TEMP_SENSOR_ERR("g_temp_sensor_drv is not NULL, can't register\n"); + return -EPERM; + } + + check_p(drv); + check_p(drv->get_main_board_temp_number); + g_temp_sensor_drv = drv; + + temp_num = g_temp_sensor_drv->get_main_board_temp_number(); + if (temp_num <= 0) { + TEMP_SENSOR_ERR("temp sensor number: %d, don't need to create temp_sensor dirs and attrs.\n", + temp_num); + g_temp_sensor_drv = NULL; + return -EINVAL; + } + mem_clear(&g_temp_sensor, sizeof(struct temp_sensor_s)); + g_temp_sensor.temp_number = temp_num; + ret = temp_sensor_root_create(); + if (ret < 0) { + TEMP_SENSOR_ERR("create temp_sensor root dir and attrs failed, ret: %d\n", ret); + g_temp_sensor_drv = NULL; + return ret; + } + + ret = temp_sensor_sub_create(); + if (ret < 0) { + TEMP_SENSOR_ERR("create temp_sensor sub dir and attrs failed, ret: %d\n", ret); + temp_sensor_root_remove(); + g_temp_sensor_drv = NULL; + return ret; + } + TEMP_SENSOR_INFO("s3ip_sysfs_temp_sensor_drivers_register success\n"); + return ret; +} + +void s3ip_sysfs_temp_sensor_drivers_unregister(void) +{ + if (g_temp_sensor_drv) { + temp_sensor_sub_remove(); + temp_sensor_root_remove(); + g_temp_sensor_drv = NULL; + TEMP_SENSOR_DBG("s3ip_sysfs_temp_sensor_drivers_unregister success.\n"); + } + return; +} + +EXPORT_SYMBOL(s3ip_sysfs_temp_sensor_drivers_register); +EXPORT_SYMBOL(s3ip_sysfs_temp_sensor_drivers_unregister); +module_param(g_temp_sensor_loglevel, int, 0644); +MODULE_PARM_DESC(g_temp_sensor_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/transceiver_sysfs.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/transceiver_sysfs.c new file mode 100644 index 000000000000..6384b452186c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/transceiver_sysfs.c @@ -0,0 +1,996 @@ +/* + * An transceiver_sysfs driver for transceiver sysfs devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#include "switch.h" +#include "transceiver_sysfs.h" + +static int g_sff_loglevel = 0; +static bool g_sff_present_debug = 0; + +#define WB_QSFP_TX_FAULT_OFFSET (4) +#define WB_QSFPDD_TX_FAULT_OFFSET (17*128 + 135) +#define WB_QSFP_TX_DISABLE_OFFSET (86) +#define WB_QSFPDD_TX_DISABLE_OFFSET (16*128 + 130) +#define WB_QSFP_RX_LOS_OFFSET (3) +#define WB_QSFPDD_RX_LOS_OFFSET (17*128 + 147) +#define WB_QSFP_LP_MODE_OFFSET (93) +#define WB_QSFPDD_LP_MODE_OFFSET (26) + +#define SFF_INFO(fmt, args...) do { \ + if (g_sff_loglevel & INFO) { \ + printk(KERN_INFO "[SFF_SYSFS][func:%s line:%d]"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define SFF_ERR(fmt, args...) do { \ + if (g_sff_loglevel & ERR) { \ + printk(KERN_ERR "[SFF_SYSFS][func:%s line:%d]"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define SFF_DBG(fmt, args...) do { \ + if (g_sff_loglevel & DBG) { \ + printk(KERN_DEBUG "[SFF_SYSFS][func:%s line:%d]"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct sff_obj_s { + struct switch_obj *sff_obj; + struct bin_attribute bin; + int sff_creat_bin_flag; +}; + +struct sff_s { + unsigned int sff_number; + struct sff_obj_s *sff; +}; + +static struct sff_s g_sff; +static struct switch_obj *g_sff_obj = NULL; +static struct s3ip_sysfs_transceiver_drivers_s *g_sff_drv = NULL; + +static ssize_t transceiver_power_on_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + check_p(g_sff_drv); + check_p(g_sff_drv->get_transceiver_power_on_status); + + return g_sff_drv->get_transceiver_power_on_status(buf, PAGE_SIZE); +} + +static ssize_t transceiver_power_on_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int eth_index, eth_num; + int ret, value; + + check_p(g_sff_drv); + check_p(g_sff_drv->set_eth_power_on_status); + + sscanf(buf, "%d", &value); + if (value < 0 || value > 1) { + SFF_ERR("invalid value: %d, can't set power on status.\n", value); + return -EINVAL; + } + + eth_num = g_sff.sff_number; + for (eth_index = 1; eth_index <= eth_num; eth_index++) { + SFF_DBG("eth index: %u\n", eth_index); + ret = g_sff_drv->set_eth_power_on_status(eth_index, value); + if (ret < 0) { + SFF_ERR("set eth%u power status failed, ret: %d\n", eth_index, ret); + break; + } + } + SFF_DBG("transceiver_power_on_store ok. sff num:%d, len:%d\n", eth_num, ret); + return count; +} + +static ssize_t transceiver_number_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", g_sff.sff_number); +} + +static ssize_t eth_optoe_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int sff_index; + int optoe_type; + + check_p(g_sff_drv); + check_p(g_sff_drv->get_eth_optoe_type); + + sff_index = obj->index; + SFF_DBG("eth_optoe_type_show, sff index:%u\n", sff_index); + return g_sff_drv->get_eth_optoe_type(sff_index, &optoe_type, buf, PAGE_SIZE); +} + +static ssize_t eth_optoe_type_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int sff_index; + int ret; + int optoe_type; + + check_p(g_sff_drv); + check_p(g_sff_drv->set_eth_optoe_type); + + ret = kstrtoint(buf, 0, &optoe_type); + if (ret != 0) { + SFF_ERR("invaild optoe_type ret: %d, buf: %s.\n", ret, buf); + return -EINVAL; + } + + sff_index = obj->index; + SFF_DBG("eth_optoe_type_store, sff index:%u, optoe_type:%d\n", sff_index, optoe_type); + ret = g_sff_drv->set_eth_optoe_type(sff_index, optoe_type); + if(ret < 0) { + SFF_ERR("set_eth_optoe_type error. sff index:%u, ret:%d\n", sff_index, ret); + return ret; + } + + SFF_DBG("eth_optoe_type_store ok. sff index:%u, optoe_type:%d\n", sff_index, optoe_type); + return count; +} + + +static ssize_t transceiver_present_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + check_p(g_sff_drv); + check_p(g_sff_drv->get_transceiver_present_status); + + return g_sff_drv->get_transceiver_present_status(buf, PAGE_SIZE); +} + +static ssize_t eth_power_on_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int eth_index; + + check_p(g_sff_drv); + check_p(g_sff_drv->get_eth_power_on_status); + + eth_index = obj->index; + SFF_DBG("eth index: %u\n", eth_index); + return g_sff_drv->get_eth_power_on_status(eth_index, buf, PAGE_SIZE); +} + +static ssize_t eth_power_on_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int eth_index; + int ret, value; + + check_p(g_sff_drv); + check_p(g_sff_drv->set_eth_power_on_status); + + sscanf(buf, "%d", &value); + eth_index = obj->index; + if (value < 0 || value > 1) { + SFF_ERR("invalid value: %d, can't set eth%u power on status.\n", value, eth_index); + return -EINVAL; + } + + ret = g_sff_drv->set_eth_power_on_status(eth_index, value); + if (ret < 0) { + SFF_ERR("set eth%u power on status %d failed, ret: %d\n", eth_index, value, ret); + return ret; + } + SFF_DBG("set eth%u power on status %d success\n", eth_index, value); + return count; +} + +static ssize_t eth_tx_fault_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int eth_index; + int ret; + char module_type[1], value[1]; + loff_t offset; + char mask; + + check_p(g_sff_drv); + check_p(g_sff_drv->read_eth_eeprom_data); + check_p(g_sff_drv->get_eth_tx_fault_status); + + eth_index = obj->index; + SFF_DBG("eth index: %u\n", eth_index); + mem_clear(module_type, sizeof(module_type)); + mem_clear(value, sizeof(value)); + ret = g_sff_drv->read_eth_eeprom_data(eth_index, module_type, 0, 1); + if (ret < 0) { + SFF_ERR("get eth%u module type failed, ret: %d\n", eth_index, ret); + if (ret == -WB_SYSFS_RV_UNSUPPORT) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_ERROR); + } + } + + if (module_type[0] == 0x03) { + SFF_DBG("get eth%u module type is SFP\n", eth_index); + return g_sff_drv->get_eth_tx_fault_status(eth_index, buf, PAGE_SIZE); + } else { + if ((module_type[0] == 0x11) || (module_type[0] == 0x0D)) { + SFF_DBG("get eth%u module type is QSFP\n", eth_index); + offset = WB_QSFP_TX_FAULT_OFFSET; + mask = 0xf; + } else if ((module_type[0] == 0x18) || (module_type[0] == 0x1e)) { + SFF_DBG("get eth%u module type is QSFP-DD\n", eth_index); + offset = WB_QSFPDD_TX_FAULT_OFFSET; + mask = 0xff; + } else { + SFF_ERR("eth%u module is unknown, module_type:%d\n", eth_index, module_type[0]); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_ERROR); + } + + ret = g_sff_drv->read_eth_eeprom_data(eth_index, value, offset, 1); + if (ret < 0) { + SFF_ERR("get eth%u module tx fault value failed, ret: %d\n", eth_index, ret); + if (ret == -WB_SYSFS_RV_UNSUPPORT) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_ERROR); + } + } + + if ((value[0] & mask) != 0) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", 1); + } else { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", 0); + } + } + + return ret; +} + +static ssize_t eth_tx_disable_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + unsigned int eth_index; + int ret; + char module_type[1], value[1]; + loff_t offset; + char mask; + + check_p(g_sff_drv); + check_p(g_sff_drv->read_eth_eeprom_data); + check_p(g_sff_drv->get_eth_tx_disable_status); + + eth_index = obj->index; + SFF_DBG("eth index: %u\n", eth_index); + mem_clear(module_type, sizeof(module_type)); + mem_clear(value, sizeof(value)); + ret = g_sff_drv->read_eth_eeprom_data(eth_index, module_type, 0, 1); + if (ret < 0) { + SFF_ERR("get eth%u module type failed, ret: %d\n", eth_index, ret); + if (ret == -WB_SYSFS_RV_UNSUPPORT) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_ERROR); + } + } + + if (module_type[0] == 0x03) { + SFF_DBG("get eth%u module type is SFP\n", eth_index); + return g_sff_drv->get_eth_tx_disable_status(eth_index, buf, PAGE_SIZE); + } else { + if ((module_type[0] == 0x11) || (module_type[0] == 0x0D)) { + SFF_DBG("get eth%u module type is QSFP\n", eth_index); + offset = WB_QSFP_TX_DISABLE_OFFSET; + mask = 0xf; + } else if ((module_type[0] == 0x18) || (module_type[0] == 0x1e)) { + SFF_DBG("get eth%u module type is QSFP-DD\n", eth_index); + offset = WB_QSFPDD_TX_DISABLE_OFFSET; + mask = 0xff; + } else { + SFF_ERR("eth%u module is unknown, module_type:%d\n", eth_index, module_type[0]); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_ERROR); + } + + ret = g_sff_drv->read_eth_eeprom_data(eth_index, value, offset, 1); + if (ret < 0) { + SFF_ERR("get eth%u module tx disable value failed, ret: %d\n", eth_index, ret); + if (ret == -WB_SYSFS_RV_UNSUPPORT) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_ERROR); + } + } + + if ((value[0] & mask) != 0) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", 1); + } else { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", 0); + } + } + + return ret; +} + +static ssize_t eth_tx_disable_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int eth_index; + int ret, value; + char module_type[1], write_buf[1]; + loff_t offset; + + check_p(g_sff_drv); + check_p(g_sff_drv->read_eth_eeprom_data); + check_p(g_sff_drv->write_eth_eeprom_data); + check_p(g_sff_drv->set_eth_tx_disable_status); + + sscanf(buf, "%d", &value); + eth_index = obj->index; + SFF_DBG("eth index: %u, tx_disable:0x%x\n", eth_index, value); + + if (value < 0 || value > 1) { + SFF_ERR("invalid value: %d, can't set eth%u tx disable status.\n", value, eth_index); + } + + write_buf[0] = 0; + mem_clear(module_type, sizeof(module_type)); + ret = g_sff_drv->read_eth_eeprom_data(eth_index, module_type, 0, 1); + if (ret < 0) { + SFF_ERR("get eth%u module type failed, ret: %d\n", eth_index, ret); + return ret; + } + + if (module_type[0] == 0x03) { + SFF_DBG("get eth%u module type is SFP\n", eth_index); + + ret = g_sff_drv->set_eth_tx_disable_status(eth_index, value); + if (ret < 0) { + SFF_ERR("set eth%u tx disable status %d failed, ret: %d\n", eth_index, value, ret); + return ret; + } + } else { + if ((module_type[0] == 0x11) || (module_type[0] == 0x0D)) { + SFF_DBG("get eth%u module type is QSFP\n", eth_index); + offset = WB_QSFP_TX_DISABLE_OFFSET; + if (value != 0) { + write_buf[0] = 0xf; + } + } else if ((module_type[0] == 0x18) || (module_type[0] == 0x1e)) { + SFF_DBG("get eth%u module type is QSFP-DD\n", eth_index); + offset = WB_QSFPDD_TX_DISABLE_OFFSET; + if (value != 0) { + write_buf[0] = 0xff; + } + } else { + SFF_ERR("eth%u module is unknown, module_type:%d\n", eth_index, module_type[0]); + return -EINVAL; + } + + ret = g_sff_drv->write_eth_eeprom_data(eth_index, write_buf, offset, 1); + if (ret < 0) { + SFF_ERR("set eth%u tx disable status %d failed, ret: %d\n", eth_index, value, ret); + return ret; + } + } + + SFF_DBG("set eth%u tx disable status %d success\n", eth_index, value); + return count; +} + +static ssize_t eth_present_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int eth_index; + int ret, res; + char debug_file_buf[DEBUG_FILE_SIZE]; + + check_p(g_sff_drv); + check_p(g_sff_drv->get_eth_present_status); + + eth_index = obj->index; + SFF_DBG("eth index: %u\n", eth_index); + ret = g_sff_drv->get_eth_present_status(eth_index, buf, PAGE_SIZE); + if (ret < 0) { + SFF_ERR("get eth%u present status failed, ret: %d\n", eth_index, ret); + return ret; + } + + if (g_sff_present_debug) { + SFF_INFO("s3ip sysfs sff present debug is enable\n"); + if (strcmp(buf, DEV_ABSENT_STR) == 0) { + SFF_DBG("eth%d absent, return act value\n", eth_index); + return ret; + } + + if ((strncmp(buf, SWITCH_DEV_NO_SUPPORT, strlen(SWITCH_DEV_NO_SUPPORT)) == 0) || (strncmp(buf, SWITCH_DEV_ERROR, strlen(SWITCH_DEV_ERROR)) == 0)) { + SFF_DBG("eth%d status sysfs unsupport or error\n", eth_index); + return ret; + } + + mem_clear(debug_file_buf, sizeof(debug_file_buf)); + res = dev_debug_file_read(SINGLE_TRANSCEIVER_PRESENT_DEBUG_FILE, eth_index, debug_file_buf, sizeof(debug_file_buf)); + if (res) { + SFF_ERR("eth%u present debug file read failed, ret: %d\n", eth_index, res); + return ret; + } + + if ((strcmp(debug_file_buf, DEV_PRESEN_STR) == 0) || (strcmp(debug_file_buf, DEV_ABSENT_STR) == 0)) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s", debug_file_buf); + } else { + SFF_ERR("eth%d present debug file value err, value: %s, not 0 or 1\n", eth_index, debug_file_buf); + return ret; + } + } + return ret; +} + +static ssize_t eth_rx_los_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int eth_index; + int ret; + char module_type[1], value[1]; + loff_t offset; + char mask; + + check_p(g_sff_drv); + check_p(g_sff_drv->read_eth_eeprom_data); + check_p(g_sff_drv->get_eth_rx_los_status); + + eth_index = obj->index; + SFF_DBG("eth index: %u\n", eth_index); + mem_clear(module_type, sizeof(module_type)); + mem_clear(value, sizeof(value)); + ret = g_sff_drv->read_eth_eeprom_data(eth_index, module_type, 0, 1); + if (ret < 0) { + SFF_ERR("get eth%u module type failed, ret: %d\n", eth_index, ret); + if (ret == -WB_SYSFS_RV_UNSUPPORT) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_ERROR); + } + } + + if (module_type[0] == 0x03) { + SFF_DBG("get eth%u module type is SFP\n", eth_index); + return g_sff_drv->get_eth_rx_los_status(eth_index, buf, PAGE_SIZE); + } else { + if ((module_type[0] == 0x11) || (module_type[0] == 0x0D)) { + SFF_DBG("get eth%u module type is QSFP\n", eth_index); + offset = WB_QSFP_RX_LOS_OFFSET; + mask = 0xf; + } else if ((module_type[0] == 0x18) || (module_type[0] == 0x1e)) { + SFF_DBG("get eth%u module type is QSFP-DD\n", eth_index); + offset = WB_QSFPDD_RX_LOS_OFFSET; + mask = 0xff; + } else { + SFF_ERR("eth%u module is unknown, module_type:%d\n", eth_index, module_type[0]); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_ERROR); + } + + ret = g_sff_drv->read_eth_eeprom_data(eth_index, value, offset, 1); + if (ret < 0) { + SFF_ERR("get eth%u module rx los value failed, ret: %d\n", eth_index, ret); + if (ret == -WB_SYSFS_RV_UNSUPPORT) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_ERROR); + } + } + + if ((value[0] & mask) != 0) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", 1); + } else { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", 0); + } + } + + return ret; +} + +static ssize_t eth_reset_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int eth_index; + + check_p(g_sff_drv); + check_p(g_sff_drv->get_eth_reset_status); + + eth_index = obj->index; + SFF_DBG("eth index: %u\n", eth_index); + return g_sff_drv->get_eth_reset_status(eth_index, buf, PAGE_SIZE); +} + +static ssize_t eth_reset_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int eth_index; + int ret, value; + + check_p(g_sff_drv); + check_p(g_sff_drv->set_eth_reset_status); + + sscanf(buf, "%d", &value); + eth_index = obj->index; + ret = g_sff_drv->set_eth_reset_status(eth_index, value); + if (ret < 0) { + SFF_ERR("set eth%u reset status %d failed, ret: %d\n", eth_index, value, ret); + return ret; + } + SFF_DBG("set eth%u reset status %d success\n", eth_index, value); + return count; +} + +static ssize_t eth_low_power_mode_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int eth_index; + int ret; + char module_type[1], value[1]; + loff_t offset; + char mask; + + check_p(g_sff_drv); + check_p(g_sff_drv->read_eth_eeprom_data); + + eth_index = obj->index; + SFF_DBG("eth index: %u\n", eth_index); + mem_clear(module_type, sizeof(module_type)); + mem_clear(value, sizeof(value)); + ret = g_sff_drv->read_eth_eeprom_data(eth_index, module_type, 0, 1); + if (ret < 0) { + SFF_ERR("get eth%u module type failed, ret: %d\n", eth_index, ret); + if (ret == -WB_SYSFS_RV_UNSUPPORT) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_ERROR); + } + } + + if (module_type[0] == 0x03) { + SFF_ERR("eth%u SFP module low power mode no support\n", eth_index); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + if ((module_type[0] == 0x11) || (module_type[0] == 0x0D)) { + SFF_DBG("get eth%u module type is QSFP\n", eth_index); + offset = WB_QSFP_LP_MODE_OFFSET; + mask = 0x3; + } else if ((module_type[0] == 0x18) || (module_type[0] == 0x1e)) { + SFF_DBG("get eth%u module type is QSFP-DD\n", eth_index); + offset = WB_QSFPDD_LP_MODE_OFFSET; + mask = 0x10; + } else { + SFF_ERR("eth%u module is unknown, module_type:%d\n", eth_index, module_type[0]); + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_ERROR); + } + + ret = g_sff_drv->read_eth_eeprom_data(eth_index, value, offset, 1); + if (ret < 0) { + SFF_ERR("get eth%u module lp mode value failed, ret: %d\n", eth_index, ret); + if (ret == -WB_SYSFS_RV_UNSUPPORT) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_NO_SUPPORT); + } else { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%s\n", SWITCH_DEV_ERROR); + } + } + + if ((value[0] & mask) == mask) { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", 1); + } else { + return (ssize_t)snprintf(buf, PAGE_SIZE, "%d\n", 0); + } + } + + return ret; +} + +static ssize_t eth_low_power_mode_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int eth_index; + int ret, value; + char module_type[1], tmp_v[1]; + loff_t offset; + unsigned char mask; + + check_p(g_sff_drv); + check_p(g_sff_drv->read_eth_eeprom_data); + check_p(g_sff_drv->write_eth_eeprom_data); + + sscanf(buf, "%d", &value); + eth_index = obj->index; + SFF_DBG("eth index: %u\n", eth_index); + if (value < 0 || value > 1) { + SFF_ERR("invalid value: %d, can't set eth%u lp mode status.\n", value, eth_index); + return -EINVAL; + } + + mask = 0; + mem_clear(module_type, sizeof(module_type)); + mem_clear(tmp_v, sizeof(tmp_v)); + ret = g_sff_drv->read_eth_eeprom_data(eth_index, module_type, 0, 1); + if (ret < 0) { + SFF_ERR("get eth%u module type failed, ret: %d\n", eth_index, ret); + return ret; + } + SFF_DBG("module type:0x%x\n", module_type[0]); + + if (module_type[0] == 0x03) { + SFF_ERR("eth%u SFP module low power mode no support\n", eth_index); + return -WB_SYSFS_RV_UNSUPPORT; + } else { + if ((module_type[0] == 0x11) || (module_type[0] == 0x0D)) { + SFF_DBG("get eth%u module type is QSFP\n", eth_index); + offset = WB_QSFP_LP_MODE_OFFSET; + mask = 0x3; + } else if ((module_type[0] == 0x18) || (module_type[0] == 0x1e)) { + SFF_DBG("get eth%u module type is QSFP-DD\n", eth_index); + offset = WB_QSFPDD_LP_MODE_OFFSET; + mask = 0x10; + } else { + SFF_ERR("eth%u module is unknown, module_type:%d\n", eth_index, module_type[0]); + return -EINVAL; + } + + ret = g_sff_drv->read_eth_eeprom_data(eth_index, tmp_v, offset, 1); + if (ret < 0) { + SFF_ERR("get eth%u module lp mode value failed, ret: %d\n", eth_index, ret); + return ret; + } + + if (value == 1) { + tmp_v[0] = tmp_v[0] | mask; + } else { + tmp_v[0] = tmp_v[0] & (~mask); + } + + ret = g_sff_drv->write_eth_eeprom_data(eth_index, tmp_v, offset, 1); + if (ret < 0) { + SFF_ERR("set eth%u module lp mode value failed, ret: %d\n", eth_index, ret); + return -EIO; + } + } + + return count; +} + +static ssize_t eth_interrupt_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int eth_index; + + check_p(g_sff_drv); + check_p(g_sff_drv->get_eth_interrupt_status); + + eth_index = obj->index; + SFF_DBG("eth index: %u\n", eth_index); + return g_sff_drv->get_eth_interrupt_status(eth_index, buf, PAGE_SIZE); +} + +static ssize_t eth_eeprom_read(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, + char *buf, loff_t offset, size_t count) +{ + struct switch_obj *eth_obj; + ssize_t rd_len; + unsigned int eth_index; + + check_p(g_sff_drv); + check_p(g_sff_drv->read_eth_eeprom_data); + + eth_obj = to_switch_obj(kobj); + eth_index = eth_obj->index; + mem_clear(buf, count); + rd_len = g_sff_drv->read_eth_eeprom_data(eth_index, buf, offset, count); + if (rd_len < 0) { + SFF_ERR("read eth%u eeprom data error, offset: 0x%llx, read len: %lu, ret: %ld.\n", + eth_index, offset, count, rd_len); + return rd_len; + } + + SFF_DBG("read eth%u eeprom data success, offset:0x%llx, read len:%lu, really read len:%ld.\n", + eth_index, offset, count, rd_len); + + return rd_len; +} + +static ssize_t eth_eeprom_write(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, + char *buf, loff_t offset, size_t count) +{ + struct switch_obj *eth_obj; + ssize_t wr_len; + unsigned int eth_index; + + check_p(g_sff_drv); + check_p(g_sff_drv->write_eth_eeprom_data); + + eth_obj = to_switch_obj(kobj); + eth_index = eth_obj->index; + wr_len = g_sff_drv->write_eth_eeprom_data(eth_index, buf, offset, count); + if (wr_len < 0) { + SFF_ERR("write eth%u eeprom data error, offset: 0x%llx, read len: %lu, ret: %ld.\n", + eth_index, offset, count, wr_len); + return wr_len; + } + + SFF_DBG("write eth%u eeprom data success, offset:0x%llx, write len:%lu, really write len:%ld.\n", + eth_index, offset, count, wr_len); + + return wr_len; +} + +/************************************eth* signal attrs*******************************************/ +static struct switch_attribute eth_power_on_attr = __ATTR(power_on, S_IRUGO | S_IWUSR, eth_power_on_show, eth_power_on_store); +static struct switch_attribute eth_tx_fault_attr = __ATTR(tx_fault, S_IRUGO, eth_tx_fault_show, NULL); +static struct switch_attribute eth_tx_disable_attr = __ATTR(tx_disable, S_IRUGO | S_IWUSR, eth_tx_disable_show, eth_tx_disable_store); +static struct switch_attribute eth_present_attr = __ATTR(present, S_IRUGO, eth_present_show, NULL); +static struct switch_attribute eth_rx_los_attr = __ATTR(rx_los, S_IRUGO, eth_rx_los_show, NULL); +static struct switch_attribute eth_reset_attr = __ATTR(reset, S_IRUGO | S_IWUSR, eth_reset_show, eth_reset_store); +static struct switch_attribute eth_low_power_mode_attr = __ATTR(low_power_mode, S_IRUGO | S_IWUSR, eth_low_power_mode_show, eth_low_power_mode_store); +static struct switch_attribute eth_interrupt_attr = __ATTR(interrupt, S_IRUGO, eth_interrupt_show, NULL); +static struct switch_attribute eth_optoe_type_attr = __ATTR(optoe_type, S_IRUGO | S_IWUSR, eth_optoe_type_show, eth_optoe_type_store); + +static struct attribute *sff_signal_attrs[] = { + ð_power_on_attr.attr, + ð_tx_fault_attr.attr, + ð_tx_disable_attr.attr, + ð_present_attr.attr, + ð_rx_los_attr.attr, + ð_reset_attr.attr, + ð_low_power_mode_attr.attr, + ð_interrupt_attr.attr, + ð_optoe_type_attr.attr, + NULL, +}; + +static struct attribute_group sff_signal_attr_group = { + .attrs = sff_signal_attrs, +}; + +/*******************************transceiver dir and attrs*******************************************/ +static struct switch_attribute transceiver_power_on_attr = __ATTR(power_on, S_IRUGO | S_IWUSR, transceiver_power_on_show, transceiver_power_on_store); +static struct switch_attribute transceiver_number_attr = __ATTR(number, S_IRUGO, transceiver_number_show, NULL); +static struct switch_attribute transceiver_present_attr = __ATTR(present, S_IRUGO, transceiver_present_show, NULL); + +static struct attribute *transceiver_dir_attrs[] = { + &transceiver_power_on_attr.attr, + &transceiver_number_attr.attr, + &transceiver_present_attr.attr, + NULL, +}; + +static struct attribute_group sff_transceiver_attr_group = { + .attrs = transceiver_dir_attrs, +}; + +/* create eth* eeprom attributes */ +static int sff_sub_single_create_eeprom_attrs(unsigned int index) +{ + int ret, eeprom_size; + struct sff_obj_s *curr_sff; + + check_p(g_sff_drv->get_eth_eeprom_size); + eeprom_size = g_sff_drv->get_eth_eeprom_size(index); + if (eeprom_size <= 0) { + SFF_INFO("eth%u, eeprom_size: %d, don't need to creat eeprom attr.\n", + index, eeprom_size); + return 0; + } + + curr_sff = &g_sff.sff[index - 1]; + sysfs_bin_attr_init(&curr_sff->bin); + curr_sff->bin.attr.name = "eeprom"; + curr_sff->bin.attr.mode = 0644; + curr_sff->bin.read = eth_eeprom_read; + curr_sff->bin.write = eth_eeprom_write; + curr_sff->bin.size = eeprom_size; + + ret = sysfs_create_bin_file(&curr_sff->sff_obj->kobj, &curr_sff->bin); + if (ret) { + SFF_ERR("eth%u, create eeprom bin error, ret: %d. \n", index, ret); + return -EBADRQC; + } + + SFF_DBG("eth%u, create bin file success, eeprom size:%d.\n", index, eeprom_size); + curr_sff->sff_creat_bin_flag = 1; + return 0; +} + +static int sff_sub_single_create_kobj(struct kobject *parent, unsigned int index) +{ + struct sff_obj_s *curr_sff; + char sff_dir_name[DIR_NAME_MAX_LEN]; + + curr_sff = &g_sff.sff[index - 1]; + mem_clear(sff_dir_name, sizeof(sff_dir_name)); + snprintf(sff_dir_name, sizeof(sff_dir_name), "eth%d", index); + curr_sff->sff_obj = switch_kobject_create(sff_dir_name, parent); + if (!curr_sff->sff_obj) { + SFF_ERR("create eth%d object error! \n", index); + return -EBADRQC; + } + curr_sff->sff_obj->index = index; + if (sysfs_create_group(&curr_sff->sff_obj->kobj, &sff_signal_attr_group) != 0) { + switch_kobject_delete(&curr_sff->sff_obj); + return -EBADRQC; + } + + SFF_DBG("create eth%d dir and attrs success\n", index); + return 0; +} + +/* remove eth directory and attributes */ +static void sff_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct sff_obj_s *curr_sff; + + curr_sff = &g_sff.sff[index - 1]; + if (curr_sff->sff_obj) { + if (curr_sff->sff_creat_bin_flag) { + sysfs_remove_bin_file(&curr_sff->sff_obj->kobj, &curr_sff->bin); + curr_sff->sff_creat_bin_flag = 0; + } + sysfs_remove_group(&curr_sff->sff_obj->kobj, &sff_signal_attr_group); + switch_kobject_delete(&curr_sff->sff_obj); + } + + return; +} + +static int sff_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index) +{ + int ret; + + ret = sff_sub_single_create_kobj(parent, index); + if (ret < 0) { + SFF_ERR("create eth%d dir error.\n", index); + return ret; + } + + sff_sub_single_create_eeprom_attrs(index); + return 0; +} + +static int sff_sub_create_kobj_and_attrs(struct kobject *parent, int sff_num) +{ + unsigned int sff_index, i; + + g_sff.sff = kzalloc(sizeof(struct sff_obj_s) * sff_num, GFP_KERNEL); + if (!g_sff.sff) { + SFF_ERR("kzalloc g_sff.sff error, sff number = %d.\n", sff_num); + return -ENOMEM; + } + + for (sff_index = 1; sff_index <= sff_num; sff_index++) { + if (sff_sub_single_create_kobj_and_attrs(parent, sff_index) != 0) { + goto error; + } + } + return 0; +error: + for (i = sff_index; i > 0; i--) { + sff_sub_single_remove_kobj_and_attrs(i); + } + kfree(g_sff.sff); + g_sff.sff = NULL; + return -EBADRQC; +} + +/* create eth directory and attributes */ +static int sff_sub_create(void) +{ + int ret; + + ret = sff_sub_create_kobj_and_attrs(&g_sff_obj->kobj, g_sff.sff_number); + return ret; +} + +/* delete eth directory and attributes */ +static void sff_sub_remove(void) +{ + unsigned int sff_index; + + if (g_sff.sff) { + for (sff_index = g_sff.sff_number; sff_index > 0; sff_index--) { + sff_sub_single_remove_kobj_and_attrs(sff_index); + } + kfree(g_sff.sff); + g_sff.sff = NULL; + } + g_sff.sff_number = 0; + return; +} + +/* create transceiver directory and attributes */ +static int sff_transceiver_create(void) +{ + g_sff_obj = switch_kobject_create("transceiver", NULL); + if (!g_sff_obj) { + SFF_ERR("switch_kobject_create transceiver error!\n"); + return -ENOMEM; + } + g_sff_obj->index = 0; + if (sysfs_create_group(&g_sff_obj->kobj, &sff_transceiver_attr_group) != 0) { + switch_kobject_delete(&g_sff_obj); + SFF_ERR("create transceiver dir attrs error!\n"); + return -EBADRQC; + } + return 0; +} + +/* delete transceiver directory and attributes */ +static void sff_transceiver_remove(void) +{ + if (g_sff_obj) { + sysfs_remove_group(&g_sff_obj->kobj, &sff_transceiver_attr_group); + switch_kobject_delete(&g_sff_obj); + } + + return; +} + +int s3ip_sysfs_sff_drivers_register(struct s3ip_sysfs_transceiver_drivers_s *drv) +{ + int ret, sff_num; + + SFF_INFO("s3ip_sysfs_sff_drivers_register...\n"); + if (g_sff_drv) { + SFF_ERR("g_sff_drv is not NULL, can't register\n"); + return -EPERM; + } + + check_p(drv); + check_p(drv->get_eth_number); + g_sff_drv = drv; + + sff_num = g_sff_drv->get_eth_number(); + if (sff_num <= 0) { + SFF_ERR("eth number: %d, don't need to create transceiver dirs and attrs.\n", sff_num); + g_sff_drv = NULL; + return -EINVAL; + } + + mem_clear(&g_sff, sizeof(struct sff_s)); + g_sff.sff_number = sff_num; + ret = sff_transceiver_create(); + if (ret < 0) { + SFF_ERR("create transceiver root dir and attrs failed, ret: %d\n", ret); + g_sff_drv = NULL; + return ret; + } + ret = sff_sub_create(); + if (ret < 0) { + SFF_ERR("create transceiver sub dir and attrs failed, ret: %d\n", ret); + sff_transceiver_remove(); + g_sff_drv = NULL; + return ret; + } + SFF_INFO("s3ip_sysfs_sff_drivers_register success\n"); + return ret; +} + +void s3ip_sysfs_sff_drivers_unregister(void) +{ + if (g_sff_drv) { + sff_sub_remove(); + sff_transceiver_remove(); + g_sff_drv = NULL; + SFF_DBG("s3ip_sysfs_sff_drivers_unregister success.\n"); + } + return; +} + +EXPORT_SYMBOL(s3ip_sysfs_sff_drivers_register); +EXPORT_SYMBOL(s3ip_sysfs_sff_drivers_unregister); +module_param(g_sff_loglevel, int, 0644); +MODULE_PARM_DESC(g_sff_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); +module_param(g_sff_present_debug, bool, 0644); +MODULE_PARM_DESC(g_sff_present_debug, "the sff present debug switch(0: disable, 1:enable, defalut: 0).\n"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/vol_sensor_sysfs.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/vol_sensor_sysfs.c new file mode 100644 index 000000000000..737aa3d94393 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/vol_sensor_sysfs.c @@ -0,0 +1,416 @@ +/* + * An vol_sensor_sysfs driver for voltage sysfs devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#include "switch.h" +#include "vol_sensor_sysfs.h" + +static int g_vol_sensor_loglevel = 0; + +#define VOL_SENSOR_INFO(fmt, args...) do { \ + if (g_vol_sensor_loglevel & INFO) { \ + printk(KERN_INFO "[VOL_SENSOR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define VOL_SENSOR_ERR(fmt, args...) do { \ + if (g_vol_sensor_loglevel & ERR) { \ + printk(KERN_ERR "[VOL_SENSOR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define VOL_SENSOR_DBG(fmt, args...) do { \ + if (g_vol_sensor_loglevel & DBG) { \ + printk(KERN_DEBUG "[VOL_SENSOR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct vol_sensor_obj_s { + struct switch_obj *obj; +}; + +struct vol_sensor_s { + unsigned int vol_number; + struct vol_sensor_obj_s *vol; +}; + +static struct s3ip_sysfs_vol_sensor_drivers_s *g_vol_sensor_drv = NULL; +static struct vol_sensor_s g_vol_sensor; +static struct switch_obj *g_vol_sensor_obj = NULL; + +static ssize_t vol_sensor_number_show(struct switch_obj *obj, struct switch_attribute *attr, + char *buf) +{ + return (ssize_t)snprintf(buf, PAGE_SIZE, "%u\n", g_vol_sensor.vol_number); +} + +static ssize_t vol_sensor_value_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int vol_index; + + check_p(g_vol_sensor_drv); + check_p(g_vol_sensor_drv->get_main_board_vol_value); + + vol_index = obj->index; + VOL_SENSOR_DBG("vol index: %u\n", vol_index); + return g_vol_sensor_drv->get_main_board_vol_value(vol_index, buf, PAGE_SIZE); +} + +static ssize_t vol_sensor_alias_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int vol_index; + + check_p(g_vol_sensor_drv); + check_p(g_vol_sensor_drv->get_main_board_vol_alias); + + vol_index = obj->index; + VOL_SENSOR_DBG("vol index: %u\n", vol_index); + return g_vol_sensor_drv->get_main_board_vol_alias(vol_index, buf, PAGE_SIZE); +} + +static ssize_t vol_sensor_type_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int vol_index; + + check_p(g_vol_sensor_drv); + check_p(g_vol_sensor_drv->get_main_board_vol_type); + + vol_index = obj->index; + VOL_SENSOR_DBG("vol index: %u\n", vol_index); + return g_vol_sensor_drv->get_main_board_vol_type(vol_index, buf, PAGE_SIZE); +} + +static ssize_t vol_sensor_max_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int vol_index; + + check_p(g_vol_sensor_drv); + check_p(g_vol_sensor_drv->get_main_board_vol_max); + + vol_index = obj->index; + VOL_SENSOR_DBG("vol index: %u\n", vol_index); + return g_vol_sensor_drv->get_main_board_vol_max(vol_index, buf, PAGE_SIZE); +} + +static ssize_t vol_sensor_max_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int vol_index; + int ret; + + check_p(g_vol_sensor_drv); + check_p(g_vol_sensor_drv->set_main_board_vol_max); + + vol_index = obj->index; + VOL_SENSOR_DBG("vol index: %u\n", vol_index); + ret = g_vol_sensor_drv->set_main_board_vol_max(vol_index, buf, count); + if (ret < 0) { + VOL_SENSOR_ERR("set vol%u max threshold failed, value: %s, count: %lu, ret: %d\n", + vol_index, buf, count, ret); + return ret; + } + VOL_SENSOR_DBG("set vol%u max threshold success, value: %s, count: %lu, ret: %d\n", + vol_index, buf, count, ret); + return count; +} + +static ssize_t vol_sensor_min_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int vol_index; + + check_p(g_vol_sensor_drv); + check_p(g_vol_sensor_drv->get_main_board_vol_min); + + vol_index = obj->index; + VOL_SENSOR_DBG("vol index: %u\n", vol_index); + return g_vol_sensor_drv->get_main_board_vol_min(vol_index, buf, PAGE_SIZE); +} + +static ssize_t vol_sensor_min_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + unsigned int vol_index; + int ret; + + check_p(g_vol_sensor_drv); + check_p(g_vol_sensor_drv->set_main_board_vol_min); + + vol_index = obj->index; + VOL_SENSOR_DBG("vol index: %u\n", vol_index); + ret = g_vol_sensor_drv->set_main_board_vol_min(vol_index, buf, count); + if (ret < 0) { + VOL_SENSOR_ERR("set vol%u min threshold failed, value: %s, count: %lu, ret: %d\n", + vol_index, buf, count, ret); + return ret; + } + VOL_SENSOR_DBG("set vol%u min threshold success, value: %s, count: %lu, ret: %d\n", + vol_index, buf, count, ret); + return count; +} + +static ssize_t vol_sensor_range_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int vol_index; + + check_p(g_vol_sensor_drv); + check_p(g_vol_sensor_drv->get_main_board_vol_range); + + vol_index = obj->index; + VOL_SENSOR_DBG("vol index: %u\n", vol_index); + return g_vol_sensor_drv->get_main_board_vol_range(vol_index, buf, PAGE_SIZE); +} + +static ssize_t vol_sensor_nominal_value_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int vol_index; + + check_p(g_vol_sensor_drv); + check_p(g_vol_sensor_drv->get_main_board_vol_nominal_value); + + vol_index = obj->index; + VOL_SENSOR_DBG("vol index: %u\n", vol_index); + return g_vol_sensor_drv->get_main_board_vol_nominal_value(vol_index, buf, PAGE_SIZE); +} + +static ssize_t vol_sensor_monitor_flag_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + unsigned int vol_index; + + check_p(g_vol_sensor_drv); + check_p(g_vol_sensor_drv->get_main_board_vol_monitor_flag); + + vol_index = obj->index; + VOL_SENSOR_DBG("vol index: %u\n", vol_index); + return g_vol_sensor_drv->get_main_board_vol_monitor_flag(vol_index, buf, PAGE_SIZE); +} + +/************************************vol_sensor dir and attrs*******************************************/ +static struct switch_attribute num_vol_att = __ATTR(number, S_IRUGO, vol_sensor_number_show, NULL); + +static struct attribute *vol_sensor_dir_attrs[] = { + &num_vol_att.attr, + NULL, +}; + +static struct attribute_group vol_sensor_root_attr_group = { + .attrs = vol_sensor_dir_attrs, +}; + +/*******************************vol1 vol2 dir and attrs*******************************************/ +static struct switch_attribute vol_value_attr = __ATTR(value, S_IRUGO, vol_sensor_value_show, NULL); +static struct switch_attribute vol_alias_attr = __ATTR(alias, S_IRUGO, vol_sensor_alias_show, NULL); +static struct switch_attribute vol_type_attr = __ATTR(type, S_IRUGO, vol_sensor_type_show, NULL); +static struct switch_attribute vol_max_attr = __ATTR(max, S_IRUGO | S_IWUSR, vol_sensor_max_show, vol_sensor_max_store); +static struct switch_attribute vol_min_attr = __ATTR(min, S_IRUGO | S_IWUSR, vol_sensor_min_show, vol_sensor_min_store); +static struct switch_attribute vol_range_attr = __ATTR(range, S_IRUGO, vol_sensor_range_show, NULL); +static struct switch_attribute vol_nominal_value_attr = __ATTR(nominal_value, S_IRUGO, vol_sensor_nominal_value_show, NULL); +static struct switch_attribute vol_monitor_flag_attr = __ATTR(monitor_flag, S_IRUGO, vol_sensor_monitor_flag_show, NULL); + +static struct attribute *vol_sensor_attrs[] = { + &vol_value_attr.attr, + &vol_alias_attr.attr, + &vol_type_attr.attr, + &vol_max_attr.attr, + &vol_min_attr.attr, + &vol_range_attr.attr, + &vol_nominal_value_attr.attr, + &vol_monitor_flag_attr.attr, + NULL, +}; + +static struct attribute_group vol_sensor_attr_group = { + .attrs = vol_sensor_attrs, +}; + +static int vol_sensor_sub_single_create_kobj_and_attrs(struct kobject *parent, unsigned int index) +{ + char name[DIR_NAME_MAX_LEN]; + struct vol_sensor_obj_s *vol_sensor; + + vol_sensor = &g_vol_sensor.vol[index - 1]; + mem_clear(name, sizeof(name)); + snprintf(name, sizeof(name), "vol%u", index); + vol_sensor->obj = switch_kobject_create(name, parent); + if (!vol_sensor->obj) { + VOL_SENSOR_ERR("create %s object error.\n", name); + return -ENOMEM; + } + + vol_sensor->obj->index = index; + if (sysfs_create_group(&vol_sensor->obj->kobj, &vol_sensor_attr_group) != 0) { + VOL_SENSOR_ERR("create %s attrs error.\n", name); + switch_kobject_delete(&vol_sensor->obj); + return -EBADRQC; + } + VOL_SENSOR_DBG("create %s dir and attrs success.\n", name); + + return 0; +} + +static void vol_sensor_sub_single_remove_kobj_and_attrs(unsigned int index) +{ + struct vol_sensor_obj_s *vol_sensor; + + vol_sensor = &g_vol_sensor.vol[index - 1]; + if (vol_sensor->obj) { + sysfs_remove_group(&vol_sensor->obj->kobj, &vol_sensor_attr_group); + switch_kobject_delete(&vol_sensor->obj); + VOL_SENSOR_DBG("delete vol%u dir and attrs success.\n", index); + } + + return; +} + +static int vol_sensor_sub_create_kobj_and_attrs(struct kobject *parent, int vol_num) +{ + unsigned int vol_index, i; + + g_vol_sensor.vol = kzalloc(sizeof(struct vol_sensor_obj_s) * vol_num, GFP_KERNEL); + if (!g_vol_sensor.vol) { + VOL_SENSOR_ERR("kzalloc g_vol_sensor.vol error, vol number: %d.\n", vol_num); + return -ENOMEM; + } + + for (vol_index = 1; vol_index <= vol_num; vol_index++) { + if (vol_sensor_sub_single_create_kobj_and_attrs(parent, vol_index) != 0) { + goto error; + } + } + return 0; +error: + for (i = vol_index; i > 0; i--) { + vol_sensor_sub_single_remove_kobj_and_attrs(i); + } + kfree(g_vol_sensor.vol); + g_vol_sensor.vol = NULL; + return -EBADRQC; +} + +/* create vol[1-n] directory and attributes*/ +static int vol_sensor_sub_create(void) +{ + int ret; + + ret = vol_sensor_sub_create_kobj_and_attrs(&g_vol_sensor_obj->kobj, g_vol_sensor.vol_number); + return ret; +} + +/* delete vol[1-n] directory and attributes*/ +static void vol_sensor_sub_remove(void) +{ + unsigned int vol_index; + + if (g_vol_sensor.vol) { + for (vol_index = g_vol_sensor.vol_number; vol_index > 0; vol_index--) { + vol_sensor_sub_single_remove_kobj_and_attrs(vol_index); + } + kfree(g_vol_sensor.vol); + g_vol_sensor.vol = NULL; + } + + return; +} + +/* create vol_sensor directory and number attributes */ +static int vol_sensor_root_create(void) +{ + g_vol_sensor_obj = switch_kobject_create("vol_sensor", NULL); + if (!g_vol_sensor_obj) { + VOL_SENSOR_ERR("switch_kobject_create vol_sensor error!\n"); + return -ENOMEM; + } + + if (sysfs_create_group(&g_vol_sensor_obj->kobj, &vol_sensor_root_attr_group) != 0) { + switch_kobject_delete(&g_vol_sensor_obj); + VOL_SENSOR_ERR("create vol_sensor dir attrs error!\n"); + return -EBADRQC; + } + + return 0; +} + +/* delete vol_sensor directory and number attributes */ +static void vol_sensor_root_remove(void) +{ + if (g_vol_sensor_obj) { + sysfs_remove_group(&g_vol_sensor_obj->kobj, &vol_sensor_root_attr_group); + switch_kobject_delete(&g_vol_sensor_obj); + } + + return; +} + +int s3ip_sysfs_vol_sensor_drivers_register(struct s3ip_sysfs_vol_sensor_drivers_s *drv) +{ + int ret, vol_num; + + VOL_SENSOR_INFO("s3ip_sysfs_vol_sensor_drivers_register...\n"); + if (g_vol_sensor_drv) { + VOL_SENSOR_ERR("g_vol_sensor_drv is not NULL, can't register\n"); + return -EPERM; + } + + check_p(drv); + check_p(drv->get_main_board_vol_number); + g_vol_sensor_drv = drv; + + vol_num = g_vol_sensor_drv->get_main_board_vol_number(); + if (vol_num <= 0) { + VOL_SENSOR_ERR("vol sensor number: %d, don't need to create vol_sensor dirs and attrs.\n", + vol_num); + g_vol_sensor_drv = NULL; + return -EINVAL; + } + mem_clear(&g_vol_sensor, sizeof(struct vol_sensor_s)); + g_vol_sensor.vol_number = vol_num; + ret = vol_sensor_root_create(); + if (ret < 0) { + VOL_SENSOR_ERR("create vol_sensor root dir and attrs failed, ret: %d\n", ret); + g_vol_sensor_drv = NULL; + return ret; + } + + ret = vol_sensor_sub_create(); + if (ret < 0) { + VOL_SENSOR_ERR("create vol_sensor sub dir and attrs failed, ret: %d\n", ret); + vol_sensor_root_remove(); + g_vol_sensor_drv = NULL; + return ret; + } + VOL_SENSOR_INFO("s3ip_sysfs_vol_sensor_drivers_register success\n"); + return ret; +} + +void s3ip_sysfs_vol_sensor_drivers_unregister(void) +{ + if (g_vol_sensor_drv) { + vol_sensor_sub_remove(); + vol_sensor_root_remove(); + g_vol_sensor_drv = NULL; + VOL_SENSOR_DBG("s3ip_sysfs_vol_sensor_drivers_unregister success.\n"); + } + return; +} + +EXPORT_SYMBOL(s3ip_sysfs_vol_sensor_drivers_register); +EXPORT_SYMBOL(s3ip_sysfs_vol_sensor_drivers_unregister); +module_param(g_vol_sensor_loglevel, int, 0644); +MODULE_PARM_DESC(g_vol_sensor_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/watchdog_sysfs.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/watchdog_sysfs.c new file mode 100644 index 000000000000..3188f18958f4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/s3ip_sysfs/sysfs_driver/watchdog_sysfs.c @@ -0,0 +1,241 @@ +/* + * An watchdog_sysfs driver for watchdog sysfs devcie function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#include "switch.h" +#include "watchdog_sysfs.h" + +static int g_wdt_loglevel = 0; + +#define WDT_INFO(fmt, args...) do { \ + if (g_wdt_loglevel & INFO) { \ + printk(KERN_INFO "[WDT_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WDT_ERR(fmt, args...) do { \ + if (g_wdt_loglevel & ERR) { \ + printk(KERN_ERR "[WDT_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WDT_DBG(fmt, args...) do { \ + if (g_wdt_loglevel & DBG) { \ + printk(KERN_DEBUG "[WDT_SYSFS][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +typedef enum wdt_enable_status_e { + WDT_DISENABLE = 0, /* close watchdog */ + WDT_ENABLE = 1, /* open watchdog */ +} wdt_enable_status_t; + +static struct switch_obj *g_watchdog_obj = NULL; +static struct s3ip_sysfs_watchdog_drivers_s *g_wdt_drv = NULL; + +static ssize_t watchdog_identify_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + check_p(g_wdt_drv); + check_p(g_wdt_drv->get_watchdog_identify); + + return g_wdt_drv->get_watchdog_identify(buf, PAGE_SIZE); +} + +static ssize_t watchdog_timeleft_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + check_p(g_wdt_drv); + check_p(g_wdt_drv->get_watchdog_timeleft); + + return g_wdt_drv->get_watchdog_timeleft(buf, PAGE_SIZE); +} + +static ssize_t watchdog_timeout_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + check_p(g_wdt_drv); + check_p(g_wdt_drv->get_watchdog_timeout); + + return g_wdt_drv->get_watchdog_timeout(buf, PAGE_SIZE); +} + +static ssize_t watchdog_timeout_store(struct switch_obj *obj, struct switch_attribute *attr, + const char *buf, size_t count) +{ + int ret, value; + + check_p(g_wdt_drv); + check_p(g_wdt_drv->set_watchdog_timeout); + + sscanf(buf, "%d", &value); + if (value < 0) { + WDT_ERR("invaild timeout value: %d, can't set watchdog timeout\n", value); + return -EINVAL; + } + + ret = g_wdt_drv->set_watchdog_timeout(value); + if (ret < 0) { + WDT_ERR("set watchdog timeout value: %d failed, ret: %d\n", value, ret); + return ret; + } + WDT_DBG("set watchdog timeout value: %d success\n", ret); + return count; +} + +static ssize_t watchdog_enable_status_show(struct switch_obj *obj, struct switch_attribute *attr, char *buf) +{ + check_p(g_wdt_drv); + check_p(g_wdt_drv->get_watchdog_enable_status); + + return g_wdt_drv->get_watchdog_enable_status(buf, PAGE_SIZE); +} + +static ssize_t watchdog_enable_status_store(struct switch_obj *obj, struct switch_attribute *attr, + const char *buf, size_t count) +{ + int ret, value; + + check_p(g_wdt_drv); + check_p(g_wdt_drv->set_watchdog_enable_status); + + sscanf(buf, "%d", &value); + if ((value != WDT_DISENABLE) && (value != WDT_ENABLE)) { + WDT_ERR("invaild enable value: %d, can't set watchdog enable status\n", value); + return -EINVAL; + } + + ret = g_wdt_drv->set_watchdog_enable_status(value); + if (ret < 0) { + WDT_ERR("set watchdog enable status %d failed, ret: %d\n", value, ret); + return ret; + } + WDT_DBG("set watchdog enable status %d success\n", ret); + return count; +} + +static ssize_t watchdog_reset_store(struct switch_obj *obj, struct switch_attribute *attr, + const char* buf, size_t count) +{ + int ret, value; + + check_p(g_wdt_drv); + check_p(g_wdt_drv->set_watchdog_reset); + + ret = kstrtoint(buf, 0, &value); + if (ret) { + WDT_ERR("invalid value: %s \n", buf); + return -EINVAL; + } + + ret = g_wdt_drv->set_watchdog_reset(value); + if (ret < 0) { + WDT_ERR("set watchdog reset %d failed, ret: %d\n", value, ret); + return ret; + } + WDT_DBG("set watchdog reset %d success\n", ret); + return count; +} + +/************************************watchdog*******************************************/ +static struct switch_attribute watchdog_identify_attr = __ATTR(identify, S_IRUGO, watchdog_identify_show, NULL); +static struct switch_attribute watchdog_timeleft_attr = __ATTR(timeleft, S_IRUGO, watchdog_timeleft_show, NULL); +static struct switch_attribute watchdog_timeout_attr = __ATTR(timeout, S_IRUGO | S_IWUSR, watchdog_timeout_show, watchdog_timeout_store); +static struct switch_attribute watchdog_enable_attr = __ATTR(enable, S_IRUGO | S_IWUSR, watchdog_enable_status_show, watchdog_enable_status_store); +static struct switch_attribute watchdog_reset_attr = __ATTR(reset, S_IWUSR, NULL, watchdog_reset_store); + +static struct attribute *watchdog_dir_attrs[] = { + &watchdog_identify_attr.attr, + &watchdog_timeleft_attr.attr, + &watchdog_timeout_attr.attr, + &watchdog_enable_attr.attr, + &watchdog_reset_attr.attr, + NULL, +}; + +static struct attribute_group watchdog_attr_group = { + .attrs = watchdog_dir_attrs, +}; + +/* create watchdog directory and attributes */ +static int watchdog_root_create(void) +{ + g_watchdog_obj = switch_kobject_create("watchdog", NULL); + if (!g_watchdog_obj) { + WDT_ERR("switch_kobject_create watchdog error!\n"); + return -ENOMEM; + } + + if (sysfs_create_group(&g_watchdog_obj->kobj, &watchdog_attr_group) != 0) { + switch_kobject_delete(&g_watchdog_obj); + WDT_ERR("create fan dir attrs error!\n"); + return -EBADRQC; + } + + return 0; +} + +/* delete watchdog directory and attributes */ +static void watchdog_root_remove(void) +{ + if (g_watchdog_obj) { + sysfs_remove_group(&g_watchdog_obj->kobj, &watchdog_attr_group); + switch_kobject_delete(&g_watchdog_obj); + } + + return; +} + +int s3ip_sysfs_watchdog_drivers_register(struct s3ip_sysfs_watchdog_drivers_s *drv) +{ + int ret; + + WDT_INFO("s3ip_sysfs_watchdog_drivers_register...\n"); + if (g_wdt_drv) { + WDT_ERR("g_wdt_drv is not NULL, can't register\n"); + return -EPERM; + } + + check_p(drv); + g_wdt_drv = drv; + + ret = watchdog_root_create(); + if (ret < 0) { + WDT_ERR("watchdog create error.\n"); + g_wdt_drv = NULL; + return ret; + } + WDT_INFO("s3ip_sysfs_watchdog_drivers_register success\n"); + return 0; +} + +void s3ip_sysfs_watchdog_drivers_unregister(void) +{ + if (g_wdt_drv) { + watchdog_root_remove(); + g_wdt_drv = NULL; + WDT_DBG("s3ip_sysfs_watchdog_drivers_unregister success.\n"); + } + + return; +} + +EXPORT_SYMBOL(s3ip_sysfs_watchdog_drivers_register); +EXPORT_SYMBOL(s3ip_sysfs_watchdog_drivers_unregister); +module_param(g_wdt_loglevel, int, 0644); +MODULE_PARM_DESC(g_wdt_loglevel, "the log level(info=0x1, err=0x2, dbg=0x4).\n"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_csu550.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_csu550.c index 0b95663b9bad..55f6a529c7be 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_csu550.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_csu550.c @@ -1,8 +1,21 @@ -// SPDX-License-Identifier: GPL-2.0-or-later /* - * Hardware monitoring driver for PMBus devices + * An wb_csu550 driver for psu csu550 function * - * Copyright (c) 2010, 2011 Ericsson AB. + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_fpga_i2c_bus_drv.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_fpga_i2c_bus_drv.c index 22cd9e16de08..b237df4e36a9 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_fpga_i2c_bus_drv.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_fpga_i2c_bus_drv.c @@ -1,7 +1,23 @@ /* - * fpga_i2c_bus_drv.c - * ko to create fpga i2c adapter + * An wb_fpga_i2c_bus_drv driver for create fpga i2c adapter function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + #include #include #include @@ -34,6 +50,8 @@ extern int io_device_func_write(const char *path, uint32_t pos, uint8_t *val, si extern int io_device_func_read(const char *path, uint32_t pos, uint8_t *val, size_t size); extern int spi_device_func_read(const char *path, uint32_t offset, uint8_t *buf, size_t count); extern int spi_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count); +extern int indirect_device_func_write(const char *path, uint32_t pos, uint8_t *val, size_t size); +extern int indirect_device_func_read(const char *path, uint32_t pos, uint8_t *val, size_t size); #define FPGA_I2C_STRETCH_TIMEOUT (0x01) #define FPGA_I2C_DEADLOCK_FAILED (0x02) @@ -53,6 +71,7 @@ extern int spi_device_func_write(const char *path, uint32_t offset, uint8_t *buf #define SYMBOL_PCIE_DEV_MODE (3) #define SYMBOL_IO_DEV_MODE (4) #define SYMBOL_SPI_DEV_MODE (5) +#define SYMBOL_INDIRECT_DEV_MODE (6) int g_wb_fpga_i2c_debug = 0; int g_wb_fpga_i2c_error = 0; @@ -170,6 +189,9 @@ static int fpga_device_write(fpga_i2c_dev_t *fpga_i2c, uint32_t pos, uint8_t *va case SYMBOL_SPI_DEV_MODE: ret = spi_device_func_write(fpga_i2c->dev_name, pos, val, size); break; + case SYMBOL_INDIRECT_DEV_MODE: + ret = indirect_device_func_write(fpga_i2c->dev_name, pos, val, size); + break; default: FPGA_I2C_ERROR("err func_mode %d, write failed.\n", fpga_i2c->i2c_func_mode); return -EINVAL; @@ -198,6 +220,9 @@ static int fpga_device_read(fpga_i2c_dev_t *fpga_i2c, uint32_t pos, uint8_t *val case SYMBOL_SPI_DEV_MODE: ret = spi_device_func_read(fpga_i2c->dev_name, pos, val, size); break; + case SYMBOL_INDIRECT_DEV_MODE: + ret = indirect_device_func_read(fpga_i2c->dev_name, pos, val, size); + break; default: FPGA_I2C_ERROR("err func_mode %d, read failed.\n", fpga_i2c->i2c_func_mode); return -EINVAL; diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_fpga_pca954x_drv.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_fpga_pca954x_drv.c index 25f2d60b9334..d55d0cef122f 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_fpga_pca954x_drv.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_fpga_pca954x_drv.c @@ -1,3 +1,23 @@ +/* + * An wb_fpga_pca954x_drv driver for create fpga pca954x adapter function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #include #include #include @@ -17,6 +37,7 @@ extern int i2c_device_func_write(const char *path, uint32_t pos, uint8_t *val, s extern int pcie_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count); extern int io_device_func_write(const char *path, uint32_t pos, uint8_t *val, size_t size); extern int spi_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count); +extern int indirect_device_func_write(const char *path, uint32_t pos, uint8_t *val, size_t size); #define PCA954X_MAX_NCHANS (8) #define FPGA_INTERNAL_PCA9548 (1) @@ -29,6 +50,7 @@ extern int spi_device_func_write(const char *path, uint32_t offset, uint8_t *buf #define SYMBOL_PCIE_DEV_MODE (3) #define SYMBOL_IO_DEV_MODE (4) #define SYMBOL_SPI_DEV_MODE (5) +#define SYMBOL_INDIRECT_DEV_MODE (6) int g_fpga_pca954x_debug = 0; int g_fpga_pca954x_error = 0; @@ -189,6 +211,9 @@ static int fpga_device_write(fpga_i2c_dev_t *fpga_i2c, int pos, unsigned char *v case SYMBOL_SPI_DEV_MODE: ret = spi_device_func_write(fpga_i2c->dev_name, pos, val, size); break; + case SYMBOL_INDIRECT_DEV_MODE: + ret = indirect_device_func_write(fpga_i2c->dev_name, pos, val, size); + break; default: FPGA_PCA954X_ERROR("err func_mode %d, write failed.\n", fpga_i2c->i2c_func_mode); return -EINVAL; @@ -416,7 +441,6 @@ static int fpga_i2c_pca954x_probe(struct i2c_client *client, const struct i2c_de data->type = id->driver_data; /* BUS ID */ ret = of_property_read_u32(dev->of_node, "fpga_9548_flag", &data->fpga_9548_flag); - ret += of_property_read_u32(dev->of_node, "fpga_9548_reset_flag", &data->fpga_9548_reset_flag); if (ret != 0) { dev_err(&client->dev, "Failed to get 954x dts config, ret:%d.\n", ret); ret = -EINVAL; @@ -431,7 +455,8 @@ static int fpga_i2c_pca954x_probe(struct i2c_client *client, const struct i2c_de FPGA_PCA954X_VERBOSE("pca9548_base_nr:%u.\n", data->pca9548_base_nr); } } - + data->fpga_9548_reset_flag = 1; + dev_info(&client->dev, "pca9548_reset_mode is forcibly set to the hardware automatic reset mode.\n"); if (data->fpga_9548_flag != FPGA_EXTERNAL_PCA9548 && data->fpga_9548_flag != FPGA_INTERNAL_PCA9548) { dev_err(&client->dev, "Error: fpga 954x flag config error, value:0x%x.\n", data->fpga_9548_flag); ret = -EINVAL; diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_fpga_pcie.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_fpga_pcie.c index baabfb5cd4d0..43fc67419f0a 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_fpga_pcie.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_fpga_pcie.c @@ -1,7 +1,23 @@ /* - * wb_fpga_pcie.c - * ko to enable fpga pcie + * An wb_fpga_pcie driver for create fpga pcie adapter function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + #include #include #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_gpio_d1500.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_gpio_d1500.c index 7d5d5da87ea7..25fa7acc1f1f 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_gpio_d1500.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_gpio_d1500.c @@ -1,10 +1,24 @@ /* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. + * An wb_gpio_d1500 driver for gpio d1500 function * - * Copyright (C) 2011, 2012 Cavium Inc. + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + + #include #include #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_gpio_device.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_gpio_device.c index 75f883b5909d..cd1fc43da118 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_gpio_device.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_gpio_device.c @@ -1,3 +1,23 @@ +/* + * An wb_gpio_device driver for gpio device function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #include #include #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_dev.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_dev.c index 59cee0b1e1c0..69b2aad0e7c8 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_dev.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_dev.c @@ -1,7 +1,23 @@ /* - * wb_io_dev.c - * ko to read/write i2c client through /dev/XXX device + * An wb_i2c_dev driver for i2c dev function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + #include #include #include @@ -27,8 +43,8 @@ #define WIDTH_2Byte (2) #define WIDTH_4Byte (4) -#define KERNEL_SPASE (0) -#define USER_SPASE (1) +#define KERNEL_SPACE (0) +#define USER_SPACE (1) static int g_i2c_dev_debug = 0; static int g_i2c_dev_error = 0; @@ -467,7 +483,7 @@ static ssize_t i2c_dev_read(struct file *file, char __user *buf, size_t count, l } /* check flag is user spase or kernel spase */ - if (flag == USER_SPASE) { + if (flag == USER_SPACE) { I2C_DEV_DEBUG_DMESG("user space read, buf: %p, offset: %lld, read count %lu.\n", buf, *offset, count); if (copy_to_user(buf, val, read_len)) { @@ -491,7 +507,7 @@ static ssize_t i2c_dev_read_user(struct file *file, char __user *buf, size_t cou I2C_DEV_DEBUG_DMESG("i2c_dev_read_user, file: %p, count: %lu, offset: %lld\n", file, count, *offset); - ret = i2c_dev_read(file, buf, count, offset, USER_SPASE); + ret = i2c_dev_read(file, buf, count, offset, USER_SPACE); return ret; } @@ -501,7 +517,7 @@ static ssize_t i2c_dev_read_iter(struct kiocb *iocb, struct iov_iter *to) I2C_DEV_DEBUG_DMESG("i2c_dev_read_iter, file: %p, count: %lu, offset: %lld\n", iocb->ki_filp, to->count, iocb->ki_pos); - ret = i2c_dev_read(iocb->ki_filp, to->kvec->iov_base, to->count, &iocb->ki_pos, KERNEL_SPASE); + ret = i2c_dev_read(iocb->ki_filp, to->kvec->iov_base, to->count, &iocb->ki_pos, KERNEL_SPACE); return ret; } @@ -530,7 +546,7 @@ static ssize_t i2c_dev_write(struct file *file, const char __user *buf, size_t c mem_clear(val, sizeof(val)); /* check flag is user spase or kernel spase */ - if (flag == USER_SPASE) { + if (flag == USER_SPACE) { I2C_DEV_DEBUG_DMESG("user space write, buf: %p, offset: %lld, write count %lu.\n", buf, *offset, count); if (copy_from_user(val, buf, count)) { @@ -560,7 +576,7 @@ static ssize_t i2c_dev_write_user(struct file *file, const char __user *buf, siz I2C_DEV_DEBUG_DMESG("i2c_dev_write_user, file: %p, count: %lu, offset: %lld\n", file, count, *offset); - ret = i2c_dev_write(file, buf, count, offset, USER_SPASE); + ret = i2c_dev_write(file, buf, count, offset, USER_SPACE); return ret; } @@ -570,7 +586,7 @@ static ssize_t i2c_dev_write_iter(struct kiocb *iocb, struct iov_iter *from) I2C_DEV_DEBUG_DMESG("i2c_dev_write_iter, file: %p, count: %lu, offset: %lld\n", iocb->ki_filp, from->count, iocb->ki_pos); - ret = i2c_dev_write(iocb->ki_filp, from->kvec->iov_base, from->count, &iocb->ki_pos, KERNEL_SPASE); + ret = i2c_dev_write(iocb->ki_filp, from->kvec->iov_base, from->count, &iocb->ki_pos, KERNEL_SPACE); return ret; } diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_dev.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_dev.h index 9cc95d88e804..5d294a7ed410 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_dev.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_dev.h @@ -1,3 +1,23 @@ +/* + * A header definition for wb_i2c_dev driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #ifndef __WB_I2C_DEV_H__ #define __WB_I2C_DEV_H__ #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_gpio_device.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_gpio_device.c index 80f18b2eab55..f884dd202e6a 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_gpio_device.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_gpio_device.c @@ -1,3 +1,23 @@ +/* + * An wb_i2c_gpio_device driver for i2c gpio device adapter function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #include #include #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_mux_pca954x.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_mux_pca954x.c index 854675d9fa99..5c7c566ed4fe 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_mux_pca954x.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_mux_pca954x.c @@ -1,21 +1,7 @@ /* - * I2C multiplexer + * An wb_i2c_mux_pca954x driver for i2c pca954x multiplexer/switch function * - * Copyright (c) 2008-2009 Rodolfo Giometti - * Copyright (c) 2008-2009 Eurotech S.p.A. - * - * This module supports the PCA954x series of I2C multiplexer/switch chips - * made by Philips Semiconductors. - * This includes the: - * PCA9540, PCA9542, PCA9543, PCA9544, PCA9545, PCA9546, PCA9547 - * and PCA9548. - * - * These chips are all controlled via the I2C bus itself, and all have a - * single 8-bit register. The upstream "parent" bus fans out to two, - * four, or eight downstream busses or channels; which of these - * are selected is determined by the chip type and register contents. A - * mux can select only one sub-bus at a time; a switch can select any - * combination simultaneously. + * Copyright (C) 2024 Micas Networks Inc. * * Based on: * pca954x.c from Kumar Gala @@ -30,11 +16,22 @@ * 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. + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_mux_pca954x.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_mux_pca954x.h index beed9b2f94ac..700b36e0236f 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_mux_pca954x.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_mux_pca954x.h @@ -1,3 +1,23 @@ +/* + * A header definition for wb_i2c_mux_pca954x driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #ifndef __WB_I2C_MUX_PCA954X_H__ #define __WB_I2C_MUX_PCA954X_H__ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_mux_pca9641.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_mux_pca9641.c index a3ae9f4b2431..83b0774ec901 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_mux_pca9641.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_mux_pca9641.c @@ -1,19 +1,21 @@ /* - * I2C multiplexer driver for PCA9541 bus master selector + * An wb_i2c_mux_pca9641 driver for pca9641 multiplexer/switch function * - * Copyright (c) 2010 Ericsson AB. + * Copyright (C) 2024 Micas Networks Inc. * - * Author: 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. * - * Derived from: - * pca954x.c + * 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. * - * Copyright (c) 2008-2009 Rodolfo Giometti - * Copyright (c) 2008-2009 Eurotech S.p.A. - * - * 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. + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_mux_pca9641.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_mux_pca9641.h index b87f7585567b..8c8ffa3da03d 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_mux_pca9641.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_mux_pca9641.h @@ -1,3 +1,23 @@ +/* + * A header definition for wb_i2c_mux_pca9641 driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #ifndef __WB_I2C_MUX_PCA9641_H__ #define __WB_I2C_MUX_PCA9641_H__ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_ocores.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_ocores.c index 20f8954cce83..643fc3b605d7 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_ocores.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_ocores.c @@ -1,12 +1,21 @@ -// SPDX-License-Identifier: GPL-2.0 /* - * i2c-ocores.c: I2C bus driver for OpenCores I2C controller - * (https://opencores.org/project/i2c/overview) + * An wb_i2c_ocores driver for i2c ocores function * - * Peter Korsgaard + * Copyright (C) 2024 Micas Networks Inc. * - * Support for the GRLIB port of the controller by - * Andreas Larsson + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_ocores.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_ocores.h index d413ebb3ad44..8b2cd206c084 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_ocores.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_i2c_ocores.h @@ -1,3 +1,23 @@ +/* + * A header definition for wb_ocores driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #ifndef __WB_I2C_OCORES_H__ #define __WB_I2C_OCORES_H__ #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_indirect_dev.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_indirect_dev.c new file mode 100644 index 000000000000..c0a730e77462 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_indirect_dev.c @@ -0,0 +1,869 @@ +/* + * An wb_indirect_dev driver for indirect adapter device function + * + * Copyright (C) 2024 Micas 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, 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 +#include +#include +#include +#include +#include + +#include "wb_indirect_dev.h" +#define MODULE_NAME "wb-indirect-dev" + +#define SYMBOL_I2C_DEV_MODE (1) +#define FILE_MODE (2) +#define SYMBOL_PCIE_DEV_MODE (3) +#define SYMBOL_IO_DEV_MODE (4) +#define SYMBOL_SPI_DEV_MODE (5) + +#define KERNEL_SPACE (0) +#define USER_SPACE (1) + +#define MAX_INDIRECT_DEV_NUM (256) +#define INDIRECT_ADDR_H(addr) ((addr >> 8) & 0xff) +#define INDIRECT_ADDR_L(addr) ((addr) & 0xff) +#define INDIRECT_OP_WRITE (0x2) +#define INDIRECT_OP_READ (0x3) + +static int g_indirect_dev_debug = 0; +static int g_indirect_dev_error = 0; + +module_param(g_indirect_dev_debug, int, S_IRUGO | S_IWUSR); +module_param(g_indirect_dev_error, int, S_IRUGO | S_IWUSR); + +#define INDIRECT_DEV_INFO(fmt, args...) do { \ + printk(KERN_INFO "[INDIRECT_DEV][INFO][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ +} while (0) + +#define INDIRECT_DEV_DEBUG(fmt, args...) do { \ + if (g_indirect_dev_debug) { \ + printk(KERN_DEBUG "[INDIRECT_DEV][DEBUG][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define INDIRECT_DEV_ERROR(fmt, args...) do { \ + if (g_indirect_dev_error) { \ + printk(KERN_ERR "[INDIRECT_DEV][ERR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static struct indirect_dev_info* indirect_dev_arry[MAX_INDIRECT_DEV_NUM]; + +static int noop_pre(struct kprobe *p, struct pt_regs *regs) { return 0; } +static struct kprobe kp = { + .symbol_name = "kallsyms_lookup_name", +}; +unsigned long (*kallsyms_lookup_name_fun)(const char *name) = NULL; + +/* Call kprobe to find the address location of kallsyms_lookup_name */ +static int find_kallsyms_lookup_name(void) +{ + int ret = -1; + + kp.pre_handler = noop_pre; + ret = register_kprobe(&kp); + if (ret < 0) { + INDIRECT_DEV_ERROR("register_kprobe failed, error:%d\n", ret); + return ret; + } + INDIRECT_DEV_DEBUG("kallsyms_lookup_name addr: %p\n", kp.addr); + kallsyms_lookup_name_fun = (void*)kp.addr; + unregister_kprobe(&kp); + + return ret; +} + +struct indirect_dev_info { + const char *name; /* generate dev name */ + const char *logic_dev_name; /* dependent dev name */ + uint32_t indirect_len; /* dev data len */ + uint32_t data_bus_width; /* dev data_bus_width */ + uint32_t addr_bus_width; /* dev addr_bus_width */ + uint32_t wr_data; /* dependent dev wr date reg */ + uint32_t wr_data_width; /* dependent dev wr_data_width */ + uint32_t addr_low; /* dependent dev w/r addr reg low */ + uint32_t addr_high; /* dependent dev w/r addr reg high */ + uint32_t rd_data; /* dependent dev rd date reg */ + uint32_t rd_data_width; /* dependent dev rd_data_width */ + uint32_t opt_ctl; /* dependent dev opt code reg */ + uint32_t logic_func_mode; /* 1: i2c, 2: file, 3:pcie, 4:io, 5:spi */ + unsigned long write_intf_addr; + unsigned long read_intf_addr; + spinlock_t indirect_dev_lock; + struct miscdevice misc; + struct device *dev; +}; + +static int wb_dev_file_read(const char *path, uint32_t pos, uint8_t *val, size_t size) +{ + int ret; + struct file *filp; + loff_t tmp_pos; + + struct kvec iov = { + .iov_base = val, + .iov_len = min_t(size_t, size, MAX_RW_COUNT), + }; + struct iov_iter iter; + + filp = filp_open(path, O_RDONLY, 0); + if (IS_ERR(filp)) { + INDIRECT_DEV_ERROR("read open failed errno = %ld\r\n", -PTR_ERR(filp)); + filp = NULL; + goto exit; + } + tmp_pos = (loff_t)pos; + iov_iter_kvec(&iter, ITER_DEST, &iov, 1, iov.iov_len); + ret = vfs_iter_read(filp, &iter, &tmp_pos, 0); + if (ret < 0) { + INDIRECT_DEV_ERROR("vfs_iter_read failed, path=%s, addr=0x%x, size=%zu, ret=%d\r\n", path, pos, size, ret); + goto exit; + } + filp_close(filp, NULL); + + return ret; + +exit: + if (filp != NULL) { + filp_close(filp, NULL); + } + + return -1; +} + +static int wb_dev_file_write(const char *path, uint32_t pos, uint8_t *val, size_t size) +{ + int ret; + struct file *filp; + loff_t tmp_pos; + + struct kvec iov = { + .iov_base = val, + .iov_len = min_t(size_t, size, MAX_RW_COUNT), + }; + struct iov_iter iter; + + filp = filp_open(path, O_RDWR, 777); + if (IS_ERR(filp)) { + INDIRECT_DEV_ERROR("write open failed errno = %ld\r\n", -PTR_ERR(filp)); + filp = NULL; + goto exit; + } + + tmp_pos = (loff_t)pos; + iov_iter_kvec(&iter, ITER_SOURCE, &iov, 1, iov.iov_len); + ret = vfs_iter_write(filp, &iter, &tmp_pos, 0); + if (ret < 0) { + INDIRECT_DEV_ERROR("vfs_iter_write failed, path=%s, addr=0x%x, size=%zu, ret=%d\r\n", path, pos, size, ret); + goto exit; + } + + vfs_fsync(filp, 1); + filp_close(filp, NULL); + + return ret; + +exit: + if (filp != NULL) { + filp_close(filp, NULL); + } + + return -1; +} + +static int wb_logic_reg_write(struct indirect_dev_info *indirect_dev, uint32_t pos, uint8_t *val, size_t size) +{ + device_func_write pfunc; + + pfunc = (device_func_write)indirect_dev->write_intf_addr; + return pfunc(indirect_dev->logic_dev_name, pos, val, size); +} + +static int wb_logic_reg_read(struct indirect_dev_info *indirect_dev, uint32_t pos, uint8_t *val, size_t size) +{ + device_func_read pfunc; + + pfunc = (device_func_read)indirect_dev->read_intf_addr; + return pfunc(indirect_dev->logic_dev_name, pos, val, size); +} + + +static int indirect_addressing_read(struct indirect_dev_info *indirect_dev, uint8_t *buf, uint32_t address, uint32_t rd_data_width) +{ + uint8_t addr_l, addr_h, op_code; + unsigned long flags; + int ret = 0; + + addr_h = INDIRECT_ADDR_H(address); + addr_l = INDIRECT_ADDR_L(address); + op_code = INDIRECT_OP_READ; + + spin_lock_irqsave(&indirect_dev->indirect_dev_lock, flags); + + ret = wb_logic_reg_write(indirect_dev, indirect_dev->addr_low, &addr_l, WIDTH_1Byte); + if (ret < 0) { + INDIRECT_DEV_ERROR("indirect_read write reg error.offset = 0x%x, value = %u\n", indirect_dev->addr_low, addr_l); + goto fail; + } + + ret = wb_logic_reg_write(indirect_dev, indirect_dev->addr_high, &addr_h, WIDTH_1Byte); + if (ret < 0) { + INDIRECT_DEV_ERROR("indirect_read write reg error.offset = 0x%x, value = %u\n", indirect_dev->addr_high, addr_h); + goto fail; + } + + ret = wb_logic_reg_write(indirect_dev, indirect_dev->opt_ctl, &op_code, WIDTH_1Byte); + if (ret < 0) { + INDIRECT_DEV_ERROR("indirect_read write reg error.offset = 0x%x, value = %u\n", indirect_dev->opt_ctl, INDIRECT_OP_READ); + goto fail; + } + + ret = wb_logic_reg_read(indirect_dev, indirect_dev->rd_data, buf, rd_data_width); + if (ret < 0) { + INDIRECT_DEV_ERROR("indirect_read read reg error.read offset = 0x%x\n, ret = %d", indirect_dev->rd_data, ret); + goto fail; + } + + INDIRECT_DEV_DEBUG("indirect_read success, addr = 0x%x\n", address); + spin_unlock_irqrestore(&indirect_dev->indirect_dev_lock, flags); + return ret; +fail: + spin_unlock_irqrestore(&indirect_dev->indirect_dev_lock, flags); + return ret; +} + +static int device_read(struct indirect_dev_info *indirect_dev, uint32_t offset, uint8_t *buf, size_t count) +{ + int i, ret; + u32 data_width; + u32 tmp; + + data_width = indirect_dev->data_bus_width; + + if (offset % data_width) { + INDIRECT_DEV_ERROR("data bus width:%d, offset:0x%x, read size %zu invalid.\n", + data_width, offset, count); + return -EINVAL; + } + + if (count > indirect_dev->indirect_len - offset) { + INDIRECT_DEV_DEBUG("read count out of range. input len:%zu, read len:%u.\n", + count, indirect_dev->indirect_len - offset); + count = indirect_dev->indirect_len - offset; + } + tmp = count; + + for (i = 0; i < count; i += data_width) { + ret = indirect_addressing_read(indirect_dev, buf + i, offset + i, (tmp > data_width ? data_width : tmp)); + if (ret < 0) { + INDIRECT_DEV_ERROR("read error.read offset = %u\n", (offset + i)); + return -EFAULT; + } + tmp -= data_width; + } + + return count; +} + +static int indirect_addressing_write(struct indirect_dev_info *indirect_dev, uint8_t *buf, uint32_t address, uint32_t wr_data_width) +{ + uint8_t addr_l, addr_h, op_code; + unsigned long flags; + int ret = 0; + + addr_h = INDIRECT_ADDR_H(address); + addr_l = INDIRECT_ADDR_L(address); + op_code = INDIRECT_OP_WRITE; + + spin_lock_irqsave(&indirect_dev->indirect_dev_lock, flags); + + ret = wb_logic_reg_write(indirect_dev, indirect_dev->wr_data, buf, wr_data_width); + if (ret < 0) { + INDIRECT_DEV_ERROR("indirect_write read reg error.read offset = 0x%x\n, ret = %d", indirect_dev->wr_data, ret); + goto fail; + } + + ret = wb_logic_reg_write(indirect_dev, indirect_dev->addr_low, &addr_l, WIDTH_1Byte); + if (ret < 0) { + INDIRECT_DEV_ERROR("indirect_write write reg error.offset = 0x%x, value = %u\n", indirect_dev->addr_low, addr_l); + goto fail; + } + + ret = wb_logic_reg_write(indirect_dev, indirect_dev->addr_high, &addr_h, WIDTH_1Byte); + if (ret < 0) { + INDIRECT_DEV_ERROR("indirect_write write reg error.offset = 0x%x, value = %u\n", indirect_dev->addr_high, addr_h); + goto fail; + } + + ret = wb_logic_reg_write(indirect_dev, indirect_dev->opt_ctl, &op_code, WIDTH_1Byte); + if (ret < 0) { + INDIRECT_DEV_ERROR("indirect_write write reg error.offset = 0x%x, value = %u\n", indirect_dev->opt_ctl, INDIRECT_OP_READ); + goto fail; + } + + INDIRECT_DEV_DEBUG("indirect_write success, addr = 0x%x\n", address); + spin_unlock_irqrestore(&indirect_dev->indirect_dev_lock, flags); + return ret; +fail: + spin_unlock_irqrestore(&indirect_dev->indirect_dev_lock, flags); + return ret; +} + +static int device_write(struct indirect_dev_info *indirect_dev, uint32_t offset, uint8_t *buf, size_t count) +{ + int i, ret; + u32 data_width; + u32 tmp; + + if (offset > indirect_dev->indirect_len) { + INDIRECT_DEV_DEBUG("offset: 0x%x, spi len: 0x%x, count: %zu, EOF.\n", + offset, indirect_dev->indirect_len, count); + return 0; + } + + data_width = indirect_dev->data_bus_width; + if (offset % data_width) { + INDIRECT_DEV_ERROR("data bus width:%d, offset:0x%x, read size %zu invalid.\n", + data_width, offset, count); + return -EINVAL; + } + + if (count > (indirect_dev->indirect_len - offset)) { + INDIRECT_DEV_DEBUG("write count out of range. input len:%zu, read len:%u.\n", + count, indirect_dev->indirect_len - offset); + count = indirect_dev->indirect_len - offset; + } + + if (count == 0) { + INDIRECT_DEV_DEBUG("offset: 0x%x, i2c len: 0x%x, read len: %zu, EOF.\n", + offset, indirect_dev->indirect_len, count); + return 0; + } + + tmp = count; + for (i = 0; i < count; i += data_width) { + ret = indirect_addressing_write(indirect_dev, buf + i, offset + i, (tmp > data_width ? data_width : tmp)); + if (ret < 0) { + INDIRECT_DEV_ERROR("write error.offset = %u\n", (offset + i)); + return -EFAULT; + } + tmp -= data_width; + } + return count; +} + +static ssize_t indirect_dev_read(struct file *file, char __user *buf, size_t count, loff_t *offset, int flag) +{ + u8 val[MAX_RW_LEN]; + int ret, read_len; + struct indirect_dev_info *indirect_dev; + + indirect_dev = file->private_data; + if (indirect_dev == NULL) { + INDIRECT_DEV_ERROR("can't get read private_data.\n"); + return -EINVAL; + } + + if (count == 0) { + INDIRECT_DEV_ERROR("Invalid params, read count is 0.\n"); + return -EINVAL; + } + + if (count > sizeof(val)) { + INDIRECT_DEV_DEBUG("read count %zu exceed max %zu.\n", count, sizeof(val)); + count = sizeof(val); + } + + mem_clear(val, sizeof(val)); + read_len = device_read(indirect_dev, (uint32_t)*offset, val, count); + if (read_len < 0) { + INDIRECT_DEV_ERROR("indirect dev read failed, dev name:%s, offset:0x%x, len:%zu.\n", + indirect_dev->name, (uint32_t)*offset, count); + return read_len; + } + + /* check flag is user spase or kernel spase */ + if (flag == USER_SPACE) { + INDIRECT_DEV_DEBUG("user space read, buf: %p, offset: %lld, read count %zu.\n", + buf, *offset, count); + if (copy_to_user(buf, val, read_len)) { + INDIRECT_DEV_ERROR("copy_to_user failed.\n"); + return -EFAULT; + } + } else { + INDIRECT_DEV_DEBUG("kernel space read, buf: %p, offset: %lld, read count %zu.\n", + buf, *offset, count); + memcpy(buf, val, read_len); + } + + *offset += read_len; + ret = read_len; + return ret; +} + +static ssize_t indirect_dev_read_user(struct file *file, char __user *buf, size_t count, loff_t *offset) +{ + int ret; + + INDIRECT_DEV_DEBUG("indirect_dev_read_user, file: %p, count: %lu, offset: %lld\n", + file, count, *offset); + ret = indirect_dev_read(file, buf, count, offset, USER_SPACE); + return ret; +} + + +static ssize_t indirect_dev_read_iter(struct kiocb *iocb, struct iov_iter *to) +{ + int ret; + + INDIRECT_DEV_DEBUG("indirect_dev_read_iter, file: %p, count: %zu, offset: %lld\n", + iocb->ki_filp, to->count, iocb->ki_pos); + ret = indirect_dev_read(iocb->ki_filp, to->kvec->iov_base, to->count, &iocb->ki_pos, KERNEL_SPACE); + return ret; +} + +static ssize_t indirect_dev_write(struct file *file, const char __user *buf, + size_t count, loff_t *offset, int flag) +{ + u8 val[MAX_RW_LEN]; + int write_len; + struct indirect_dev_info *indirect_dev; + + indirect_dev = file->private_data; + if (indirect_dev == NULL) { + INDIRECT_DEV_ERROR("get write private_data error.\n"); + return -EINVAL; + } + + if (count == 0) { + INDIRECT_DEV_ERROR("Invalid params, write count is 0.\n"); + return -EINVAL; + } + + if (count > sizeof(val)) { + INDIRECT_DEV_DEBUG("write count %zu exceed max %zu.\n", count, sizeof(val)); + count = sizeof(val); + } + + mem_clear(val, sizeof(val)); + /* check flag is user spase or kernel spase */ + if (flag == USER_SPACE) { + INDIRECT_DEV_DEBUG("user space write, buf: %p, offset: %lld, write count %zu.\n", + buf, *offset, count); + if (copy_from_user(val, buf, count)) { + INDIRECT_DEV_ERROR("copy_from_user failed.\n"); + return -EFAULT; + } + } else { + INDIRECT_DEV_DEBUG("kernel space write, buf: %p, offset: %lld, write count %zu.\n", + buf, *offset, count); + memcpy(val, buf, count); + } + + write_len = device_write(indirect_dev, (uint32_t)*offset, val, count); + if (write_len < 0) { + INDIRECT_DEV_ERROR("indirect dev write failed, dev name:%s, offset:0x%llx, len:%zu.\n", + indirect_dev->name, *offset, count); + return write_len; + } + + *offset += write_len; + return write_len; +} + +static ssize_t indirect_dev_write_user(struct file *file, const char __user *buf, size_t count, loff_t *offset) +{ + int ret; + + INDIRECT_DEV_DEBUG("indirect_dev_write_user, file: %p, count: %lu, offset: %lld\n", + file, count, *offset); + ret = indirect_dev_write(file, buf, count, offset, USER_SPACE); + return ret; +} + +static ssize_t indirect_dev_write_iter(struct kiocb *iocb, struct iov_iter *from) +{ + int ret; + + INDIRECT_DEV_DEBUG("indirect_dev_write_iter, file: %p, count: %zu, offset: %lld\n", + iocb->ki_filp, from->count, iocb->ki_pos); + ret = indirect_dev_write(iocb->ki_filp, from->kvec->iov_base, from->count, &iocb->ki_pos, KERNEL_SPACE); + return ret; +} + +static loff_t indirect_dev_llseek(struct file *file, loff_t offset, int origin) +{ + loff_t ret = 0; + struct indirect_dev_info *indirect_dev; + + indirect_dev = file->private_data; + if (indirect_dev == NULL) { + INDIRECT_DEV_ERROR("indirect_dev is NULL, llseek failed.\n"); + return -EINVAL; + } + + switch (origin) { + case SEEK_SET: + if (offset < 0) { + INDIRECT_DEV_ERROR("SEEK_SET, offset:%lld, invalid.\n", offset); + ret = -EINVAL; + break; + } + if (offset > indirect_dev->indirect_len) { + INDIRECT_DEV_ERROR("SEEK_SET out of range, offset:%lld, i2c_len:0x%x.\n", + offset, indirect_dev->indirect_len); + ret = - EINVAL; + break; + } + file->f_pos = offset; + ret = file->f_pos; + break; + case SEEK_CUR: + if (((file->f_pos + offset) > indirect_dev->indirect_len) || ((file->f_pos + offset) < 0)) { + INDIRECT_DEV_ERROR("SEEK_CUR out of range, f_ops:%lld, offset:%lld.\n", + file->f_pos, offset); + } + file->f_pos += offset; + ret = file->f_pos; + break; + default: + INDIRECT_DEV_ERROR("unsupport llseek type:%d.\n", origin); + ret = -EINVAL; + break; + } + return ret; +} + +static long indirect_dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + return 0; +} + +static int indirect_dev_open(struct inode *inode, struct file *file) +{ + unsigned int minor = iminor(inode); + struct indirect_dev_info *indirect_dev; + + if (minor >= MAX_INDIRECT_DEV_NUM) { + INDIRECT_DEV_ERROR("minor out of range, minor = %d.\n", minor); + return -ENODEV; + } + + indirect_dev = indirect_dev_arry[minor]; + if (indirect_dev == NULL) { + INDIRECT_DEV_ERROR("indirect_dev is NULL, open failed, minor = %d\n", minor); + return -ENODEV; + } + + file->private_data = indirect_dev; + + return 0; +} + +static int indirect_dev_release(struct inode *inode, struct file *file) +{ + file->private_data = NULL; + + return 0; +} + +static const struct file_operations indirect_dev_fops = { + .owner = THIS_MODULE, + .llseek = indirect_dev_llseek, + .read = indirect_dev_read_user, + .write = indirect_dev_write_user, + .read_iter = indirect_dev_read_iter, + .write_iter = indirect_dev_write_iter, + .unlocked_ioctl = indirect_dev_ioctl, + .open = indirect_dev_open, + .release = indirect_dev_release, +}; + +static struct indirect_dev_info *dev_match(const char *path) +{ + struct indirect_dev_info *indirect_dev; + char dev_name[DEV_NAME_LEN]; + int i; + + for (i = 0; i < MAX_INDIRECT_DEV_NUM; i++) { + if (indirect_dev_arry[i] == NULL) { + continue; + } + indirect_dev = indirect_dev_arry[i]; + snprintf(dev_name, DEV_NAME_LEN,"/dev/%s", indirect_dev->name); + if (!strcmp(path, dev_name)) { + INDIRECT_DEV_DEBUG("get dev_name = %s, minor = %d\n", dev_name, i); + return indirect_dev; + } + } + + return NULL; +} + +int indirect_device_func_read(const char *path, uint32_t offset, uint8_t *buf, size_t count) +{ + struct indirect_dev_info *indirect_dev; + int read_len; + + if (path == NULL) { + INDIRECT_DEV_ERROR("path NULL"); + return -EINVAL; + } + + if (buf == NULL) { + INDIRECT_DEV_ERROR("buf NULL"); + return -EINVAL; + } + + indirect_dev = dev_match(path); + if (indirect_dev == NULL) { + INDIRECT_DEV_ERROR("indirect_dev match failed. dev path = %s", path); + return -EINVAL; + } + + read_len = device_read(indirect_dev, offset, buf, count); + if (read_len < 0) { + INDIRECT_DEV_ERROR("indirect_dev_read_tmp failed, ret:%d.\n", read_len); + } + return read_len; +} +EXPORT_SYMBOL(indirect_device_func_read); + +int indirect_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t count) +{ + struct indirect_dev_info *indirect_dev; + int write_len; + + if (path == NULL) { + INDIRECT_DEV_ERROR("path NULL"); + return -EINVAL; + } + + if (buf == NULL) { + INDIRECT_DEV_ERROR("buf NULL"); + return -EINVAL; + } + + indirect_dev = dev_match(path); + if (indirect_dev == NULL) { + INDIRECT_DEV_ERROR("indirect_dev match failed. dev path = %s", path); + return -EINVAL; + } + + write_len = device_write(indirect_dev, offset, buf, count); + if (write_len < 0) { + INDIRECT_DEV_ERROR("indirect_dev_write_tmp failed, ret:%d.\n", write_len); + } + return write_len; +} +EXPORT_SYMBOL(indirect_device_func_write); + + +static int wb_indirect_dev_probe(struct platform_device *pdev) +{ + int ret; + struct indirect_dev_info *indirect_dev; + struct miscdevice *misc; + indirect_dev_device_t *indirect_dev_device; + + INDIRECT_DEV_DEBUG("wb_indirect_dev_probe\n"); + + indirect_dev = devm_kzalloc(&pdev->dev, sizeof(struct indirect_dev_info), GFP_KERNEL); + if (!indirect_dev) { + dev_err(&pdev->dev, "devm_kzalloc error.\n"); + return -ENOMEM; + } + + platform_set_drvdata(pdev, indirect_dev); + indirect_dev->dev = &pdev->dev; + + if (pdev->dev.of_node) { + ret = 0; + ret += of_property_read_string(pdev->dev.of_node, "dev_name", &indirect_dev->name); + ret += of_property_read_string(pdev->dev.of_node, "logic_dev_name", &indirect_dev->logic_dev_name); + ret += of_property_read_u32(pdev->dev.of_node, "addr_low", &indirect_dev->addr_low); + ret += of_property_read_u32(pdev->dev.of_node, "data_bus_width", &indirect_dev->data_bus_width); + ret += of_property_read_u32(pdev->dev.of_node, "addr_bus_width", &indirect_dev->addr_bus_width); + ret += of_property_read_u32(pdev->dev.of_node, "addr_high", &indirect_dev->addr_high); + ret += of_property_read_u32(pdev->dev.of_node, "wr_data", &indirect_dev->wr_data); + ret += of_property_read_u32(pdev->dev.of_node, "rd_data", &indirect_dev->rd_data); + ret += of_property_read_u32(pdev->dev.of_node, "opt_ctl", &indirect_dev->opt_ctl); + ret += of_property_read_u32(pdev->dev.of_node, "indirect_len", &indirect_dev->indirect_len); + ret += of_property_read_u32(pdev->dev.of_node, "logic_func_mode", &indirect_dev->logic_func_mode); + + if (of_property_read_u32(pdev->dev.of_node, "wr_data_width", &indirect_dev->wr_data_width)) { + /* dts have no wr_data_width,set default 1 */ + indirect_dev->wr_data_width = WIDTH_1Byte; + } + if (of_property_read_u32(pdev->dev.of_node, "rd_data_width", &indirect_dev->rd_data_width)) { + /* dts have no rd_data_width,set default 1 */ + indirect_dev->rd_data_width = WIDTH_1Byte; + } + if (ret != 0) { + dev_err(&pdev->dev, "dts config error.ret:%d.\n", ret); + return -ENXIO; + } + } else { + if (pdev->dev.platform_data == NULL) { + dev_err(&pdev->dev, "Failed to get platform data config.\n"); + return -ENXIO; + } + indirect_dev_device = pdev->dev.platform_data; + indirect_dev->name = indirect_dev_device->dev_name; + indirect_dev->logic_dev_name = indirect_dev_device->logic_dev_name; + indirect_dev->data_bus_width = indirect_dev_device->data_bus_width; + indirect_dev->addr_bus_width = indirect_dev_device->addr_bus_width; + indirect_dev->wr_data = indirect_dev_device->wr_data; + indirect_dev->wr_data_width = indirect_dev_device->wr_data_width; + indirect_dev->addr_low = indirect_dev_device->addr_low; + indirect_dev->addr_high = indirect_dev_device->addr_high; + indirect_dev->rd_data = indirect_dev_device->rd_data; + indirect_dev->rd_data_width = indirect_dev_device->rd_data_width; + indirect_dev->opt_ctl = indirect_dev_device->opt_ctl; + indirect_dev->indirect_len = indirect_dev_device->indirect_len; + indirect_dev->logic_func_mode = indirect_dev_device->logic_func_mode; + } + + switch (indirect_dev->logic_func_mode) { + case SYMBOL_I2C_DEV_MODE: + indirect_dev->write_intf_addr = (unsigned long)kallsyms_lookup_name_fun("i2c_device_func_write"); + indirect_dev->read_intf_addr = (unsigned long)kallsyms_lookup_name_fun("i2c_device_func_read"); + break; + case SYMBOL_SPI_DEV_MODE: + indirect_dev->write_intf_addr = (unsigned long)kallsyms_lookup_name_fun("spi_device_func_write"); + indirect_dev->read_intf_addr = (unsigned long)kallsyms_lookup_name_fun("spi_device_func_read"); + break; + case SYMBOL_IO_DEV_MODE: + indirect_dev->write_intf_addr = (unsigned long)kallsyms_lookup_name_fun("io_device_func_write"); + indirect_dev->read_intf_addr = (unsigned long)kallsyms_lookup_name_fun("io_device_func_read"); + break; + case SYMBOL_PCIE_DEV_MODE: + indirect_dev->write_intf_addr = (unsigned long)kallsyms_lookup_name_fun("pcie_device_func_write"); + indirect_dev->read_intf_addr = (unsigned long)kallsyms_lookup_name_fun("pcie_device_func_read"); + break; + case FILE_MODE: + indirect_dev->write_intf_addr = (unsigned long)wb_dev_file_write; + indirect_dev->read_intf_addr = (unsigned long)wb_dev_file_read; + break; + default: + dev_err(&pdev->dev, "func mode %d don't support.\n", indirect_dev->logic_func_mode); + return -EINVAL; + } + + if (!indirect_dev->write_intf_addr || !indirect_dev->read_intf_addr) { + dev_err(&pdev->dev, "Fail: func mode %u rw symbol undefined.\n", indirect_dev->logic_func_mode); + return -ENOSYS; + } + + /* TODO: data_bus_width unuse now, need judge in rd or wr */ + dev_info(&pdev->dev, "register indirect device %s success. logic_dev_name: %s, indirect_len: 0x%x, data_bus_width: 0x%x, dependent dev: 0x%x, wr_data: 0x%x, wr_data_width: %d, \ + rd_data: 0x%x, rd_data_width: %d, addr_low: 0x%x, addr_high: 0x%x, opt_ctl: 0x%x, logic_func_mode: %d\n", indirect_dev->name, indirect_dev->logic_dev_name, indirect_dev->indirect_len, indirect_dev->data_bus_width, \ + indirect_dev->addr_bus_width, indirect_dev->wr_data, indirect_dev->wr_data_width, indirect_dev->rd_data, indirect_dev->rd_data_width, indirect_dev->addr_low, indirect_dev->addr_high,\ + indirect_dev->opt_ctl, indirect_dev->logic_func_mode); + + misc = &indirect_dev->misc; + misc->minor = MISC_DYNAMIC_MINOR; + misc->name = indirect_dev->name; + misc->fops = &indirect_dev_fops; + misc->mode = 0666; + if (misc_register(misc) != 0) { + dev_err(&pdev->dev, "register %s faild.\n", misc->name); + return -ENXIO; + } + + if (misc->minor >= MAX_INDIRECT_DEV_NUM) { + dev_err(&pdev->dev, "minor number beyond the limit! is %d.\n", misc->minor); + misc_deregister(misc); + return -ENXIO; + } + spin_lock_init(&indirect_dev->indirect_dev_lock); + indirect_dev_arry[misc->minor] = indirect_dev; + + dev_info(&pdev->dev, "register indirect device %s success.\n", indirect_dev->name); + return 0; +} + +static int wb_indirect_dev_remove(struct platform_device *pdev) +{ + int i; + + for (i = 0; i < MAX_INDIRECT_DEV_NUM; i++) { + if (indirect_dev_arry[i] != NULL) { + if (indirect_dev_arry[i]->dev == &pdev->dev) { + misc_deregister(&indirect_dev_arry[i]->misc); + indirect_dev_arry[i] = NULL; + return 0; + } + } + } + return 0; +} + +static const struct of_device_id wb_indirect_dev_driver_of_match[] = { + { .compatible = "wb-indirect-dev" }, + { }, +}; + +static struct platform_driver wb_indirect_dev_driver = { + .probe = wb_indirect_dev_probe, + .remove = wb_indirect_dev_remove, + .driver = { + .owner = THIS_MODULE, + .name = MODULE_NAME, + .of_match_table = wb_indirect_dev_driver_of_match, + }, +}; + +static int __init wb_indirect_dev_init(void) +{ + int ret; + + ret = find_kallsyms_lookup_name(); + if (ret < 0) { + INDIRECT_DEV_ERROR("find kallsyms_lookup_name failed\n"); + return -ENXIO; + } + INDIRECT_DEV_DEBUG("find kallsyms_lookup_name ok\n"); + return platform_driver_register(&wb_indirect_dev_driver); +} + +static void __exit wb_indirect_dev_exit(void) +{ + platform_driver_unregister(&wb_indirect_dev_driver); +} + +module_init(wb_indirect_dev_init); +module_exit(wb_indirect_dev_exit); +MODULE_DESCRIPTION("indirect device driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_indirect_dev.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_indirect_dev.h new file mode 100644 index 000000000000..bc2570f52794 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_indirect_dev.h @@ -0,0 +1,54 @@ +/* + * A header definition for wb_indirect_dev driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __WB_INDIRECT_DEV_H__ +#define __WB_INDIRECT_DEV_H__ + +#include + +#define DEV_NAME_LEN (64) +#define WIDTH_1Byte (1) +#define WIDTH_2Byte (2) +#define WIDTH_4Byte (4) +#define MAX_RW_LEN (256) + +#define mem_clear(data, size) memset((data), 0, (size)) + +typedef int (*device_func_write)(const char *, uint32_t, uint8_t *, size_t); +typedef int (*device_func_read)(const char *, uint32_t, uint8_t *, size_t ); + +typedef struct indirect_dev_device_s { + char dev_name[DEV_NAME_LEN]; + char logic_dev_name[DEV_NAME_LEN]; + uint32_t data_bus_width; + uint32_t addr_bus_width; + uint32_t indirect_len; + uint32_t wr_data; + uint32_t wr_data_width; + uint32_t addr_low; + uint32_t addr_high; + uint32_t rd_data; + uint32_t rd_data_width; + uint32_t opt_ctl; + uint32_t logic_func_mode; + int device_flag; +} indirect_dev_device_t; + +#endif /* __WB_INDIRECT_DEV_H__ */ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_io_dev.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_io_dev.c index 03571871014b..6699397aa4b2 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_io_dev.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_io_dev.c @@ -1,7 +1,23 @@ /* - * wb_io_dev.c - * ko to read/write ioports through /dev/XXX device + * An wb_io_dev driver for read/write ioports device function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + #include #include #include @@ -27,8 +43,8 @@ #define IO_INDIRECT_OP_WRITE (0x2) #define IO_INDIRECT_OP_READ (0X3) -#define KERNEL_SPASE (0) -#define USER_SPASE (1) +#define KERNEL_SPACE (0) +#define USER_SPACE (1) static int g_io_dev_debug = 0; static int g_io_dev_error = 0; @@ -54,9 +70,11 @@ typedef struct wb_io_dev_s { uint32_t io_len; uint32_t indirect_addr; uint32_t wr_data; + uint32_t wr_data_width; uint32_t addr_low; uint32_t addr_high; uint32_t rd_data; + uint32_t rd_data_width; uint32_t opt_ctl; spinlock_t io_dev_lock; struct miscdevice misc; @@ -90,14 +108,15 @@ static int io_dev_release(struct inode *inode, struct file *file) return 0; } -uint8_t io_indirect_addressing_read(wb_io_dev_t *wb_io_dev, uint32_t address) +u32 io_indirect_addressing_read(wb_io_dev_t *wb_io_dev, uint32_t address) { - uint8_t addr_l, addr_h, value; + int width; + uint8_t addr_l, addr_h; unsigned long flags; + u32 value; addr_h = IO_INDIRECT_ADDR_H(address); addr_l = IO_INDIRECT_ADDR_L(address); - IO_DEV_DEBUG_VERBOSE("read one count, addr = 0x%x\n", address); spin_lock_irqsave(&wb_io_dev->io_dev_lock, flags); @@ -107,16 +126,32 @@ uint8_t io_indirect_addressing_read(wb_io_dev_t *wb_io_dev, uint32_t address) outb(IO_INDIRECT_OP_READ, wb_io_dev->io_base + wb_io_dev->opt_ctl); - value = inb(wb_io_dev->io_base + wb_io_dev->rd_data); + width = wb_io_dev->rd_data_width; + switch (width) { + case IO_DATA_WIDTH_2: + value = inw(wb_io_dev->io_base + wb_io_dev->rd_data); + break; + case IO_DATA_WIDTH_4: + value = inl(wb_io_dev->io_base + wb_io_dev->rd_data); + break; + case IO_DATA_WIDTH_1: + default: + /* default 1 byte mode */ + value = inb(wb_io_dev->io_base + wb_io_dev->rd_data); + break; + } spin_unlock_irqrestore(&wb_io_dev->io_dev_lock, flags); + IO_DEV_DEBUG_VERBOSE("read one count, addr = 0x%x, value = 0x%x\n", address, value); + return value; } static int io_dev_read_tmp(wb_io_dev_t *wb_io_dev, uint32_t offset, uint8_t *buf, size_t count) { - int i; + int width, i, j; + u32 val; if (offset > wb_io_dev->io_len) { IO_DEV_DEBUG_VERBOSE("offset:0x%x, io len:0x%x, EOF.\n", offset, wb_io_dev->io_len); @@ -129,8 +164,19 @@ static int io_dev_read_tmp(wb_io_dev_t *wb_io_dev, uint32_t offset, uint8_t *buf count = wb_io_dev->io_len - offset; } if (wb_io_dev->indirect_addr) { - for (i = 0; i < count; i++) { - buf[i] = io_indirect_addressing_read(wb_io_dev, offset + i); + width = wb_io_dev->rd_data_width; + + if (offset % width) { + IO_DEV_DEBUG_VERBOSE("rd_data_width:%d, offset:0x%x, size %lu invalid.\n", + width, offset, count); + return -EINVAL; + } + + for (i = 0; i < count; i += width) { + val = io_indirect_addressing_read(wb_io_dev, offset + i); + for (j = 0; (j < width) && (i + j < count); j++) { + buf[i + j] = (val >> (8 * j)) & 0xff; + } } } else { for (i = 0; i < count; i++) { @@ -171,7 +217,7 @@ static ssize_t io_dev_read(struct file *file, char __user *buf, size_t count, lo } /* check flag is user spase or kernel spase */ - if (flag == USER_SPASE) { + if (flag == USER_SPACE) { IO_DEV_DEBUG_VERBOSE("user space read, buf: %p, offset: %lld, read count %lu.\n", buf, *offset, count); if (copy_to_user(buf, buf_tmp, read_len)) { @@ -194,7 +240,7 @@ static ssize_t io_dev_read_user(struct file *file, char __user *buf, size_t coun IO_DEV_DEBUG_VERBOSE("io_dev_read_user, file: %p, count: %lu, offset: %lld\n", file, count, *offset); - ret = io_dev_read(file, buf, count, offset, USER_SPASE); + ret = io_dev_read(file, buf, count, offset, USER_SPACE); return ret; } @@ -204,22 +250,37 @@ static ssize_t io_dev_read_iter(struct kiocb *iocb, struct iov_iter *to) IO_DEV_DEBUG_VERBOSE("io_dev_read_iter, file: %p, count: %lu, offset: %lld\n", iocb->ki_filp, to->count, iocb->ki_pos); - ret = io_dev_read(iocb->ki_filp, to->kvec->iov_base, to->count, &iocb->ki_pos, KERNEL_SPASE); + ret = io_dev_read(iocb->ki_filp, to->kvec->iov_base, to->count, &iocb->ki_pos, KERNEL_SPACE); return ret; } -void io_indirect_addressing_write(wb_io_dev_t *wb_io_dev, uint32_t address, uint8_t reg_val) +void io_indirect_addressing_write(wb_io_dev_t *wb_io_dev, uint32_t address, u32 reg_val) { + int width; uint8_t addr_l, addr_h; unsigned long flags; addr_h = IO_INDIRECT_ADDR_H(address); addr_l = IO_INDIRECT_ADDR_L(address); - IO_DEV_DEBUG_VERBOSE("write one count, addr = 0x%x\n", address); + IO_DEV_DEBUG_VERBOSE("write one count, addr = 0x%x, val = 0x%x\n", address, reg_val); + + width = wb_io_dev->wr_data_width; spin_lock_irqsave(&wb_io_dev->io_dev_lock, flags); - outb(reg_val, wb_io_dev->io_base + wb_io_dev->wr_data); + switch (width) { + case IO_DATA_WIDTH_2: + outw(reg_val, wb_io_dev->io_base + wb_io_dev->wr_data); + break; + case IO_DATA_WIDTH_4: + outl(reg_val, wb_io_dev->io_base + wb_io_dev->wr_data); + break; + case IO_DATA_WIDTH_1: + default: + /* default 1 byte mode */ + outb(reg_val, wb_io_dev->io_base + wb_io_dev->wr_data); + break; + } outb(addr_l, wb_io_dev->io_base + wb_io_dev->addr_low); @@ -234,7 +295,8 @@ void io_indirect_addressing_write(wb_io_dev_t *wb_io_dev, uint32_t address, uint static int io_dev_write_tmp(wb_io_dev_t *wb_io_dev, uint32_t offset, uint8_t *buf, size_t count) { - int i; + int width, i, j; + u32 val; if (offset > wb_io_dev->io_len) { IO_DEV_DEBUG_VERBOSE("offset:0x%x, io len:0x%x, EOF.\n", offset, wb_io_dev->io_len); @@ -247,8 +309,20 @@ static int io_dev_write_tmp(wb_io_dev_t *wb_io_dev, uint32_t offset, uint8_t *bu count = wb_io_dev->io_len - offset; } if (wb_io_dev->indirect_addr) { - for (i = 0; i < count; i++) { - io_indirect_addressing_write(wb_io_dev, offset + i, buf[i]); + width = wb_io_dev->wr_data_width; + + if (offset % width) { + IO_DEV_DEBUG_VERBOSE("wr_data_width:%d, offset:0x%x, size %lu invalid.\n", + width, offset, count); + return -EINVAL; + } + + for (i = 0; i < count; i += width) { + val = 0; + for (j = 0; (j < width) && (i + j < count); j++) { + val |= buf[i + j] << (8 * j); + } + io_indirect_addressing_write(wb_io_dev, i + offset, val); } } else { for (i = 0; i < count; i++) { @@ -283,7 +357,7 @@ static ssize_t io_dev_write(struct file *file, const char __user *buf, size_t co mem_clear(buf_tmp, sizeof(buf_tmp)); /* check flag is user spase or kernel spase */ - if (flag == USER_SPASE) { + if (flag == USER_SPACE) { IO_DEV_DEBUG_VERBOSE("user space write, buf: %p, offset: %lld, write count %lu.\n", buf, *offset, count); if (copy_from_user(buf_tmp, buf, count)) { @@ -312,7 +386,7 @@ static ssize_t io_dev_write_user(struct file *file, const char __user *buf, size IO_DEV_DEBUG_VERBOSE("io_dev_write_user, file: %p, count: %lu, offset: %lld\n", file, count, *offset); - ret = io_dev_write(file, buf, count, offset, USER_SPASE); + ret = io_dev_write(file, buf, count, offset, USER_SPACE); return ret; } @@ -322,7 +396,7 @@ static ssize_t io_dev_write_iter(struct kiocb *iocb, struct iov_iter *from) IO_DEV_DEBUG_VERBOSE("io_dev_write_iter, file: %p, count: %lu, offset: %lld\n", iocb->ki_filp, from->count, iocb->ki_pos); - ret = io_dev_write(iocb->ki_filp, from->kvec->iov_base, from->count, &iocb->ki_pos, KERNEL_SPASE); + ret = io_dev_write(iocb->ki_filp, from->kvec->iov_base, from->count, &iocb->ki_pos, KERNEL_SPACE); return ret; } @@ -455,7 +529,7 @@ int io_device_func_write(const char *path, uint32_t offset, uint8_t *buf, size_t wb_io_dev = dev_match(path); if (wb_io_dev == NULL) { - IO_DEV_DEBUG_ERROR("i2c_dev match failed. dev path = %s", path); + IO_DEV_DEBUG_ERROR("io_dev match failed. dev path = %s", path); return -EINVAL; } @@ -488,15 +562,22 @@ static int io_dev_probe(struct platform_device *pdev) ret += of_property_read_u32(pdev->dev.of_node, "io_base", &wb_io_dev->io_base); ret += of_property_read_u32(pdev->dev.of_node, "io_len", &wb_io_dev->io_len); if (of_property_read_bool(pdev->dev.of_node, "indirect_addr")) { - wb_io_dev->indirect_addr = 1; ret += of_property_read_u32(pdev->dev.of_node, "wr_data", &wb_io_dev->wr_data); ret += of_property_read_u32(pdev->dev.of_node, "addr_low", &wb_io_dev->addr_low); ret += of_property_read_u32(pdev->dev.of_node, "addr_high", &wb_io_dev->addr_high); ret += of_property_read_u32(pdev->dev.of_node, "rd_data", &wb_io_dev->rd_data); ret += of_property_read_u32(pdev->dev.of_node, "opt_ctl", &wb_io_dev->opt_ctl); - } else { + if (of_property_read_u32(pdev->dev.of_node, "wr_data_width", &wb_io_dev->wr_data_width)) { + /* dts have no wr_data_width,set default 1 */ + wb_io_dev->wr_data_width = IO_DATA_WIDTH_1; + } + if (of_property_read_u32(pdev->dev.of_node, "rd_data_width", &wb_io_dev->rd_data_width)) { + /* dts have no rd_data_width,set default 1 */ + wb_io_dev->rd_data_width = IO_DATA_WIDTH_1; + } + } else { wb_io_dev->indirect_addr = 0; } if (ret != 0) { @@ -515,10 +596,18 @@ static int io_dev_probe(struct platform_device *pdev) wb_io_dev->indirect_addr = io_dev_device->indirect_addr; if (wb_io_dev->indirect_addr == 1) { wb_io_dev->wr_data = io_dev_device->wr_data; + wb_io_dev->wr_data_width = io_dev_device->wr_data_width; wb_io_dev->addr_low = io_dev_device->addr_low; wb_io_dev->addr_high = io_dev_device->addr_high; wb_io_dev->rd_data = io_dev_device->rd_data; + wb_io_dev->rd_data_width = io_dev_device->rd_data_width; wb_io_dev->opt_ctl = io_dev_device->opt_ctl; + if (wb_io_dev->wr_data_width == 0) { + wb_io_dev->wr_data_width = IO_DATA_WIDTH_1; + } + if (wb_io_dev->rd_data_width == 0) { + wb_io_dev->rd_data_width = IO_DATA_WIDTH_1; + } } } diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_io_dev.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_io_dev.h index 3a1a10f0f20c..61cba26a155c 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_io_dev.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_io_dev.h @@ -1,3 +1,23 @@ +/* + * A header definition for wb_io_dev driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #ifndef __WB_IO_DEV_H__ #define __WB_IO_DEV_H__ #include @@ -5,15 +25,21 @@ #define mem_clear(data, size) memset((data), 0, (size)) #define IO_DEV_NAME_MAX_LEN (64) +#define IO_DATA_WIDTH_1 (1) +#define IO_DATA_WIDTH_2 (2) +#define IO_DATA_WIDTH_4 (4) + typedef struct io_dev_device_s { char io_dev_name[IO_DEV_NAME_MAX_LEN]; uint32_t io_base; uint32_t io_len; uint32_t indirect_addr; uint32_t wr_data; + uint32_t wr_data_width; uint32_t addr_low; uint32_t addr_high; uint32_t rd_data; + uint32_t rd_data_width; uint32_t opt_ctl; int device_flag; } io_dev_device_t; diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_lpc_drv.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_lpc_drv.c index c079dc409696..45290ca843ea 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_lpc_drv.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_lpc_drv.c @@ -1,7 +1,23 @@ /* - * wb_lpc_drv.c - * ko to set lpc pcie config io addr and enable lpc + * An wb_lpc_drv driver for lpc device function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + #include #include #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_lpc_drv.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_lpc_drv.h index 76e8c32c12e9..52c64b187bd5 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_lpc_drv.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_lpc_drv.h @@ -1,3 +1,23 @@ +/* + * A header definition for wb_lpc_drv driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #ifndef __WB_LPC_DRV_H__ #define __WB_LPC_DRV_H__ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_mac_bsc.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_mac_bsc.c index a94ae020a4b7..ba9cd692f8e8 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_mac_bsc.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_mac_bsc.c @@ -1,6 +1,7 @@ /* + * An wb_mac_bsc driver for mac bsc function * - * Copyright (c) 1998, 1999 Frodo Looijaard + * Copyright (C) 2024 Micas 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_mdio_gpio_device.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_mdio_gpio_device.c index e3198b378a20..65b8d2a42749 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_mdio_gpio_device.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_mdio_gpio_device.c @@ -1,3 +1,23 @@ +/* + * An wb_mdio_gpio_device driver for mdio gpio device function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #include #include #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_pcie_dev.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_pcie_dev.c index 093d070fd429..83904d7960e0 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_pcie_dev.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_pcie_dev.c @@ -1,7 +1,23 @@ /* - * wb_pcie_dev.c - * ko to read/write pcie iomem and ioports through /dev/XXX device + * An wb_pcie_dev driver for pcie device function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + #include #include #include @@ -25,8 +41,14 @@ #define PCIE_BUS_WIDTH_2 (2) #define PCIE_BUS_WIDTH_4 (4) -#define KERNEL_SPASE (0) -#define USER_SPASE (1) +#define KERNEL_SPACE (0) +#define USER_SPACE (1) + +#define SEARCH_DEV_DEFAULT (0) +#define SEARCH_DEV_BY_BRIDGE (1) + +#define SECBUS (0x19) +#define SUBBUS (0x1a) static int g_pcie_dev_debug = 0; static int g_pcie_dev_error = 0; @@ -65,6 +87,10 @@ typedef struct wb_pci_dev_s { uint32_t bus_width; uint32_t check_pci_id; uint32_t pci_id; + uint32_t search_mode; + uint32_t bridge_bus; + uint32_t bridge_slot; + uint32_t bridge_fn; struct miscdevice misc; void (*setreg)(struct wb_pci_dev_s *wb_pci_dev, int reg, u32 value); u32 (*getreg)(struct wb_pci_dev_s *wb_pci_dev, int reg); @@ -250,7 +276,7 @@ static ssize_t pci_dev_read(struct file *file, char __user *buf, size_t count, l return read_len; } /* check flag is user spase or kernel spase */ - if (flag == USER_SPASE) { + if (flag == USER_SPACE) { PCIE_DEV_DEBUG_VERBOSE("user space read, buf: %p, offset: %lld, read count %lu.\n", buf, *offset, count); if (copy_to_user(buf, buf_tmp, read_len)) { @@ -273,7 +299,7 @@ static ssize_t pci_dev_read_user(struct file *file, char __user *buf, size_t cou PCIE_DEV_DEBUG_VERBOSE("pci_dev_read_user, file: %p, count: %lu, offset: %lld\n", file, count, *offset); - ret = pci_dev_read(file, buf, count, offset, USER_SPASE); + ret = pci_dev_read(file, buf, count, offset, USER_SPACE); return ret; } @@ -283,7 +309,7 @@ static ssize_t pci_dev_read_iter(struct kiocb *iocb, struct iov_iter *to) PCIE_DEV_DEBUG_VERBOSE("pci_dev_read_iter, file: %p, count: %lu, offset: %lld\n", iocb->ki_filp, to->count, iocb->ki_pos); - ret = pci_dev_read(iocb->ki_filp, to->kvec->iov_base, to->count, &iocb->ki_pos, KERNEL_SPASE); + ret = pci_dev_read(iocb->ki_filp, to->kvec->iov_base, to->count, &iocb->ki_pos, KERNEL_SPACE); return ret; } @@ -347,7 +373,7 @@ static ssize_t pci_dev_write(struct file *file, const char __user *buf, size_t c mem_clear(buf_tmp, sizeof(buf_tmp)); /* check flag is user spase or kernel spase */ - if (flag == USER_SPASE) { + if (flag == USER_SPACE) { PCIE_DEV_DEBUG_VERBOSE("user space write, buf: %p, offset: %lld, write count %lu.\n", buf, *offset, count); if (copy_from_user(buf_tmp, buf, count)) { @@ -376,7 +402,7 @@ static ssize_t pci_dev_write_user(struct file *file, const char __user *buf, siz PCIE_DEV_DEBUG_VERBOSE("pci_dev_write_user, file: %p, count: %lu, offset: %lld\n", file, count, *offset); - ret = pci_dev_write(file, buf, count, offset, USER_SPASE); + ret = pci_dev_write(file, buf, count, offset, USER_SPACE); return ret; } @@ -386,7 +412,7 @@ static ssize_t pci_dev_write_iter(struct kiocb *iocb, struct iov_iter *from) PCIE_DEV_DEBUG_VERBOSE("pci_dev_write_iter, file: %p, count: %lu, offset: %lld\n", iocb->ki_filp, from->count, iocb->ki_pos); - ret = pci_dev_write(iocb->ki_filp, from->kvec->iov_base, from->count, &iocb->ki_pos, KERNEL_SPASE); + ret = pci_dev_write(iocb->ki_filp, from->kvec->iov_base, from->count, &iocb->ki_pos, KERNEL_SPACE); return ret; } @@ -618,10 +644,11 @@ static int pci_dev_probe(struct platform_device *pdev) int ret, devfn; uint32_t pci_id; wb_pci_dev_t *wb_pci_dev; - struct pci_dev *pci_dev; + struct pci_dev *pci_dev, *pci_bridge_dev; struct miscdevice *misc; firmware_upg_t *firmware_upg; pci_dev_device_t *pci_dev_device; + u8 secbus_val, subbus_val; wb_pci_dev = devm_kzalloc(&pdev->dev, sizeof(wb_pci_dev_t), GFP_KERNEL); if (!wb_pci_dev) { @@ -636,7 +663,6 @@ static int pci_dev_probe(struct platform_device *pdev) ret = 0; ret += of_property_read_string(pdev->dev.of_node, "pci_dev_name", &wb_pci_dev->name); ret += of_property_read_u32(pdev->dev.of_node, "pci_domain", &wb_pci_dev->domain); - ret += of_property_read_u32(pdev->dev.of_node, "pci_bus", &wb_pci_dev->bus); ret += of_property_read_u32(pdev->dev.of_node, "pci_slot", &wb_pci_dev->slot); ret += of_property_read_u32(pdev->dev.of_node, "pci_fn", &wb_pci_dev->fn); ret += of_property_read_u32(pdev->dev.of_node, "pci_bar", &wb_pci_dev->bar); @@ -647,6 +673,30 @@ static int pci_dev_probe(struct platform_device *pdev) return -ENXIO; } + wb_pci_dev->search_mode = SEARCH_DEV_DEFAULT; + of_property_read_u32(pdev->dev.of_node, "search_mode", &wb_pci_dev->search_mode); + ret = 0; + if (wb_pci_dev->search_mode == SEARCH_DEV_BY_BRIDGE) { + ret += of_property_read_u32(pdev->dev.of_node, "bridge_bus", &wb_pci_dev->bridge_bus); + ret += of_property_read_u32(pdev->dev.of_node, "bridge_slot", &wb_pci_dev->bridge_slot); + ret += of_property_read_u32(pdev->dev.of_node, "bridge_fn", &wb_pci_dev->bridge_fn); + if (ret != 0) { + PCIE_DEV_DEBUG_VERBOSE("get pci bridge config fail, ret:%d.\n", ret); + return -ENXIO; + } else { + PCIE_DEV_DEBUG_VERBOSE("bridge_bus:0x%02x, bridge_slot:0x%02x, bridge_fn:0x%02x.\n", + wb_pci_dev->bridge_bus, wb_pci_dev->bridge_slot, wb_pci_dev->bridge_fn); + } + } else { + ret += of_property_read_u32(pdev->dev.of_node, "pci_bus", &wb_pci_dev->bus); + if (ret != 0) { + PCIE_DEV_DEBUG_VERBOSE("get pci bus config fail, ret:%d.\n", ret); + return -ENXIO; + } else { + PCIE_DEV_DEBUG_VERBOSE("get pci_bus:0x%02x.\n", wb_pci_dev->bus); + } + } + ret = 0; ret += of_property_read_u32(pdev->dev.of_node, "upg_ctrl_base", &firmware_upg->upg_ctrl_base); ret += of_property_read_u32(pdev->dev.of_node, "upg_flash_base", &firmware_upg->upg_flash_base); @@ -674,31 +724,79 @@ static int pci_dev_probe(struct platform_device *pdev) pci_dev_device = pdev->dev.platform_data; wb_pci_dev->name = pci_dev_device->pci_dev_name; wb_pci_dev->domain = pci_dev_device->pci_domain; - wb_pci_dev->bus = pci_dev_device->pci_bus; wb_pci_dev->slot = pci_dev_device->pci_slot; wb_pci_dev->fn = pci_dev_device->pci_fn; wb_pci_dev->bar = pci_dev_device->pci_bar; wb_pci_dev->bus_width = pci_dev_device->bus_width; wb_pci_dev->check_pci_id = pci_dev_device->check_pci_id; - wb_pci_dev->pci_id = pci_dev_device->pci_id; + wb_pci_dev->search_mode = pci_dev_device->search_mode; firmware_upg->upg_ctrl_base = pci_dev_device->upg_ctrl_base; firmware_upg->upg_flash_base = pci_dev_device->upg_flash_base; + if (wb_pci_dev->search_mode == SEARCH_DEV_BY_BRIDGE) { + PCIE_DEV_DEBUG_VERBOSE("bridge_bus:0x%02x, bridge_slot:0x%02x, bridge_fn:0x%02x.\n", + wb_pci_dev->bridge_bus, wb_pci_dev->bridge_slot, wb_pci_dev->bridge_fn); + } PCIE_DEV_DEBUG_VERBOSE("upg_ctrl_base:0x%04x, upg_flash_base:0x%02x.\n", firmware_upg->upg_ctrl_base, firmware_upg->upg_flash_base); } - PCIE_DEV_DEBUG_VERBOSE("name:%s, domain:0x%04x, bus:0x%02x, slot:0x%02x, fn:%u, bar:%u, bus_width:%d.\n", + PCIE_DEV_DEBUG_VERBOSE("name:%s, domain:0x%04x, bus:0x%02x, slot:0x%02x, fn:%u, bar:%u, bus_width:%d, search_mode:%d \n", wb_pci_dev->name, wb_pci_dev->domain, wb_pci_dev->bus, wb_pci_dev->slot, wb_pci_dev->fn, - wb_pci_dev->bar, wb_pci_dev->bus_width); + wb_pci_dev->bar, wb_pci_dev->bus_width, wb_pci_dev->search_mode); - devfn = PCI_DEVFN(wb_pci_dev->slot, wb_pci_dev->fn); - pci_dev = pci_get_domain_bus_and_slot(wb_pci_dev->domain, wb_pci_dev->bus, devfn); - if (pci_dev == NULL) { - dev_err(&pdev->dev, "Failed to find pci_dev, domain:0x%04x, bus:0x%02x, devfn:0x%x\n", - wb_pci_dev->domain, wb_pci_dev->bus, devfn); - return -ENXIO; + if (wb_pci_dev->search_mode != SEARCH_DEV_DEFAULT && wb_pci_dev->search_mode != SEARCH_DEV_BY_BRIDGE) { + dev_err(&pdev->dev, "Error: unsupported search_mode (%d).\n", wb_pci_dev->search_mode); + return -EINVAL; + } + + if (wb_pci_dev->search_mode == SEARCH_DEV_DEFAULT) { + wb_pci_dev->bus = pci_dev_device->pci_bus; + devfn = PCI_DEVFN(wb_pci_dev->slot, wb_pci_dev->fn); + pci_dev = pci_get_domain_bus_and_slot(wb_pci_dev->domain, wb_pci_dev->bus, devfn); + if (pci_dev == NULL) { + dev_err(&pdev->dev, "Failed to find pci_dev, domain:0x%04x, bus:0x%02x, devfn:0x%x\n", + wb_pci_dev->domain, wb_pci_dev->bus, devfn); + return -ENXIO; + } + } else { /* search_mode = SEARCH_DEV_BY_BRIDGE */ + wb_pci_dev->bridge_bus = pci_dev_device->bridge_bus; + wb_pci_dev->bridge_slot = pci_dev_device->bridge_slot; + wb_pci_dev->bridge_fn = pci_dev_device->bridge_fn; + devfn = PCI_DEVFN(wb_pci_dev->bridge_slot, wb_pci_dev->bridge_fn); + pci_bridge_dev = pci_get_domain_bus_and_slot(wb_pci_dev->domain, wb_pci_dev->bridge_bus, devfn); + if (pci_bridge_dev == NULL) { + dev_err(&pdev->dev, "Failed to find pci_bridge_dev, domain:0x%04x, bus:0x%02x, devfn:0x%x\n", + wb_pci_dev->domain, wb_pci_dev->bridge_bus, devfn); + return -ENXIO; + } + + ret = pci_read_config_byte(pci_bridge_dev, SECBUS, &secbus_val); + if (ret) { + PCIE_DEV_DEBUG_ERROR("pci_read_config_dword failed reg:%02x ret %d.\n", SECBUS, ret); + return -EIO; + } + ret = pci_read_config_byte(pci_bridge_dev, SUBBUS, &subbus_val); + if (ret) { + PCIE_DEV_DEBUG_ERROR("pci_read_config_dword failed reg:%02x ret %d.\n", SUBBUS, ret); + return -EIO; + } + if (secbus_val != subbus_val) { + /* If the SECBUS register value is different from the SUBBUS register value, a multistage PCIE bridge is available*/ + PCIE_DEV_DEBUG_ERROR("not support ,secbus_val not equal subbus_val secbus_val:%02x secbus_val:%02x.\n", secbus_val, subbus_val); + return -EIO; + } + wb_pci_dev->bus = secbus_val; + devfn = PCI_DEVFN(wb_pci_dev->slot, wb_pci_dev->fn); + pci_dev = pci_get_domain_bus_and_slot(wb_pci_dev->domain, wb_pci_dev->bus, devfn); + if (pci_dev == NULL) { + dev_err(&pdev->dev, "Failed to find pci_dev, domain:0x%04x, bus:0x%02x, devfn:0x%x\n", + wb_pci_dev->domain, wb_pci_dev->bus, devfn); + return -ENXIO; + } } + if (wb_pci_dev->check_pci_id == 1) { + wb_pci_dev->pci_id = pci_dev_device->pci_id; pci_id = (pci_dev->vendor << 16) | pci_dev->device; if (wb_pci_dev->pci_id != pci_id) { dev_err(&pdev->dev, "Failed to check pci id, except: 0x%x, really: 0x%x\n", diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_pcie_dev.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_pcie_dev.h index 33da8d475f91..ef390a1585f3 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_pcie_dev.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_pcie_dev.h @@ -1,3 +1,23 @@ +/* + * A header definition for wb_pcie_dev driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #ifndef __WB_PCIE_DEV_H__ #define __WB_PCIE_DEV_H__ #include @@ -23,6 +43,10 @@ typedef struct pci_dev_device_s { int upg_ctrl_base; int upg_flash_base; int device_flag; + int search_mode; + int bridge_bus; + int bridge_slot; + int bridge_fn; } pci_dev_device_t; #endif diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_platform_i2c_dev.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_platform_i2c_dev.c index 092c99da2ad8..678a48483bd7 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_platform_i2c_dev.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_platform_i2c_dev.c @@ -1,3 +1,23 @@ +/* + * An wb_platform_i2c_dev driver for i2c platform device function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #include #include #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_platform_i2c_dev.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_platform_i2c_dev.h index b5158c9fec57..f40282176484 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_platform_i2c_dev.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_platform_i2c_dev.h @@ -1,3 +1,23 @@ +/* + * A header definition for wb_platform_i2c_dev driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #ifndef __WB_PLATFORM_I2C_DEV_H__ #define __WB_PLATFORM_I2C_DEV_H__ #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_dev.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_dev.c index d70424afb0e7..dd13fe9a991b 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_dev.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_dev.c @@ -1,6 +1,21 @@ /* - * wb_spi_dev.c - * ko to read/write spi device through /dev/XXX device + * An wb_spi_dev driver for spi device function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include @@ -32,8 +47,8 @@ #define OP_READ (0x3) #define OP_WRITE (0x2) -#define KERNEL_SPASE (0) -#define USER_SPASE (1) +#define KERNEL_SPACE (0) +#define USER_SPACE (1) static int g_spi_dev_debug = 0; static int g_spi_dev_error = 0; @@ -346,7 +361,7 @@ static ssize_t spi_dev_read(struct file *file, char __user *buf, size_t count, l } /* check flag is user spase or kernel spase */ - if (flag == USER_SPASE) { + if (flag == USER_SPACE) { SPI_DEV_DEBUG("user space read, buf: %p, offset: %lld, read count %lu.\n", buf, *offset, count); if (copy_to_user(buf, val, read_len)) { @@ -370,7 +385,7 @@ static ssize_t spi_dev_read_user(struct file *file, char __user *buf, size_t cou SPI_DEV_DEBUG("spi_dev_read_user, file: %p, count: %lu, offset: %lld\n", file, count, *offset); - ret = spi_dev_read(file, buf, count, offset, USER_SPASE); + ret = spi_dev_read(file, buf, count, offset, USER_SPACE); return ret; } @@ -380,7 +395,7 @@ static ssize_t spi_dev_read_iter(struct kiocb *iocb, struct iov_iter *to) SPI_DEV_DEBUG("spi_dev_read_iter, file: %p, count: %lu, offset: %lld\n", iocb->ki_filp, to->count, iocb->ki_pos); - ret = spi_dev_read(iocb->ki_filp, to->kvec->iov_base, to->count, &iocb->ki_pos, KERNEL_SPASE); + ret = spi_dev_read(iocb->ki_filp, to->kvec->iov_base, to->count, &iocb->ki_pos, KERNEL_SPACE); return ret; } @@ -409,7 +424,7 @@ static ssize_t spi_dev_write(struct file *file, const char __user *buf, mem_clear(val, sizeof(val)); /* check flag is user spase or kernel spase */ - if (flag == USER_SPASE) { + if (flag == USER_SPACE) { SPI_DEV_DEBUG("user space write, buf: %p, offset: %lld, write count %lu.\n", buf, *offset, count); if (copy_from_user(val, buf, count)) { @@ -439,7 +454,7 @@ static ssize_t spi_dev_write_user(struct file *file, const char __user *buf, siz SPI_DEV_DEBUG("spi_dev_write_user, file: %p, count: %lu, offset: %lld\n", file, count, *offset); - ret = spi_dev_write(file, buf, count, offset, USER_SPASE); + ret = spi_dev_write(file, buf, count, offset, USER_SPACE); return ret; } @@ -449,7 +464,7 @@ static ssize_t spi_dev_write_iter(struct kiocb *iocb, struct iov_iter *from) SPI_DEV_DEBUG("spi_dev_write_iter, file: %p, count: %lu, offset: %lld\n", iocb->ki_filp, from->count, iocb->ki_pos); - ret = spi_dev_write(iocb->ki_filp, from->kvec->iov_base, from->count, &iocb->ki_pos, KERNEL_SPASE); + ret = spi_dev_write(iocb->ki_filp, from->kvec->iov_base, from->count, &iocb->ki_pos, KERNEL_SPACE); return ret; } diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_dev.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_dev.h index fed5237e3860..03ff8f42f7ec 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_dev.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_dev.h @@ -1,3 +1,23 @@ +/* + * A header definition for wb_spi_dev driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #ifndef __WB_SPI_DEV_H__ #define __WB_SPI_DEV_H__ #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_gpio_device.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_gpio_device.c index b073dac08a8a..61551a33d3c1 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_gpio_device.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_gpio_device.c @@ -1,3 +1,23 @@ +/* + * An wb_spi_gpio_device driver for spi gpio device function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #include #include #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_ocores.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_ocores.c index 5cf3538d88fa..f87dd63ecae4 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_ocores.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_ocores.c @@ -1,6 +1,21 @@ /* - * wb_spi_ocores.c - * ko to create ocores spi adapter + * An wb_spi_ocores driver for spi ocores adapter device function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include @@ -109,6 +124,7 @@ struct spioc { uint32_t num_chipselect; uint32_t freq; uint32_t big_endian; + uint32_t irq_flag; struct device *dev; int transfer_busy_flag; }; @@ -870,6 +886,11 @@ static int ocores_spi_config_init(struct spioc *spioc) ret = -ENXIO; return ret; } + ret = of_property_read_u32(dev->of_node, "irq_flag", &spioc->irq_flag); + if (ret != 0) { + spioc->irq_flag = 0; + ret = 0; + } } else { if (spioc->dev->platform_data == NULL) { SPI_OC_ERROR("platform data config error.\n"); @@ -886,12 +907,13 @@ static int ocores_spi_config_init(struct spioc *spioc) spioc->freq = spi_ocores_device->clock_frequency; spioc->reg_access_mode = spi_ocores_device->reg_access_mode; spioc->num_chipselect = spi_ocores_device->num_chipselect; + spioc->irq_flag = spi_ocores_device->irq_flag; } SPI_OC_VERBOSE("name:%s, base:0x%x, reg_shift:0x%x, io_width:0x%x, clock-frequency:0x%x.\n", spioc->dev_name, spioc->base_addr, spioc->reg_shift, spioc->reg_io_width, spioc->freq); - SPI_OC_VERBOSE("reg access mode:%u, num_chipselect:%u.\n", - spioc->reg_access_mode, spioc->num_chipselect); + SPI_OC_VERBOSE("reg access mode:%u, num_chipselect:%u, irq_flag: %u\n", + spioc->reg_access_mode, spioc->num_chipselect, spioc->irq_flag); return ret; } @@ -921,7 +943,6 @@ static int spioc_probe(struct platform_device *pdev) if (spioc->dev->of_node) { if (of_property_read_u32(spioc->dev->of_node, "big_endian", &spioc->big_endian)) { - be = 0; } else { be = spioc->big_endian; @@ -974,17 +995,24 @@ static int spioc_probe(struct platform_device *pdev) spioc->bitbang.chipselect = spioc_chipselect; spioc->bitbang.txrx_bufs = spioc_spi_txrx_bufs; - /* gooooohi need revision */ - spioc->irq = platform_get_irq(pdev, 0); - if (spioc->irq >= 0) { - SPI_OC_VERBOSE("spi oc use irq, irq number:%d.\n", spioc->irq); - init_completion(&spioc->done); - ret = devm_request_irq(&pdev->dev, spioc->irq, spioc_spi_irq, 0, - pdev->name, spioc); - if (ret) { - dev_err(spioc->dev, "Failed to request irq:%d.\n", spioc->irq); + if (spioc->irq_flag == 1) { + spioc->irq = platform_get_irq(pdev, 0); + if (spioc->irq >= 0) { + SPI_OC_VERBOSE("spi oc use irq, irq number:%d.\n", spioc->irq); + init_completion(&spioc->done); + ret = devm_request_irq(&pdev->dev, spioc->irq, spioc_spi_irq, 0, + pdev->name, spioc); + if (ret) { + dev_err(spioc->dev, "Failed to request irq:%d.\n", spioc->irq); + goto free; + } + } else { + ret = spioc->irq; + dev_err(spioc->dev, "Failed to get irq, ret: %d.\n", ret); goto free; } + } else { + spioc->irq = -1; } ret = spi_bitbang_start(&spioc->bitbang); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_ocores.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_ocores.h index 647ff0c5f9cf..e94a770552ec 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_ocores.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_spi_ocores.h @@ -1,3 +1,23 @@ +/* + * A header definition for wb_spi_ocores driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #ifndef __WB_SPI_OCORES_H__ #define __WB_SPI_OCORES_H__ #include @@ -15,6 +35,7 @@ typedef struct spi_ocores_device_s { uint32_t reg_io_width; uint32_t clock_frequency; uint32_t num_chipselect; + uint32_t irq_flag; int device_flag; } spi_ocores_device_t; diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_ucd9081.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_ucd9081.c new file mode 100644 index 000000000000..2fae45c72ae6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_ucd9081.c @@ -0,0 +1,356 @@ +/* + * An wb_ucd9081 driver for ucd9081 adapter device function + * + * Copyright (C) 2024 Micas 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, 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 WB_UCD9081_RAIL1H (0x00) /* Channel 1 voltage address, high 8 bits */ +#define WB_UCD9081_RAIL1L (0x01) /* Channel 1 voltage address, low 8 bits */ +#define WB_UCD9081_RAIL2H (0x02) /* Channel 2 voltage address, high 8 bits */ +#define WB_UCD9081_RAIL2L (0x03) /* Channel 2 voltage address, low 8 bits */ +#define WB_UCD9081_RAIL3H (0x04) /* Channel 3 voltage address, high 8 bits */ +#define WB_UCD9081_RAIL3L (0x05) /* Channel 3 voltage address, low 8 bits */ +#define WB_UCD9081_RAIL4H (0x06) /* Channel 4 voltage address, high 8 bits */ +#define WB_UCD9081_RAIL4L (0x07) /* Channel 4 voltage address, low 8 bits */ +#define WB_UCD9081_RAIL5H (0x08) /* Channel 5 voltage address, high 8 bits */ +#define WB_UCD9081_RAIL5L (0x09) /* Channel 5 voltage address, low 8 bits */ +#define WB_UCD9081_RAIL6H (0x0a) /* Channel 6 voltage address, high 8 bits */ +#define WB_UCD9081_RAIL6L (0x0b) /* Channel 6 voltage address, low 8 bits */ +#define WB_UCD9081_RAIL7H (0x0c) /* Channel 7 voltage address, high 8 bits */ +#define WB_UCD9081_RAIL7L (0x0d) /* Channel 7 voltage address, low 8 bits */ +#define WB_UCD9081_WADDR1 (0x30) /* UCD9081 High address register write address, low 8 bits */ +#define WB_UCD9081_WADDR2 (0x31) /* UCD9081 High address register write address, low 8 bits */ +#define WB_UCD9081_WDATA1 (0x32) /* Write WADDR data,low 8 bits */ +#define WB_UCD9081_WDATA2 (0x33) /* Write WADDR data,low 8 bits */ + +#define WB_UCD9081_FLASHLOCK_REG (0x2E) +#define WB_UCD9081_FLASHUNLOCK_VAL (0x02) +#define WB_UCD9081_FLASHLOCK_VAL (0x0) + +#define WB_UCD9081_FLASHLOCK_REFERENCESELECT_REG_H (0xE1) +#define WB_UCD9081_FLASHLOCK_REFERENCESELECT_REG_L (0x86) + +/* Voltage definition */ +#define WB_UCD9081_SELREF_OFFSET (13) +#define WB_UCD9081_SELREF_0 (0x0) /* External reference selected (VCC 3.3V) */ +#define WB_UCD9081_SELREF_1 (0x1) /* Internal reference selected (VCC 2.5V) */ +#define WB_UCD9081_VREF_EXTERNAL (3300) /* 3.3V */ +#define WB_UCD9081_VREF_INTERNAL (2500) /* 2.5V */ +#define WB_UCD9081_VOLTAGE_MASK (0x3ff) +#define WB_UCD9081_VOLTAGE_DIVIDE (1024) + +#define WB_I2C_RETRY_TIME (10) +#define WB_I2C_RETRY_SLEEP_TIME (10000) /* 10ms */ + +static int g_wb_ucd9081_debug = 0; +static int g_wb_ucd9081_error = 0; + +module_param(g_wb_ucd9081_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_ucd9081_error, int, S_IRUGO | S_IWUSR); + +#define WB_UCD9081_VERBOSE(fmt, args...) do { \ + if (g_wb_ucd9081_debug) { \ + printk(KERN_INFO "[WB_UCD9081][VER][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_UCD9081_ERROR(fmt, args...) do { \ + if (g_wb_ucd9081_error) { \ + printk(KERN_ERR "[WB_UCD9081][ERR][func:%s line:%d]\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +struct ucd9081_data { + struct i2c_client *client; + struct device *hwmon_dev; + struct mutex update_lock; + u32 vref; /* Voltage unit */ +}; + +static s32 wb_i2c_smbus_write_byte_data(const struct i2c_client *client, u8 command, u8 value) +{ + int i; + s32 ret; + + for (i = 0; i < WB_I2C_RETRY_TIME; i++) { + ret = i2c_smbus_write_byte_data(client, command, value); + if (ret >= 0) { + return ret; + } + usleep_range(WB_I2C_RETRY_SLEEP_TIME, WB_I2C_RETRY_SLEEP_TIME + 1); + } + return ret; +} + +static s32 wb_i2c_smbus_read_word_data(const struct i2c_client *client, u8 command) +{ + int i; + s32 ret; + + for (i = 0; i < WB_I2C_RETRY_TIME; i++) { + ret = i2c_smbus_read_word_data(client, command); + if (ret >= 0) { + return ret; + } + usleep_range(WB_I2C_RETRY_SLEEP_TIME, WB_I2C_RETRY_SLEEP_TIME + 1); + } + return ret; +} + +static s32 wb_i2c_smbus_write_word_data(const struct i2c_client *client, u8 command, + u16 value) +{ + int i; + s32 ret; + + for (i = 0; i < WB_I2C_RETRY_TIME; i++) { + ret = i2c_smbus_write_word_data(client, command, value); + if (ret >= 0) { + return ret; + } + usleep_range(WB_I2C_RETRY_SLEEP_TIME, WB_I2C_RETRY_SLEEP_TIME + 1); + } + return ret; +} + +/* Get 9081 voltage units */ +static int ucd9081_get_vref(struct i2c_client *client) +{ + int ret; + uint16_t wr_val; + uint16_t ori_addr; + uint16_t reference_select_val; + struct ucd9081_data *data; + + data = i2c_get_clientdata(client); + WB_UCD9081_VERBOSE("%d-%04x: enter ucd9081_get_vref\n", client->adapter->nr, + client->addr); + + mutex_lock(&data->update_lock); + /* 0.Backup original WADDR */ + ori_addr = wb_i2c_smbus_read_word_data(client, WB_UCD9081_WADDR1); + if (ori_addr < 0) { + WB_UCD9081_ERROR("%d-%04x: read ucd9081 origin addr failed, ret: %d\n", client->adapter->nr, + client->addr, ori_addr); + ret = ori_addr; + goto error; + } + WB_UCD9081_VERBOSE("%d-%04x: save ucd9081 waddr success, ori_addr: 0x%x\n", + client->adapter->nr, client->addr, ori_addr); + + /* 1.Unlock */ + ret = wb_i2c_smbus_write_byte_data(client, WB_UCD9081_FLASHLOCK_REG, WB_UCD9081_FLASHUNLOCK_VAL); + if (ret) { + WB_UCD9081_ERROR("%d-%04x: ucd9081 unlock failed\n", client->adapter->nr, + client->addr); + goto error; + } + + /* 2. Write Voltage configuration flash register address 0xE186 address to WADDR */ + wr_val = (WB_UCD9081_FLASHLOCK_REFERENCESELECT_REG_H << 8) | WB_UCD9081_FLASHLOCK_REFERENCESELECT_REG_L; + ret = wb_i2c_smbus_write_word_data(client, WB_UCD9081_WADDR1, wr_val); + if (ret) { + WB_UCD9081_ERROR("%d-%04x: write ucd9081 waddr failed\n", client->adapter->nr, + client->addr); + goto error; + } + + /* 3. The voltage configuration flash register value is read through WDATA*/ + reference_select_val = wb_i2c_smbus_read_word_data(client, WB_UCD9081_WDATA1); + if (reference_select_val < 0) { + WB_UCD9081_ERROR("%d-%04x: read ucd9081 wdata failed, ret: %d\n", client->adapter->nr, + client->addr, ret); + ret = reference_select_val; + goto error; + } + + /* 4.LOCK */ + ret = wb_i2c_smbus_write_byte_data(client, WB_UCD9081_FLASHLOCK_REG, WB_UCD9081_FLASHLOCK_VAL); + if (ret) { + WB_UCD9081_ERROR("%d-%04x: ucd9081 flash lock failed\n", client->adapter->nr, + client->addr); + goto error; + } + + /* 5.Restore the original WADDR address */ + ret = wb_i2c_smbus_write_word_data(client, WB_UCD9081_WADDR1, ori_addr); + if (ret) { + WB_UCD9081_ERROR("%d-%04x: recover ucd9081 waddr failed\n", client->adapter->nr, + client->addr); + goto error; + } + + /* 5.Calculated voltage unit*/ + WB_UCD9081_VERBOSE("%d-%04x: ucd9081 reference_select_val: 0x%x\n", + client->adapter->nr, client->addr, reference_select_val); + if ((reference_select_val >> WB_UCD9081_SELREF_OFFSET) == WB_UCD9081_SELREF_0) { + data->vref = WB_UCD9081_VREF_EXTERNAL; + } else { + data->vref = WB_UCD9081_VREF_INTERNAL; + } + + mutex_unlock(&data->update_lock); + WB_UCD9081_VERBOSE("%d-%04x: ucd9081 use vref: %d\n", + client->adapter->nr, client->addr, data->vref); + return 0; + +error: + mutex_unlock(&data->update_lock); + return ret; +} + +static ssize_t ucd9081_voltage_show(struct device *dev, struct device_attribute *da, char *buf) +{ + int ret; + struct ucd9081_data *data; + struct i2c_client *client; + uint32_t index, channel, value; + long voltage; + + data = dev_get_drvdata(dev); + client = data->client; + index = to_sensor_dev_attr_2(da)->index; + channel = to_sensor_dev_attr_2(da)->nr; + ret = 0; + + mutex_lock(&data->update_lock); + value = wb_i2c_smbus_read_word_data(client, index); + if (value < 0) { + WB_UCD9081_ERROR("%d-%04x: read ucd9081 channel%d voltage reg failed, reg: 0x%x ret: %d\n", client->adapter->nr, + client->addr, channel, index, ret); + ret = value; + goto error; + } + /* Terminal conversion */ + value = ((value & 0xff00) >> 8) | ((value & 0xff) << 8); + WB_UCD9081_VERBOSE("%d-%04x: read ucd9081 channel%d voltage success, reg: 0x%x, value: 0x%x\n", + client->adapter->nr, client->addr, channel, index, value); + + voltage = ((value & WB_UCD9081_VOLTAGE_MASK) * data->vref) / WB_UCD9081_VOLTAGE_DIVIDE; + WB_UCD9081_VERBOSE("%d-%04x: ucd9081 channel%d voltage: %ld\n", client->adapter->nr, client->addr, channel, voltage); + mutex_unlock(&data->update_lock); + return snprintf(buf, PAGE_SIZE, "%ld\n", voltage); +error: + mutex_unlock(&data->update_lock); + return ret; +} + +static SENSOR_DEVICE_ATTR_2(in1_input, S_IRUGO, ucd9081_voltage_show, NULL, 1, WB_UCD9081_RAIL1H); +static SENSOR_DEVICE_ATTR_2(in2_input, S_IRUGO, ucd9081_voltage_show, NULL, 2, WB_UCD9081_RAIL2H); +static SENSOR_DEVICE_ATTR_2(in3_input, S_IRUGO, ucd9081_voltage_show, NULL, 3, WB_UCD9081_RAIL3H); +static SENSOR_DEVICE_ATTR_2(in4_input, S_IRUGO, ucd9081_voltage_show, NULL, 4, WB_UCD9081_RAIL4H); +static SENSOR_DEVICE_ATTR_2(in5_input, S_IRUGO, ucd9081_voltage_show, NULL, 5, WB_UCD9081_RAIL5H); +static SENSOR_DEVICE_ATTR_2(in6_input, S_IRUGO, ucd9081_voltage_show, NULL, 6, WB_UCD9081_RAIL6H); +static SENSOR_DEVICE_ATTR_2(in7_input, S_IRUGO, ucd9081_voltage_show, NULL, 7, WB_UCD9081_RAIL7H); + +static struct attribute *ucd9081_hwmon_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, + NULL +}; +ATTRIBUTE_GROUPS(ucd9081_hwmon); + +static int ucd9081_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + int ret; + struct ucd9081_data *data; + + WB_UCD9081_VERBOSE("bus: %d, addr: 0x%02x do probe.\n", client->adapter->nr, client->addr); + data = devm_kzalloc(&client->dev, sizeof(struct ucd9081_data), GFP_KERNEL); + if (!data) { + dev_err(&client->dev, "devm_kzalloc failed.\n"); + return -ENOMEM; + } + + data->client = client; + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + + ret = ucd9081_get_vref(client); + if (ret != 0) { + dev_err(&client->dev, "get ucd9081 vref failed, ret: %d\n", ret); + return ret; + } + + data->hwmon_dev = hwmon_device_register_with_groups(&client->dev, client->name, data, ucd9081_hwmon_groups); + if (IS_ERR(data->hwmon_dev)) { + ret = PTR_ERR(data->hwmon_dev); + dev_err(&client->dev, "Failed to register ucd9081 hwmon device, ret: %d\n", ret); + return ret; + } + dev_info(&client->dev, "ucd9081 (addr:0x%x, nr:%d) probe success\n", client->addr, client->adapter->nr); + return 0; +} + +static void ucd9081_remove(struct i2c_client *client) +{ + struct ucd9081_data *data; + + data = i2c_get_clientdata(client); + dev_info(&client->dev, "ucd9081 do remove\n"); + + hwmon_device_unregister(data->hwmon_dev); + return; +} + +static const struct i2c_device_id ucd9081_id[] = { + {"wb_ucd9081", 0}, + {} +}; +MODULE_DEVICE_TABLE(i2c, ucd9081_id); + +static const struct of_device_id ucd9081_dev_of_match[] = { + { .compatible = "ti,wb_ucd9081" }, + { }, +}; +MODULE_DEVICE_TABLE(of, ucd9081_dev_of_match); + +static struct i2c_driver ucd9081_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "wb_ucd9081", + .of_match_table = ucd9081_dev_of_match, + }, + .probe = ucd9081_probe, + .remove = ucd9081_remove, + .id_table = ucd9081_id, +}; + +module_i2c_driver(ucd9081_driver); + +MODULE_AUTHOR("support"); +MODULE_DESCRIPTION("ucd9081 Driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_uio_irq.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_uio_irq.c index da2b582443b8..835386127fb0 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_uio_irq.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_uio_irq.c @@ -1,3 +1,23 @@ +/* + * An wb_uio_irq driver for uio irq device function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #include #include #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_wdt.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_wdt.c index aa50ef848dde..899886a0390b 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_wdt.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_wdt.c @@ -1,6 +1,21 @@ /* - * wb_wdt.c - * ko for watchdog function + * An wb_wdt driver for watchdog device function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include @@ -69,8 +84,8 @@ enum { enum { WATCHDOG_DEVICE_TYPE = 0, - HRTIMER_TYPE, - THREAD_TYPE, + HRTIMER_TYPE = 1, + THREAD_TYPE = 2, }; typedef struct wb_wdt_priv_s { @@ -427,8 +442,8 @@ static int wdt_thread_timer(void *data) wb_wdt_priv_t *priv = data; while (!kthread_should_stop()) { - schedule_timeout_uninterruptible(msecs_to_jiffies(priv->feed_time)); wdt_hwping(priv); + schedule_timeout_uninterruptible(msecs_to_jiffies(priv->feed_time)); } return 0; } @@ -673,6 +688,32 @@ static const struct watchdog_ops wb_wdt_ops = { .get_timeleft = wb_wdt_get_timeleft, }; +static int wb_wdt_register_device(wb_wdt_priv_t *priv) +{ + int ret; + + watchdog_set_drvdata(&priv->wdd, priv); + + priv->wdd.info = &wb_wdt_ident; + priv->wdd.ops = &wb_wdt_ops; + priv->wdd.bootstatus = 0; + priv->wdd.timeout = priv->hw_margin / MS_TO_S; + priv->wdd.min_timeout = priv->timer_accuracy / MS_TO_S; + priv->wdd.max_timeout = priv->timer_accuracy * MAX_REG_VAL / MS_TO_S; + priv->wdd.parent = priv->dev; + + watchdog_stop_on_reboot(&priv->wdd); + + ret = devm_watchdog_register_device(priv->dev, &priv->wdd); + if (ret != 0) { + dev_err(priv->dev, "cannot register watchdog device (err=%d)\n", ret); + return -ENXIO; + } + + return 0; +} + + static int watchdog_device_cfg(wb_wdt_priv_t *priv) { int ret; @@ -712,24 +753,6 @@ static int watchdog_device_cfg(wb_wdt_priv_t *priv) } } - watchdog_set_drvdata(&priv->wdd, priv); - - priv->wdd.info = &wb_wdt_ident; - priv->wdd.ops = &wb_wdt_ops; - priv->wdd.bootstatus = 0; - priv->wdd.timeout = priv->hw_margin / MS_TO_S; - priv->wdd.min_timeout = priv->timer_accuracy / MS_TO_S; - priv->wdd.max_timeout = priv->timer_accuracy * MAX_REG_VAL / MS_TO_S; - priv->wdd.parent = priv->dev; - - watchdog_stop_on_reboot(&priv->wdd); - - ret = devm_watchdog_register_device(priv->dev, &priv->wdd); - if (ret != 0) { - dev_err(priv->dev, "cannot register watchdog device (err=%d)\n", ret); - return -ENXIO; - } - return 0; } @@ -1085,6 +1108,12 @@ static int wb_wdt_probe(struct platform_device *pdev) dev_info(&pdev->dev, "register %s mode, config_mode %u, func_mode %u, %u ms overtime wdt success\n", algo, priv->config_mode, priv->priv_func_mode, priv->hw_margin); + ret = wb_wdt_register_device(priv); + if (ret < 0) { + dev_err(&pdev->dev, "kernel watchdog sysfs register %u failed.\n", ret); + return -ENODEV; + } + if (priv->sysfs_index != SYSFS_NO_CFG) { priv->sysfs_group = wdt_get_attr_group(priv->sysfs_index); diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_wdt.h b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_wdt.h index d45904ba32ea..431464688878 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_wdt.h +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_wdt.h @@ -1,3 +1,23 @@ +/* + * A header definition for wb_wdt driver + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #ifndef __WB_WDT_H__ #define __WB_WDT_H__ diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_xdpe132g5c.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_xdpe132g5c.c index 51c5b4143df8..3d2b2ff0bab6 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_xdpe132g5c.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_xdpe132g5c.c @@ -1,12 +1,21 @@ /* - * xdpe132g5c_i2c_drv.c + * An wb_xdpe132g5c driver for xdpe132g5c avs and hwmon device function * - * This module create sysfs to set AVS and create hwmon to get out power - * through xdpe132g5c I2C address. + * Copyright (C) 2024 Micas Networks Inc. * - * History - * [Version] [Date] [Description] - * * v1.0 2021-09-17 Initial version + * 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 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_xdpe132g5c_pmbus.c b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_xdpe132g5c_pmbus.c index d1e0fa220725..493f477a1688 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_xdpe132g5c_pmbus.c +++ b/platform/broadcom/sonic-platform-modules-micas/common/modules/wb_xdpe132g5c_pmbus.c @@ -1,3 +1,23 @@ +/* + * An wb_xdpe132g5c_pmbus driver for xdpe132g5c pmbus device function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #include #include #include diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/auto_update.py b/platform/broadcom/sonic-platform-modules-micas/common/script/auto_update.py index 838e64f6b417..e1a781420176 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/auto_update.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/auto_update.py @@ -1,4 +1,19 @@ #!/usr/bin/env python3 +# +# Copyright (C) 2024 Micas 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 . try: import os diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/avscontrol.py b/platform/broadcom/sonic-platform-modules-micas/common/script/avscontrol.py index 1f367133a89b..898e528e6f01 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/avscontrol.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/avscontrol.py @@ -1,4 +1,20 @@ #!/usr/bin/env python3 +# +# Copyright (C) 2024 Micas 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 sys import os import time @@ -164,7 +180,7 @@ def doAvsCtrol(avs_conf): ret, log = doAvsCtrol_single(avs_conf) if ret is True: return True, log - time.sleep(10) + time.sleep(1) return False, log diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/cpodaemon.sh b/platform/broadcom/sonic-platform-modules-micas/common/script/cpodaemon.sh new file mode 100755 index 000000000000..11ed62e214a6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/cpodaemon.sh @@ -0,0 +1,99 @@ +#!/bin/bash +# +# Copyright (C) 2024 Micas 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 . + +# SYNCD_SOCKET_FILE=/var/run/sswsyncd/sswsyncd.socket + +function debug() +{ + /usr/bin/logger $1 + /bin/echo `date` "- $1" >> ${DEBUGLOG} +} + +wait_syncd() { + # while true; do + # if [ -e ${SYNCD_SOCKET_FILE} ]; then + # break + # fi + # sleep 1 + # done + + # wait until bcm sdk is ready to get a request + counter=0 + while true; do + /usr/bin/bcmcmd -t 1 "show unit" | grep BCM >/dev/null 2>&1 + rv=$? + if [ $rv -eq 0 ]; then + break + fi + counter=$((counter+1)) + if [ $counter -ge 60 ]; then + echo "syncd is not ready to take commands after $counter re-tries; Exiting!" + break + fi + sleep 1 + done +} + +start() { + debug "Starting cpodaemon service..." + + platforms=( \ + "x86_64-micas_m2-w6940-128x1-fr4-r0" \ + ) + + result=$(cat /host/machine.conf | grep onie_platform | cut -d = -f 2) + echo $result + + cpo_device=0 + for i in ${platforms[*]}; do + if [ $result == $i ]; + then + cpo_device=1 + break + fi + done + + if [ $cpo_device -eq 1 ]; + then + wait_syncd + cpo_daemon + else + echo "$result not support cpo" + exit 0 + fi +} + +wait() { + debug "wait cpodaemon service... do nothing" +} + +stop() { + debug "Stopping cpodaemon service..." + pkill -9 cpo_daemon + debug "Stopped cpodaemon service..." + exit 0 +} + +case "$1" in + start|wait|stop) + $1 + ;; + *) + echo "Usage: $0 {start|wait|stop}" + exit 1 + ;; +esac diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/dev_monitor.py b/platform/broadcom/sonic-platform-modules-micas/common/script/dev_monitor.py index 8ce06db061bf..23b39d3731a0 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/dev_monitor.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/dev_monitor.py @@ -1,4 +1,20 @@ #!/usr/bin/env python3 +# +# Copyright (C) 2024 Micas 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 sys import os import time diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/drv_update.py b/platform/broadcom/sonic-platform-modules-micas/common/script/drv_update.py index ac7c189f1b8f..aebeeee654e0 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/drv_update.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/drv_update.py @@ -1,5 +1,20 @@ #!/usr/bin/env python -# -*- coding: UTF-8 -*- +# +# Copyright (C) 2024 Micas 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 syslog import os import shutil diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/generate_airflow.py b/platform/broadcom/sonic-platform-modules-micas/common/script/generate_airflow.py index ff4fed46fa13..fcbebfab6757 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/generate_airflow.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/generate_airflow.py @@ -1,5 +1,20 @@ #!/usr/bin/env python -# -*- coding: UTF-8 -*- +# +# Copyright (C) 2024 Micas 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 . + ''' generate board air flow according to fan and psu air flow write resulet to AIRFLOW_RESULT_FILE, file format: diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/hal_fanctrl.py b/platform/broadcom/sonic-platform-modules-micas/common/script/hal_fanctrl.py index 5a12b88ac463..a7bfa03942a8 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/hal_fanctrl.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/hal_fanctrl.py @@ -1,4 +1,20 @@ #!/usr/bin/env python3 +# +# Copyright (C) 2024 Micas 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 os import subprocess import time diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/hal_ledctrl.py b/platform/broadcom/sonic-platform-modules-micas/common/script/hal_ledctrl.py index c21fd3c1f585..74fc1727ac77 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/hal_ledctrl.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/hal_ledctrl.py @@ -1,9 +1,26 @@ #!/usr/bin/env python3 +# +# Copyright (C) 2024 Micas 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 time import syslog import traceback from plat_hal.interface import interface from plat_hal.baseutil import baseutil +from platform_util import get_value try: import abc except ImportError as error: @@ -32,7 +49,8 @@ COLOR_GREEN = 1 COLOR_AMBER = 2 COLOR_RED = 3 -LED_STATUS_DICT = {COLOR_GREEN: "green", COLOR_AMBER: "amber", COLOR_RED: "red"} +COLOR_FLASH = 4 +LED_STATUS_DICT = {COLOR_GREEN: "green", COLOR_AMBER: "amber", COLOR_RED: "red", COLOR_FLASH: "flash"} def ledcontrol_debug(s): @@ -305,6 +323,8 @@ def __init__(self): self.__board_air_flow = "" self.int_case = interface() self.__config = baseutil.get_monitor_config() + self.__dcdc_whitelist = self.__config.get('dcdc_monitor_whitelist', {}) + self.__fw_upgrade_check = self.__config.get('fw_upgrade_check', []) self.__temps_threshold_config = self.__config["temps_threshold"] for temp_threshold in self.__temps_threshold_config.values(): temp_threshold['temp'] = 0 @@ -320,9 +340,13 @@ def __init__(self): self.__board_sys_led = self.__ledcontrol_para.get("board_sys_led", []) self.__board_psu_led = self.__ledcontrol_para.get("board_psu_led", []) self.__board_fan_led = self.__ledcontrol_para.get("board_fan_led", []) + self.__board_smb_led = self.__ledcontrol_para.get("board_smb_led", []) self.__psu_air_flow_monitor = self.__ledcontrol_para.get("psu_air_flow_monitor", 0) self.__fan_air_flow_monitor = self.__ledcontrol_para.get("fan_air_flow_monitor", 0) self.__fan_mix_list = self.__ledcontrol_para.get("fan_mix_list", []) + self.__sysled_check_temp = self.__ledcontrol_para.get("sysled_check_temp", 1) + self.__sysled_check_fw_up = self.__ledcontrol_para.get("sysled_check_fw_up", 0) + self.__smbled_ctrl = self.__ledcontrol_para.get("smbled_ctrl", 0) @property def na_ret(self): @@ -372,10 +396,26 @@ def board_psu_led(self): def board_fan_led(self): return self.__board_fan_led + @property + def board_smb_led(self): + return self.__board_smb_led + @property def fan_mix_list(self): return self.__fan_mix_list + @property + def sysled_check_temp(self): + return self.__sysled_check_temp + + @property + def sysled_check_fw_up(self): + return self.__sysled_check_fw_up + + @property + def smbled_ctrl(self): + return self.__smbled_ctrl + @property def interval(self): return self.__interval @@ -397,6 +437,15 @@ def set_led_color(self, led_name, color): ret = False return ret + def set_smb_led(self, color): + for led in self.board_smb_led: + led_name = led.get("led_name") + ret = self.set_led_color(led_name, color) + if ret is True: + ledcontrol_debug("set %s success, color:%s," % (led_name, color)) + else: + ledcontrol_debug("set %s failed, color:%s," % (led_name, color)) + def set_sys_led(self, color): for led in self.board_sys_led: led_name = led.get("led_name") @@ -533,6 +582,97 @@ def checkTempCrit(self): ledcontrol_error(str(e)) return False + def dcdc_whitelist_check(self, dcdc_name): + try: + check_item = self.__dcdc_whitelist.get(dcdc_name, {}) + if len(check_item) == 0: + ledcontrol_debug("%s whitelist config is None" % dcdc_name) + return False + + checkbit = check_item.get("checkbit", None) + okval = check_item.get("okval", None) + if checkbit is None or okval is None: + ledcontrol_error('%s config error, checkbit:%s, okval:%s' % (dcdc_name, checkbit, okval)) + return False + + ret, retval = get_value(check_item) + if ret is False: + ledcontrol_error("get %s whitelist value error, config: %s, msg: %s" % (dcdc_name, check_item, retval)) + return False + + val_t = retval & (1 << checkbit) >> checkbit + if val_t != okval: + return False + return True + except Exception as e: + ledcontrol_error('%%WHITELIST_CHECK: %s check error, msg: %s.' % (dcdc_name, str(e))) + return False + + def get_voltage_led_status(self): + try: + led_status = COLOR_GREEN + dcdc_dict = self.int_case.get_dcdc_all_info() + for dcdc_name, item in dcdc_dict.items(): + ret = self.dcdc_whitelist_check(dcdc_name) + if ret is False: + if item['Value'] is None or int(item['Value']) == self.int_case.error_ret: + ledcontrol_error('The value of %s read failed.' % (dcdc_name)) + elif float(item['Value']) > float(item['Max']): + led_status = COLOR_AMBER + ledcontrol_debug('%s voltage %.3f%s is larger than max threshold %.3f%s.' % + (dcdc_name, float(item['Value']), item['Unit'], float(item['Max']), item['Unit'])) + elif float(item['Value']) < float(item['Min']): + led_status = COLOR_AMBER + ledcontrol_debug('%s voltage %.3f%s is lower than min threshold %.3f%s.' % + (dcdc_name, float(item['Value']), item['Unit'], float(item['Min']), item['Unit'])) + else: + ledcontrol_debug('%s value %s is in range [%s, %s].' % (dcdc_name, item['Value'], item['Min'], item['Max'])) + else: + ledcontrol_debug('%s is in dcdc whitelist, not monitor voltage' % dcdc_name) + except Exception as e: + ledcontrol_error('update dcdc sensors status error, msg: %s.' % (str(e))) + ledcontrol_debug("monitor voltage, set led: %s" % LED_STATUS_DICT.get(led_status)) + return led_status + + def monitor_point_check(self, item): + try: + gettype = item.get('gettype', None) + okval = item.get('okval', None) + compare_mode = item.get('compare_mode', "equal") + ret, value = get_value(item) + if ret is True: + if compare_mode == "equal": + if value == okval: + return True + elif compare_mode == "great": + if value > okval: + return True + elif compare_mode == "ignore": + return True + else: + ledcontrol_debug('compare_mode %s not match error.' % (compare_mode)) + else: + ledcontrol_debug('point check failed, gettype: %s, msg: %s' % (gettype, value)) + except Exception as e: + ledcontrol_error('point check error. msg: %s.' % (str(e))) + return False + + def get_fw_up_led_status(self): + fw_upgrade_flag = False + for item in self.__fw_upgrade_check: + for monitor_point in item: + status = self.monitor_point_check(monitor_point) + if status is False: + fw_upgrade_flag = False + break + fw_upgrade_flag = True + + if fw_upgrade_flag is True: + ledcontrol_debug("Firmware upgrade check: firmware upgrade in progress") + return COLOR_FLASH + ledcontrol_debug("Firmware upgrade check: firmware upgrade not in progress") + return COLOR_GREEN + def check_board_air_flow(self): board_air_flow = self.board_air_flow air_flow_tuple = (F2B_AIR_FLOW, B2F_AIR_FLOW) @@ -697,15 +837,15 @@ def get_monitor_psu_air_flow(self): ledcontrol_debug("monitor psu air flow, set psu led: %s" % LED_STATUS_DICT.get(psu_led_status)) return psu_led_status - def get_temp_sys_led_status(self): + def get_temp_led_status(self): if self.checkTempCrit() is True: - sys_led_status = COLOR_RED + led_status = COLOR_RED elif self.checkTempWarning() is True: - sys_led_status = COLOR_AMBER + led_status = COLOR_AMBER else: - sys_led_status = COLOR_GREEN - ledcontrol_debug("monitor temperature, set sys led: %s" % LED_STATUS_DICT.get(sys_led_status)) - return sys_led_status + led_status = COLOR_GREEN + ledcontrol_debug("monitor temperature, set led: %s" % LED_STATUS_DICT.get(led_status)) + return led_status def get_sys_led_follow_fan_status(self): @@ -728,12 +868,17 @@ def get_sys_led_follow_psu_status(self): def dealSysLedStatus(self): sys_led_status_list = [] - # get_monitor_temp - self.get_monitor_temp() - - # monitor temp get sys led status - sys_led_status = self.get_temp_sys_led_status() - sys_led_status_list.append(sys_led_status) + if self.sysled_check_temp == 1: + ledcontrol_debug("sys led check temperature status") + # get_monitor_temp + self.get_monitor_temp() + # monitor temp get sys led status + sys_led_status = self.get_temp_led_status() + ledcontrol_debug("monitor temperature to get sys led status: %s" % + LED_STATUS_DICT.get(sys_led_status)) + sys_led_status_list.append(sys_led_status) + else: + ledcontrol_debug("sys led don't need to check temperature status") # check sys led follow fan led status sys_led_status = self.get_sys_led_follow_fan_status() @@ -743,6 +888,16 @@ def dealSysLedStatus(self): sys_led_status = self.get_sys_led_follow_psu_status() sys_led_status_list.append(sys_led_status) + if self.sysled_check_fw_up == 1: + ledcontrol_debug("sys led check firmware upgrade") + # monitor firmware get sys led status + sys_led_status = self.get_fw_up_led_status() + ledcontrol_debug("monitor firmware upgrade to get sys led status: %s" % + LED_STATUS_DICT.get(sys_led_status)) + sys_led_status_list.append(sys_led_status) + else: + ledcontrol_debug("sys led don't need to check firmware upgrade") + sys_led_status = max(sys_led_status_list) sys_led_color = LED_STATUS_DICT.get(sys_led_status) @@ -789,10 +944,37 @@ def dealPsuLedStatus(self): # set psu led self.set_psu_led(psu_led_color) + def dealSmbLedStatus(self): + if self.smbled_ctrl == 0: + ledcontrol_debug("Don't need to control SMB led") + return + + ledcontrol_debug("Start to control SMB led") + smb_led_status_list = [] + + # get_monitor_temp + self.get_monitor_temp() + # monitor temp get smb led status + smb_led_status = self.get_temp_led_status() + smb_led_status_list.append(smb_led_status) + ledcontrol_debug("monitor temperature to get smb led status: %s" % LED_STATUS_DICT.get(smb_led_status)) + + # monitor volgate get smb led status + smb_led_status = self.get_voltage_led_status() + smb_led_status_list.append(smb_led_status) + ledcontrol_debug("monitor voltage to get smb led status: %s" % LED_STATUS_DICT.get(smb_led_status)) + + smb_led_status = max(smb_led_status_list) + smb_led_color = LED_STATUS_DICT.get(smb_led_status) + + # set smb led + self.set_smb_led(smb_led_color) + def do_ledcontrol(self): self.dealPsuLedStatus() self.dealFanLedStatus() self.dealSysLedStatus() + self.dealSmbLedStatus() def fan_obj_init(self): fan_num = self.get_fan_total_number() diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/hal_pltfm.py b/platform/broadcom/sonic-platform-modules-micas/common/script/hal_pltfm.py index 11196f507ef1..aec37de3619c 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/hal_pltfm.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/hal_pltfm.py @@ -1,5 +1,20 @@ #!/usr/bin/env python3 -# -*- coding: UTF-8 -*- +# +# Copyright (C) 2024 Micas 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 inspect import sys import json @@ -418,7 +433,8 @@ def get_temps_sensor(): print("=================get_temps_sensor======================") temp_list = int_case.get_temps() for temp in temp_list: - print("id: %s, name: %s, API name: %s, value: %s" % (temp.temp_id, temp.name, temp.api_name, temp.Value)) + print("id: %s, name: %s, API name: %s, value: %s, Min: %s, Low: %s, High: %s, Max: %s, Invalid: %s, Error: %s" % + (temp.temp_id, temp.name, temp.api_name, temp.Value, temp.Min, temp.Low, temp.High, temp.Max, temp.temp_invalid, temp.temp_error)) def get_cpu_reset_num(): r'''get_cpu_reset_num''' diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/intelligent_monitor.py b/platform/broadcom/sonic-platform-modules-micas/common/script/intelligent_monitor.py index 33d5bfba64e6..89c6cc26c274 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/intelligent_monitor.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/intelligent_monitor.py @@ -1,12 +1,26 @@ #!/usr/bin/python3 -# -*- coding: UTF-8 -*- +# +# Copyright (C) 2024 Micas 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 os import time import syslog from plat_hal.interface import interface from plat_hal.baseutil import baseutil -from platform_util import io_rd, wbi2cget +from platform_util import get_value INTELLIGENT_MONITOR_DEBUG_FILE = "/etc/.intelligent_monitor_debug" @@ -59,39 +73,20 @@ def dcdc_whitelist_check(self, dcdc_name): check_item = self.__dcdc_whitelist.get(dcdc_name, {}) if len(check_item) == 0: return False - gettype = check_item.get("gettype", None) + checkbit = check_item.get("checkbit", None) okval = check_item.get("okval", None) - if gettype is None or checkbit is None or okval is None: - monitor_syslog('%%INTELLIGENT_MONITOR-3-DCDC_WHITELIST_FAILED: %s config error. gettype:%s, checkbit:%s, okval:%s' % - (dcdc_name, gettype, checkbit, okval)) + if checkbit is None or okval is None: + monitor_syslog('%%INTELLIGENT_MONITOR-3-DCDC_WHITELIST_FAILED: %s config error. checkbit:%s, okval:%s' % + (dcdc_name, checkbit, okval)) return False - if gettype == "io": - io_addr = check_item.get('io_addr', None) - val = io_rd(io_addr) - if val is not None: - retval = val - else: - monitor_syslog( - '%%INTELLIGENT_MONITOR-3-DCDC_WHITELIST_FAILED: %s io_rd error. io_addr:%s' % - (dcdc_name, io_addr)) - return False - elif gettype == "i2c": - bus = check_item.get('bus', None) - addr = check_item.get('addr', None) - offset = check_item.get('offset', None) - ind, val = wbi2cget(bus, addr, offset) - if ind is True: - retval = val - else: - monitor_syslog('%%INTELLIGENT_MONITOR-3-DCDC_WHITELIST_FAILED: %s i2cget error. bus:%s, addr:%s, offset:%s' % - (dcdc_name, bus, addr, offset)) - return False - else: - monitor_syslog('%%INTELLIGENT_MONITOR-3-DCDC_WHITELIST_FAILED: %s gettype not support' % dcdc_name) + ret, retval = get_value(check_item) + if ret is False: + monitor_syslog( + '%%INTELLIGENT_MONITOR-3-DCDC_WHITELIST_FAILED: %s get value failed, msg:%s' % (dcdc_name, retval)) return False - val_t = (int(retval, 16) & (1 << checkbit)) >> checkbit + val_t = retval & (1 << checkbit) >> checkbit if val_t != okval: return False return True diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/intelligent_monitor/monitor_fan.py b/platform/broadcom/sonic-platform-modules-micas/common/script/intelligent_monitor/monitor_fan.py index bb596a94cc94..01fbe4046837 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/intelligent_monitor/monitor_fan.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/intelligent_monitor/monitor_fan.py @@ -1,5 +1,19 @@ #!/usr/bin/python3 -# -*- coding: UTF-8 -*- +# +# Copyright (C) 2024 Micas 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 os import time diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_common.py b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_common.py index 35c16728f72c..025a22ce82cc 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_common.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_common.py @@ -1,4 +1,19 @@ #!/usr/bin/python3 +# +# Copyright (C) 2024 Micas 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 . __all__ = [ "BLACKLIST_DRIVERS", @@ -15,6 +30,7 @@ "OPTOE", "REBOOT_CAUSE_PARA", "UPGRADE_SUMMARY", + "FW_UPGRADE_STARTED_FLAG", "WARM_UPGRADE_PARAM", "WARM_UPG_FLAG", "WARM_UPGRADE_STARTED_FLAG", @@ -67,7 +83,9 @@ "MONITOR_DEV_STATUS", "MONITOR_DEV_STATUS_DECODE", "DEV_LEDS", - "fanloc" + "fanloc", + "PLATFORM_POWER_CONF", + "POWER_CTRL_CONF" ] # driver blacklist parameter @@ -111,6 +129,7 @@ # upgrade parameter UPGRADE_SUMMARY = {} +FW_UPGRADE_STARTED_FLAG = "/etc/sonic/.doing_fw_upg" # warm_uprade parameter WARM_UPGRADE_PARAM = {} @@ -136,6 +155,12 @@ # driver update config DRVIER_UPDATE_CONF = {} +# platform power config +PLATFORM_POWER_CONF = [] + +# power control config +POWER_CTRL_CONF = {} + ################################ fancontrol parameter################################### MONITOR_TEMP_MIN = 38 MONITOR_K = 11 diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_config.py b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_config.py index d6b3151e47cf..762f33dfbcf9 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_config.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_config.py @@ -1,4 +1,19 @@ #!/usr/bin/python3 +# +# Copyright (C) 2024 Micas 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 sys import os @@ -20,6 +35,7 @@ "PMON_SYSLOG_STATUS", "REBOOT_CAUSE_PARA", "UPGRADE_SUMMARY", + "FW_UPGRADE_STARTED_FLAG", "WARM_UPGRADE_PARAM", "WARM_UPG_FLAG", "WARM_UPGRADE_STARTED_FLAG", @@ -43,7 +59,9 @@ "MONITOR_DEV_STATUS", "MONITOR_DEV_STATUS_DECODE", "DEV_LEDS", - "fanloc" + "fanloc", + "PLATFORM_POWER_CONF", + "POWER_CTRL_CONF" ] @@ -115,6 +133,7 @@ def getdeviceplatform(): # upgrade parameter UPGRADE_SUMMARY = module_product.UPGRADE_SUMMARY +FW_UPGRADE_STARTED_FLAG = module_product.FW_UPGRADE_STARTED_FLAG # warm_uprade parameter WARM_UPGRADE_PARAM = module_product.WARM_UPGRADE_PARAM @@ -140,6 +159,12 @@ def getdeviceplatform(): # driver update config DRVIER_UPDATE_CONF = module_product.DRVIER_UPDATE_CONF +# platform power config +PLATFORM_POWER_CONF = module_product.PLATFORM_POWER_CONF + +# power control config +POWER_CTRL_CONF = module_product.POWER_CTRL_CONF + ################################ fancontrol parameter################################### diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_driver.py b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_driver.py index e27d461bab81..290e3a93a38e 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_driver.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_driver.py @@ -1,9 +1,25 @@ #!/usr/bin/env python3 +# +# Copyright (C) 2024 Micas 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 os import subprocess import time import click -from platform_config import GLOBALCONFIG, WARM_UPGRADE_STARTED_FLAG, WARM_UPG_FLAG +from platform_config import GLOBALCONFIG, WARM_UPGRADE_STARTED_FLAG, WARM_UPG_FLAG, FW_UPGRADE_STARTED_FLAG CONTEXT_SETTINGS = {"help_option_names": ['-h', '--help']} @@ -40,6 +56,10 @@ def platform_process_file_check(): if os.path.exists(WARM_UPG_FLAG): os.remove(WARM_UPG_FLAG) + # FW_UPGRADE_STARTED_FLAG is used as upgrade.py process start flag + if os.path.exists(FW_UPGRADE_STARTED_FLAG): + os.remove(FW_UPGRADE_STARTED_FLAG) + def startCommon_operation(): platform_process_file_check() diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_e2.py b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_e2.py index 4dafde2701cb..a3b7bb7c5421 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_e2.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_e2.py @@ -1,17 +1,52 @@ #!/usr/bin/env python3 -# -*- coding: UTF-8 -*- -import click -import os +# +# Copyright (C) 2024 Micas 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 binascii import sys +import os +import json +import re +import shutil +import click -from eepromutil.fru import ipmifru +from eepromutil.fru import ipmifru, BoardInfoArea, ProductInfoArea from eepromutil.cust_fru import CustFru from eepromutil.fantlv import fan_tlv +from eepromutil.wedge import Wedge +from eepromutil.wedge_v5 import WedgeV5 import eepromutil.onietlv as ot from platform_config import PLATFORM_E2_CONF -from platform_util import byteTostr, dev_file_read +from platform_util import byteTostr, dev_file_read, exec_os_cmd -CONTEXT_SETTINGS = {"help_option_names": ['-h', '--help']} +PYTHON_VERSION = sys.version_info.major +GENERATE_RAWDATA_NUM = 0 +OUTPUT_DIR = "output/" +SUPPORT_E2_TYPE = ("onie_tlv", "fru", "fantlv", "custfru", "wedge", "wedge_v5") +E2_NAME_CLICK_HELP = "Display eeprom information of specified name, such as " + +for e2_key, e2_conf_list in sorted(PLATFORM_E2_CONF.items()): + E2_NAME_CLICK_HELP += e2_key + ", " + for e2_conf in e2_conf_list: + e2_name = e2_conf["name"] + if e2_name == e2_key: + continue + E2_NAME_CLICK_HELP += e2_name + ", " + +E2_NAME_CLICK_HELP = E2_NAME_CLICK_HELP.rstrip(", ") class AliasedGroup(click.Group): @@ -43,7 +78,6 @@ def decode_mac_number(encodedata): return None return (ord(encodedata[0]) << 8) | (ord(encodedata[1]) & 0x00ff) - @staticmethod @staticmethod def fru_decode_mac_number(params): ipmi_fru = params.get("fru") @@ -52,7 +86,7 @@ def fru_decode_mac_number(params): area_info = getattr(ipmi_fru, area, None) if area_info is not None: raw_mac_number = getattr(area_info, field, None) - mac_number = decode_mac_number(raw_mac_number) + mac_number = ExtraFunc.decode_mac_number(raw_mac_number) ipmi_fru.setValue(area, field, mac_number) @staticmethod @@ -63,7 +97,7 @@ def fru_decode_mac(params): area_info = getattr(ipmi_fru, area, None) if area_info is not None: raw_mac = getattr(area_info, field, None) - decoded_mac = decode_mac(raw_mac) + decoded_mac = ExtraFunc.decode_mac(raw_mac) ipmi_fru.setValue(area, field, decoded_mac) @staticmethod @@ -114,20 +148,22 @@ def onie_eeprom_decode(onie, e2_decode): continue -def onie_eeprom_show(eeprom, e2_decode=None): +def onie_eeprom_show(e2_name, eeprom, e2_decode=None): try: onietlv = ot.onie_tlv() rets = onietlv.decode(eeprom) if e2_decode is not None: onie_eeprom_decode(rets, e2_decode) - print("%-20s %-5s %-5s %-20s" % ("TLV name", "Code", "lens", "Value")) + print("===================%s===================" % e2_name) + print("%-20s %-5s %-5s %s" % ("TLV name", "Code", "lens", "Value")) for item in rets: if item["code"] == 0xfd: - print("%-20s 0x%-02X %-5s" % (item["name"], item["code"], item["lens"])) + print("%-20s 0x%-02X %s" % (item["name"], item["code"], item["lens"])) else: - print("%-20s 0x%-02X %-5s %-20s" % (item["name"], item["code"], item["lens"], item["value"])) + print("%-20s 0x%-02X %-5s %s" % (item["name"], item["code"], item["lens"], item["value"])) + return True, "" except Exception as e: - print(str(e)) + return False, str(e) def set_fantlv_value(params): @@ -166,21 +202,21 @@ def fantlv_eeprom_decode(fantlv_dict, e2_decode): continue -def fantlv_eeprom_show(eeprom, e2_decode=None): +def fantlv_eeprom_show(e2_name, eeprom, e2_decode=None): try: tlv = fan_tlv() rets = tlv.decode(eeprom) if len(rets) == 0: - print("fan tlv eeprom info error.!") - return + return False, "fan tlv eeprom info error." if e2_decode is not None: fantlv_eeprom_decode(rets, e2_decode) - print("%-15s %-5s %-5s %-20s" % ("TLV name", "Code", "lens", "Value")) + print("===================%s===================" % e2_name) + print("%-15s %-5s %-5s %s" % ("TLV name", "Code", "lens", "Value")) for item in rets: - print("%-15s 0x%-02X %-5s %-20s" % (item["name"], item["code"], item["lens"], item["value"])) + print("%-15s 0x%-02X %-5s %s" % (item["name"], item["code"], item["lens"], item["value"])) + return True, "" except Exception as e: - print(str(e)) - return + return False, str(e) def run_func(funcname, params): @@ -227,51 +263,171 @@ def fru_eeprom_decode(ipmi_fru, e2_decode): continue -def fru_eeprom_show(eeprom, e2_decode=None): +def fru_eeprom_show(e2_name, eeprom, e2_decode=None): try: ipmi_fru = ipmifru() ipmi_fru.decodeBin(eeprom) if e2_decode is not None: fru_eeprom_decode(ipmi_fru, e2_decode) + print("===================%s==============" % e2_name) print("=================board=================") print(ipmi_fru.boardInfoArea) print("=================product=================") print(ipmi_fru.productInfoArea) + return True, "" except Exception as e: - print(str(e)) + return False, str(e) -def custfru_eeprom_show(eeprom, e2_decode=None): +def custfru_eeprom_show(e2_name, eeprom, e2_decode=None): try: custfru = CustFru() custfru.decode(eeprom) + print("===================%s==============" % e2_name) print(custfru) + return True, "" except Exception as e: - print(str(e)) + return False, str(e) + + +def wedge_eeprom_show(e2_name, eeprom, e2_decode=None): + try: + wegde = Wedge() + wegde.decode(eeprom) + print("===================%s==============" % e2_name) + print(wegde) + return True, "" + except Exception as e: + return False, str(e) + + +def wedge_v5_eeprom_show(e2_name, eeprom, e2_decode=None): + try: + wegdev5 = WedgeV5() + rets = wegdev5.decode(eeprom) + print("===================%s===================" % e2_name) + print("%-32s %-5s %-5s %s" % ("TLV name","Type","Length","Value")) + for item in rets: + print("%-32s %-5d %-5s %s" % (item["name"],item["code"],item["lens"],item["value"])) + return True, "" + except Exception as e: + return False, str(e) + + +def eeprom_parse_by_type(e2_type, name, binval, e2_decode): + if e2_type == "onie_tlv": + return onie_eeprom_show(name, binval, e2_decode) + + if e2_type == "fru": + return fru_eeprom_show(name, binval, e2_decode) + + if e2_type == "fantlv": + return fantlv_eeprom_show(name, binval, e2_decode) + + if e2_type == "custfru": + return custfru_eeprom_show(name, binval, e2_decode) + + if e2_type == "wedge": + return wedge_eeprom_show(name, binval, e2_decode) + + if e2_type == "wedge_v5": + return wedge_v5_eeprom_show(name, binval, e2_decode) + + return False, "Unsupport e2_type: %s" % e2_type -def eeprom_parase(eeprom_conf): +def eeprom_parse_traverse(name, binval, e2_decode=None): + errmsg = "" + support_e2_type = ("onie_tlv", "fru", "fantlv", "custfru", "wedge", "wedge_v5") + for e2_type in support_e2_type: + status, msg = eeprom_parse_by_type(e2_type, name, binval, e2_decode) + if status is True: + return True, "" + errmsg = "%s %s\n" % (errmsg, msg) + return False, errmsg + + +def eeprom_parse_file(e2_path, e2_size): + if e2_size is None: + e2_size = os.path.getsize(e2_path) + ret, binval_bytes = dev_file_read(e2_path, 0, e2_size) + if ret is False: + print("eeprom read error, eeprom path: %s, msg: %s" % (e2_path, binval_bytes)) + return + binval = byteTostr(binval_bytes) + status, msg = eeprom_parse_traverse(e2_path, binval) + if status is not True: + print("===================%s===================" % e2_path) + print("parse [%s] eeprom failed, errmsg:" % e2_path) + print("%s" % msg) + return + + +def eeprom_parse_dir(e2_path, e2_size): + for root, dirs, names in os.walk(e2_path): + # root: directory absolute path + # dirs: folder path collection under directory + # names: file path collection under directory + for filename in names: + # file_path is file absolute path + file_path = os.path.join(root, filename) + eeprom_parse_file(file_path, e2_size) + return + + +def eeprom_parse(e2_path, e2_size): + if os.path.isdir(e2_path): + eeprom_parse_dir(e2_path, e2_size) + elif os.path.isfile(e2_path): + eeprom_parse_file(e2_path, e2_size) + else: + msg = "path: %s not found" % e2_path + print(msg) + return + + +def eeprom_parse_by_config(eeprom_conf): + errmsg = "" name = eeprom_conf.get("name") e2_type = eeprom_conf.get("e2_type") e2_path = eeprom_conf.get("e2_path") e2_size = eeprom_conf.get("e2_size", 256) e2_decode = eeprom_conf.get("e2_decode") - print("===================%s===================" % name) ret, binval_bytes = dev_file_read(e2_path, 0, e2_size) if ret is False: + print("===================%s===================" % name) print("eeprom read error, eeprom path: %s, msg: %s" % (e2_path, binval_bytes)) return binval = byteTostr(binval_bytes) - if e2_type == "onie_tlv": - onie_eeprom_show(binval, e2_decode) - elif e2_type == "fru": - fru_eeprom_show(binval, e2_decode) - elif e2_type == "fantlv": - fantlv_eeprom_show(binval, e2_decode) - elif e2_type == "custfru": - custfru_eeprom_show(binval, e2_decode) - else: - print("Unknow eeprom type: %s" % e2_type) + + if e2_type is None: + status, msg = eeprom_parse_traverse(name, binval, e2_decode) + if status is not True: + print("===================%s===================" % name) + print("parse [%s] eeprom failed, errmsg:" % name) + print("%s" % msg) + return + + if isinstance(e2_type, str): + status, msg = eeprom_parse_by_type(e2_type, name, binval, e2_decode) + if status is not True: + print("===================%s===================" % name) + print("parse [%s] eeprom failed, errmsg: %s" % (name, msg)) + return + + if isinstance(e2_type, list): + for e2_type_item in e2_type: + status, msg = eeprom_parse_by_type(e2_type_item, name, binval, e2_decode) + if status is True: + return + errmsg = "%s %s\n" % (errmsg, msg) + print("===================%s===================" % name) + print("parse [%s] eeprom failed, errmsg:" % name) + print("%s" % errmsg) + return + + print("===================%s===================" % name) + print("Unsupprot e2_type config: %s" % type(e2_type)) return @@ -283,7 +439,7 @@ def get_fans_eeprom_info(param): return if param == 'all': for conf in fan_eeprom_conf: - eeprom_parase(conf) + eeprom_parse_by_config(conf) return if not param.isdigit(): print("param error, %s is not digital or 'all'" % param) @@ -292,7 +448,7 @@ def get_fans_eeprom_info(param): if fan_index < 0 or fan_index >= fan_num: print("param error, total fan number: %d, fan index: %d" % (fan_num, fan_index + 1)) return - eeprom_parase(fan_eeprom_conf[fan_index]) + eeprom_parse_by_config(fan_eeprom_conf[fan_index]) return @@ -304,7 +460,7 @@ def get_psus_eeprom_info(param): return if param == 'all': for conf in psu_eeprom_conf: - eeprom_parase(conf) + eeprom_parse_by_config(conf) return if not param.isdigit(): print("param error, %s is not digital or 'all'" % param) @@ -313,7 +469,7 @@ def get_psus_eeprom_info(param): if psu_index < 0 or psu_index >= psu_num: print("param error, total psu number: %d, psu index: %d" % (psu_num, psu_index + 1)) return - eeprom_parase(psu_eeprom_conf[psu_index]) + eeprom_parse_by_config(psu_eeprom_conf[psu_index]) return @@ -325,7 +481,7 @@ def get_slots_eeprom_info(param): return if param == 'all': for conf in slot_eeprom_conf: - eeprom_parase(conf) + eeprom_parse_by_config(conf) return if not param.isdigit(): print("param error, %s is not digital or 'all'" % param) @@ -334,7 +490,7 @@ def get_slots_eeprom_info(param): if slot_index < 0 or slot_index >= slot_num: print("param error, total slot number: %d, slot index: %d" % (slot_num, slot_index + 1)) return - eeprom_parase(slot_eeprom_conf[slot_index]) + eeprom_parse_by_config(slot_eeprom_conf[slot_index]) return @@ -346,7 +502,7 @@ def get_syseeprom_info(param): return if param == 'all': for conf in syseeprom_conf: - eeprom_parase(conf) + eeprom_parse_by_config(conf) return if not param.isdigit(): print("param error, %s is not digital or 'all'" % param) @@ -355,27 +511,501 @@ def get_syseeprom_info(param): if syseeprom_index < 0 or syseeprom_index >= syseeprom_num: print("param error, total syseeprom number: %d, syseeprom index: %d" % (syseeprom_num, syseeprom_index + 1)) return - eeprom_parase(syseeprom_conf[syseeprom_index]) + eeprom_parse_by_config(syseeprom_conf[syseeprom_index]) return -def decode_eeprom_info(e2_type, e2_path, e2_size): - if not e2_size.isdigit(): - print("param error, e2_size %s is not digital" % e2_size) +def get_all_eeprom_info(): + for e2_key, e2_conf in sorted(PLATFORM_E2_CONF.items()): + for conf in e2_conf: + eeprom_parse_by_config(conf) + + +def get_specified_eeprom_info(e2_type): + if e2_type not in SUPPORT_E2_TYPE: + print("Unsupprot e2_type %s" % e2_type) + return + + match_flag = 0 + for e2_key, e2_conf in sorted(PLATFORM_E2_CONF.items()): + for conf in e2_conf: + name = conf.get("name") + conf_e2_type = conf.get("e2_type") + e2_path = conf.get("e2_path") + e2_size = conf.get("e2_size", 256) + e2_decode = conf.get("e2_decode") + if conf_e2_type is None or (isinstance(conf_e2_type, list) and e2_type in conf_e2_type): + ret, binval_bytes = dev_file_read(e2_path, 0, e2_size) + if ret is False: + # Since it is not sure whether the E2 type matches, don't print error logs. + continue + + binval = byteTostr(binval_bytes) + status, msg = eeprom_parse_by_type(e2_type, name, binval, e2_decode) + if status is True: + match_flag = 1 + continue + + if isinstance(conf_e2_type, str) and conf_e2_type == e2_type: + match_flag = 1 + ret, binval_bytes = dev_file_read(e2_path, 0, e2_size) + if ret is False: + print("===================%s===================" % name) + print("eeprom read error, eeprom path: %s, msg: %s" % (e2_path, binval_bytes)) + continue + + binval = byteTostr(binval_bytes) + status, msg = eeprom_parse_by_type(e2_type, name, binval, e2_decode) + if status is not True: + print("===================%s===================" % name) + print("parse [%s] eeprom failed, errmsg: %s" % (name, msg)) + if match_flag == 0: + print("The eeprom type [%s] was not found in the machine" % e2_type) + return + + +def traverse_eeprom_by_name(e2_name): + match_flag = False + for e2_key, e2_conf_list in sorted(PLATFORM_E2_CONF.items()): + for e2_conf in e2_conf_list: + if e2_conf["name"] == e2_name: + match_flag = True + eeprom_parse_by_config(e2_conf) + return match_flag + + +def get_eeprom_info_by_name(e2_name): + e2_conf_list = PLATFORM_E2_CONF.get(e2_name) + if e2_conf_list is not None: # display all the eeprom information of e2_conf_list + for e2_conf in e2_conf_list: + eeprom_parse_by_config(e2_conf) + return + + # e2_conf_list is None, traverse the configuration to display the specified name eeprom information + status = traverse_eeprom_by_name(e2_name) + if status is False: + print("Can't find %s eeprom information" % e2_name) + return + + +def get_eeprom_config_by_json_file(file_path): + if not os.path.isfile(file_path): + msg = "file path: %s not exits" % file_path + return False, msg + with open(file_path, 'r') as jsonfile: + json_dict = json.load(jsonfile) + return True, json_dict + + +def write_rawdata_to_file(rawdata,out_file): + out_file_dir = os.path.dirname(out_file) + if len(out_file_dir) != 0: + cmd = "mkdir -p %s" % out_file_dir + exec_os_cmd(cmd) + data_array = bytearray() + for x in rawdata: + data_array.append(ord(x)) + with open(out_file, 'wb') as fd: + fd.write(data_array) + return + + +def isValidMac(mac): + if re.match(r"^\s*([0-9a-fA-F]{2,2}:){5,5}[0-9a-fA-F]{2,2}\s*$", mac): + return True + return False + + +def mac_addr_decode(origin_mac): + mac = origin_mac.replace("0x", "") + if len(mac) != 12: + msg = "Invalid MAC address: %s" % origin_mac + return False, msg + release_mac = "" + for i in range(len(mac) // 2): + if i == 0: + release_mac += mac[i * 2:i * 2 + 2] + else: + release_mac += ":" + mac[i * 2:i * 2 + 2] + return True, release_mac + + +def json_list_value_decode(list_value): + u'''json file''' + ret = "" + for item in list_value: + value = int(item, 16) + ret += chr(value) + return ret + + +def get_ext_tlv_body(tlv_type, tlv_value): + ret = "" + ret += (chr(tlv_type)) + ret += (chr(len(tlv_value))) + if isinstance(tlv_value, str): + ret += tlv_value + elif isinstance(tlv_value, list): + ret += json_list_value_decode(tlv_value) + else: + msg = "unsupport onie tlv value type: %s, value: %s" % (type(tlv_value), tlv_value) + return False, msg + return True, ret + + +def generate_ext(ext_dict): + ret = "" + iana = ext_dict.get("iana") + if iana is not None: + if isinstance(iana, str): + ret += iana + elif isinstance(iana, list): + ret += json_list_value_decode(iana) + else: + msg = "unsupport iana type: %s, value: %s" % (type(iana), iana) + return False, msg + del ext_dict['iana'] + + key_list = sorted(ext_dict.keys()) + for key in key_list: + if not key.startswith("code_"): # tlv type format msut be "code_XX" + continue + tlv_type = int(key[5:], 16) + tlv_value = ext_dict[key] + status, ret_tmp= get_ext_tlv_body(tlv_type, tlv_value) + if status is False: + return False, ret_tmp + ret += ret_tmp + return True, ret + + +def check_mac_addr(mac): + if mac.startswith("0x"): + status, mac = mac_addr_decode(mac) + if status is False: + return False, mac + + if isValidMac(mac) is False: + msg = "Invalid MAC address: %s" % mac + return False, msg + return True, mac + + +def generate_onie_tlv_value(onie_tlv_dict): + global GENERATE_RAWDATA_NUM + _value = {} + try: + generate_flag = onie_tlv_dict.get("generate_flag", 0) + if generate_flag == 0: + return + GENERATE_RAWDATA_NUM += 1 + e2_size = onie_tlv_dict.get("e2_size", 256) + e2_name = onie_tlv_dict.get("e2_name") + if e2_name is None: + print("onie tlv config error, e2_name is None, please check") + return + onietlv = ot.onie_tlv() + key_list = sorted(onie_tlv_dict.keys()) + for key in key_list: + if not key.startswith("code_"): # tlv type format msut be "code_XX" + continue + tlv_type = int(key[5:], 16) + tlv_value = onie_tlv_dict[key] + if tlv_type == onietlv.TLV_CODE_MAC_BASE: + status, ret = check_mac_addr(tlv_value) + if status is False: + print("generate onie tlv eeprom rawdata %s failed, errmsg: %s" % (e2_name, ret)) + return + tlv_value = ret + elif tlv_type == onietlv.TLV_CODE_VENDOR_EXT: + status, ret= generate_ext(tlv_value) + if status is False: + print("generate onie tlv eeprom rawdata %s failed, errmsg: %s" % (e2_name, ret)) + return + tlv_value = ret + _value[tlv_type] = tlv_value + + rawdata, ret = onietlv.generate_value(_value, e2_size) + write_rawdata_to_file(rawdata, OUTPUT_DIR + e2_name) + print("generate onie tlv eeprom rawdata success, output file: %s"% (OUTPUT_DIR + e2_name)) + return + except Exception as e: + msg = "generate onie tlv eeprom rawdata %s error, errmsg: %s" % (e2_name, str(e)) + print(msg) + return + + +def generate_fan_tlv_value(fan_tlv_dict): + global GENERATE_RAWDATA_NUM + _value = {} + try: + generate_flag = fan_tlv_dict.get("generate_flag", 0) + if generate_flag == 0: + return + GENERATE_RAWDATA_NUM += 1 + e2_size = fan_tlv_dict.get("e2_size", 256) + e2_name = fan_tlv_dict.get("e2_name") + tlv_terminator = fan_tlv_dict.get("tlv_terminator", 0) + if e2_name is None: + print("fan tlv config error, e2_name is None, please check") + return + + fantlv = fan_tlv() + fantlv.typename = fan_tlv_dict["ProductName"] + fantlv.typesn = fan_tlv_dict["SerialNumber"] + fantlv.typehwinfo = fan_tlv_dict["HardwareInfo"] + fantlv.typedevtype = int(fan_tlv_dict["DevType"], 16) + if tlv_terminator == 1: + fantlv.typename += "\x00" + fantlv.typesn += "\x00" + fantlv.typehwinfo += "\x00" + rawdata = fantlv.generate_fan_value(e2_size) + write_rawdata_to_file(rawdata, OUTPUT_DIR + e2_name) + print("generate fan tlv eeprom rawdata success, output file: %s"% (OUTPUT_DIR + e2_name)) + return + except Exception as e: + msg = "generate fan tlv eeprom rawdata %s error, errmsg: %s" % (e2_name, str(e)) + print(msg) + return + + +def generate_fru_value(fru_dict): + global GENERATE_RAWDATA_NUM + try: + generate_flag = fru_dict.get("generate_flag", 0) + if generate_flag == 0: + return + GENERATE_RAWDATA_NUM += 1 + e2_size = fru_dict.get("e2_size", 256) + e2_name = fru_dict.get("e2_name") + if e2_name is None: + print("fru config error, e2_name is None, please check") + return + + boradispresent = fru_dict.get("boardinfoarea_ispresent", 0) + productispresent = fru_dict.get("productInfoArea_ispresent", 0) + if boradispresent == 0 and productispresent == 0: + print("fru config error, boradispresent = 0 abd productispresent = 0") + return + + bia = None + pia = None + if boradispresent != 0: + boardinfoarea_conf = fru_dict.get("boardinfoarea") + if boardinfoarea_conf is None: + print("fru config error, boardinfoarea ispresent but boardinfoarea config is None") + return + bia = BoardInfoArea(name="Board Info Area", size=0) + bia.isPresent = True + bia.mfg_date =boardinfoarea_conf.get("mfg_date") + bia.boardManufacturer =boardinfoarea_conf["Manufacturer"] + bia.boardProductName = boardinfoarea_conf["ProductName"] + bia.boardSerialNumber = boardinfoarea_conf["SerialNumber"] + bia.boardPartNumber = boardinfoarea_conf["PartNumber"] + bia.fruFileId = boardinfoarea_conf["FRUFileID"] + for i in range(1,11): + ext_str = "extra%d" % i + valtmp = "boardextra%d" % i + val_t = boardinfoarea_conf.get(ext_str) + if val_t is None: + break + if isinstance(val_t, list): + val_t = json_list_value_decode(val_t) + setattr(bia, valtmp, val_t) + + if productispresent != 0: + productinfoarea_conf = fru_dict.get("productInfoArea") + if productinfoarea_conf is None: + print("fru config error, productinfoarea ispresent but productinfoarea_conf config is None") + return + + pia = ProductInfoArea(name="Product Info Area ", size=0) + pia.isPresent = True + pia.productManufacturer = productinfoarea_conf["Manufacturer"] + pia.productName = productinfoarea_conf["ProductName"] + pia.productPartModelName = productinfoarea_conf["PartModelName"] + pia.productVersion = productinfoarea_conf["Version"] + pia.productSerialNumber = productinfoarea_conf["SerialNumber"] + pia.productAssetTag = productinfoarea_conf.get("AssetTag") + pia.fruFileId = productinfoarea_conf["FRUFileID"] + for i in range(1,11): + ext_str = "extra%d" % i + valtmp = "productextra%d" % i + val_t = productinfoarea_conf.get(ext_str) + if val_t is None: + break + if isinstance(val_t, list): + val_t = json_list_value_decode(val_t) + setattr(pia, valtmp, val_t) + + fru = ipmifru() + if bia is not None: + fru.boardInfoArea = bia + if pia is not None: + fru.productInfoArea = pia + fru.recalcute(e2_size) + write_rawdata_to_file(fru.bindata, OUTPUT_DIR + e2_name) + print("generate fru eeprom rawdata success, output file: %s"% (OUTPUT_DIR + e2_name)) + return + except Exception as e: + msg = "generate fru eeprom rawdata %s error, errmsg: %s" % (e2_name, str(e)) + print(msg) return - e2_size = int(e2_size, 10) - eeprom_conf = {} - eeprom_conf["name"] = e2_type - eeprom_conf["e2_type"] = e2_type - eeprom_conf["e2_path"] = e2_path - eeprom_conf["e2_size"] = e2_size - eeprom_parase(eeprom_conf) + + +def generate_wedge_value(wedge_dict): + global GENERATE_RAWDATA_NUM + try: + generate_flag = wedge_dict.get("generate_flag", 0) + if generate_flag == 0: + return + GENERATE_RAWDATA_NUM += 1 + e2_size = wedge_dict.get("e2_size", 256) + e2_name = wedge_dict.get("e2_name") + if e2_name is None: + print("wedge V3 config error, e2_name is None, please check") + return + + wedge = Wedge() + wedge.fbw_product_name = wedge_dict.get("product_name", "") + wedge.fbw_product_number = wedge_dict.get("product_number", "") + wedge.fbw_assembly_number = wedge_dict.get("assembly_number", "") + wedge.fbw_facebook_pcba_number = wedge_dict.get("fb_pcba_number", "") + wedge.fbw_facebook_pcb_number = wedge_dict.get("fb_pcb_number", "") + wedge.fbw_odm_pcba_number = wedge_dict.get("odm_pcba_number", "") + wedge.fbw_odm_pcba_serial = wedge_dict.get("odm_pcba_serial", "") + wedge.fbw_production_state = wedge_dict.get("production_state", 0) + wedge.fbw_product_version = wedge_dict.get("product_version", 0) + wedge.fbw_product_subversion = wedge_dict.get("product_subversion", 0) + wedge.fbw_product_serial = wedge_dict.get("product_serial", "") + wedge.fbw_product_asset = wedge_dict.get("product_asset", "") + wedge.fbw_system_manufacturer = wedge_dict.get("system_manufacturer", "") + wedge.fbw_system_manufacturing_date = wedge_dict.get("system_manufacturing_date", "") + wedge.fbw_pcb_manufacturer = wedge_dict.get("pcb_manufacturer", "") + wedge.fbw_assembled = wedge_dict.get("assembled", "") + wedge.fbw_local_mac = wedge_dict.get("local_mac", "") + wedge.fbw_mac_base = wedge_dict.get("mac_base", "") + wedge.fbw_mac_size = wedge_dict.get("mac_size", 3) + wedge.fbw_location = wedge_dict.get("location", "") + + rawdata = wedge.generate_value(e2_size) + write_rawdata_to_file(rawdata, OUTPUT_DIR + e2_name) + print("generate wedge V3 eeprom rawdata success, output file: %s"% (OUTPUT_DIR + e2_name)) + return + except Exception as e: + msg = "generate wedge V3 eeprom rawdata %s error, errmsg: %s" % (e2_name, str(e)) + print(msg) + return + + +def generate_wedge_v5_value(wedge_v5_dict): + global GENERATE_RAWDATA_NUM + _value = {} + try: + generate_flag = wedge_v5_dict.get("generate_flag", 0) + if generate_flag == 0: + return + GENERATE_RAWDATA_NUM += 1 + e2_size = wedge_v5_dict.get("e2_size", 256) + e2_name = wedge_v5_dict.get("e2_name") + if e2_name is None: + print("wedge V5 config error, e2_name is None, please check") + return + wedgetlv = WedgeV5() + key_list = sorted(wedge_v5_dict.keys()) + for key in key_list: + if not key.startswith("code_"): # tlv type format msut be "code_XX" + continue + tlv_type = int(key[5:], 16) + tlv_value = wedge_v5_dict[key] + if isinstance(tlv_value, list): + tlv_value = json_list_value_decode(tlv_value) + _value[tlv_type] = tlv_value + rawdata = wedgetlv.generate_value(_value, e2_size) + write_rawdata_to_file(rawdata, OUTPUT_DIR + e2_name) + print("generate wedge V5 eeprom rawdata success, output file: %s"% (OUTPUT_DIR + e2_name)) + return + except Exception as e: + msg = "generate wedge V5 eeprom rawdata %s error, errmsg: %s" % (e2_name, str(e)) + print(msg) + return + + +def unicode_convert(input): + if isinstance(input, dict): + return {unicode_convert(key): unicode_convert(value) for key, value in input.iteritems()} + if isinstance(input, list): + return [unicode_convert(element) for element in input] + if isinstance(input, unicode): + return input.encode('utf-8') + return input + + +def generate_eeprom_rawdata(file): + status, ret = get_eeprom_config_by_json_file(file) + if status is False: + print(ret) + return + if os.path.exists(OUTPUT_DIR): + shutil.rmtree(OUTPUT_DIR) + os.mkdir(OUTPUT_DIR) + + if PYTHON_VERSION == 2: + ret = unicode_convert(ret) + + onie_tlv_conf_list = ret.get("onie_tlv", []) + rg_tlv_conf_list = ret.get("fan_tlv", []) + fru_conf_list = ret.get("fru", []) + wedge_conf_list = ret.get("wedge", []) + wedge_v5_conf_list = ret.get("wedge_v5", []) + + for onie_tlv_conf in onie_tlv_conf_list: + generate_onie_tlv_value(onie_tlv_conf) + + for fan_tlv_conf in rg_tlv_conf_list: + generate_fan_tlv_value(fan_tlv_conf) + + for fru_conf in fru_conf_list: + generate_fru_value(fru_conf) + + for wedge_conf in wedge_conf_list: + generate_wedge_value(wedge_conf) + + for wedge_v5_conf in wedge_v5_conf_list: + generate_wedge_v5_value(wedge_v5_conf) + + + if GENERATE_RAWDATA_NUM == 0: + print("All generate_flag config is 0, no eeprom rawdata was generated.") return -@click.group(cls=AliasedGroup, context_settings=CONTEXT_SETTINGS) -def main(): +@click.group(cls=AliasedGroup, invoke_without_command=True) +@click.help_option('-h', '--help', help='show help info') +@click.option('-p', '--parse', help='Parse eeprom rawdata of the specified path, support directory and file') +@click.option('-f', '--file', help='JSON file to generate eeprom rawdata') +@click.option('-t', '--type', help='Display eeprom information of specified type, support onie_tlv/fru/fantlv/custfru/wedge/wedge_v5') +@click.option('-s', '--size', type=int, help='Parse eeprom rawdata of the specified path, support directory and file', hidden=True) +@click.option('-n', '--name', help=E2_NAME_CLICK_HELP) +@click.pass_context +def main(ctx, parse, file, type, size, name): '''platform eeprom display script''' + if ctx.invoked_subcommand is None and parse is None and file is None and type is None and name is None: + cli_ctx = click.Context(main) + click.echo(cli_ctx.get_help()) + return + + if file is not None: + generate_eeprom_rawdata(file) + + if parse is not None: + eeprom_parse(parse, size) + + if type is not None: + get_specified_eeprom_info(type) + + if name is not None: + get_eeprom_info_by_name(name) # fan eeprom info display @@ -410,35 +1040,12 @@ def syseeprom(syseeprom_index): get_syseeprom_info(syseeprom_index) -# fru eeprom info decode -@main.command() -@click.argument('e2_path', required=True) -@click.argument('e2_size', required=False, default="256") -def fru(e2_path, e2_size): - '''e2_path''' - decode_eeprom_info("fru", e2_path, e2_size) - - -# fantlv eeprom info decode -@main.command() -@click.argument('e2_path', required=True) -@click.argument('e2_size', required=False, default="256") -def fantlv(e2_path, e2_size): - '''e2_path''' - decode_eeprom_info("fantlv", e2_path, e2_size) - - -# onie_tlv eeprom info decode +# all eeprom info display @main.command() -@click.argument('e2_path', required=True) -@click.argument('e2_size', required=False, default="256") -def onie_tlv(e2_path, e2_size): - '''e2_path''' - decode_eeprom_info("onie_tlv", e2_path, e2_size) +def all(): + '''get all eeprom info''' + get_all_eeprom_info() if __name__ == '__main__': - if os.geteuid() != 0: - print("Root privileges are required for this operation") - sys.exit(1) main() diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_intf.py b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_intf.py index ef27c2392eb4..9015397a5d26 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_intf.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_intf.py @@ -1,4 +1,20 @@ #!/usr/bin/env python3 +# +# Copyright (C) 2024 Micas 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 os import syslog import glob diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_ipmi.py b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_ipmi.py index c9b72c99cca9..fa3fbc6ece18 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_ipmi.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_ipmi.py @@ -1,5 +1,20 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- +# +# Copyright (C) 2024 Micas 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 sys import os import syslog diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_manufacturer.py b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_manufacturer.py index b2643da9bce4..c9b7cd1441d8 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_manufacturer.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_manufacturer.py @@ -1,4 +1,19 @@ #!/usr/bin/env python3 +# +# Copyright (C) 2024 Micas 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 mmap @@ -11,6 +26,7 @@ import sys from platform_config import MANUINFO_CONF from monitor import status +from platform_util import * INDENT = 4 @@ -171,16 +187,9 @@ def removedriver(name): def deal_itmes(item_list): for item in item_list: - dealtype = item.get("dealtype") - if dealtype == "shell": - cmd = item.get("cmd") - timeout = item.get("timeout", 10) - exec_os_cmd(cmd, timeout) - elif dealtype == "io_wr": - io_addr = item.get("io_addr") - wr_value = item.get("value") - io_wr(io_addr, wr_value) - + ret, log = set_value(item) + if not ret: + print("deal items error:%s" % log) def get_func_value(funcname, params): func = getattr(ExtraFunc, funcname) @@ -228,7 +237,7 @@ def devfileread(path, offset, length, bit_width): for j in range(0, bit_width): val_str += "%02x" % val_list[i + bit_width - j - 1] except Exception as e: - return str(e) + return "%s-%s" % (path, str(e)) finally: if fd > 0: os.close(fd) @@ -495,7 +504,10 @@ def hunt(self): if self.decode is not None: tmp_version = self.decode.get(version) if tmp_version is None: - version = "ERR decode %s failed" % version + if self.decode.get("default") is not None: + version = self.decode.get("default") + else: + version = "ERR decode %s failed" % version else: version = tmp_version format_str = "{}{:<{}}{}".format(indent, self.key + ':', diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_power.py b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_power.py new file mode 100755 index 000000000000..a624b2087d1c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_power.py @@ -0,0 +1,111 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2024 Micas 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 . + +from platform_config import PLATFORM_POWER_CONF +from platform_util import get_value, get_format_value + + +class Power(object): + def __init__(self, conf): + self.name = None + self.format = None + self.unit = None + self.val_conf = None + self.value = 0 + self.child_list = [] + self.status = True + self.pre_check = None + self.__dict__.update(conf) + + def update_value(self): + try: + if self.pre_check is not None: + ret, val = get_value(self.pre_check) + if ret is False: + self.status = False + self.value = "ERR: %s" % val + return + mask = self.pre_check.get("mask") + if isinstance(val, str): + value = int(val, 16) + else: + value = val + ttt = value & mask + okval = self.pre_check.get("okval") + if ttt != okval: + self.status = False + self.value = "%s" % self.pre_check.get("not_ok_msg") + return + + val_list = [] + for val_conf_item in self.val_conf: + ret, val_tmp = get_value(val_conf_item) + if ret is False: + self.status = False + self.value = "ERR: %s" % val_tmp + return + val_list.append(val_tmp) + val_tuple = tuple(val_list) + value = get_format_value(self.format % (val_tuple)) + self.status = True + self.value = round(float(value), 1) + return + except Exception as e: + self.status = False + self.value = "ERR: %s" % str(e) + return + + +def run(): + if len(PLATFORM_POWER_CONF) == 0: + print("platform_power config error, config len is 0!") + return + + power_obj_list = [] + for power_item in PLATFORM_POWER_CONF: + power_obj = Power(power_item) + tmp_value = 0 + power_obj.child_list = [] + children = power_item.get("children") + # get power value with children + if children is not None: + for child in children: + child_obj = Power(child) + power_obj.child_list.append(child_obj) + child_obj.update_value() + if child_obj.status is True: + tmp_value += child_obj.value + power_obj.value = round(float(tmp_value), 1) + else: + power_obj.update_value() + + if power_obj.status is False: + print("%-34s : %s" % (power_obj.name, power_obj.value)) + else: + print("%-34s : %s %s" % (power_obj.name, power_obj.value, power_obj.unit)) + if len(power_obj.child_list) != 0: + for obj in power_obj.child_list: + if obj.status is False: + print(" %-30s : %s" % (obj.name, obj.value)) + else: + print(" %-30s : %s %s" % (obj.name, obj.value, obj.unit)) + print("") + return + + +if __name__ == "__main__": + run() diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_process.py b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_process.py index 6013c5d65853..3c76dd447a7d 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_process.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_process.py @@ -1,4 +1,20 @@ #!/usr/bin/env python3 +# +# Copyright (C) 2024 Micas 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 os import subprocess import glob diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_sensors.py b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_sensors.py index cea20393195f..b7f5ca29d427 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_sensors.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_sensors.py @@ -1,9 +1,35 @@ #!/usr/bin/python3 +# +# Copyright (C) 2024 Micas 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 os import sys import importlib.machinery +try: + from platform_sensors_hal import Platoform_sensor_hal + + platform_sensor_hal = Platoform_sensor_hal() + print_src = platform_sensor_hal.get_sensor_print_src() + if print_src == "s3ip": + platform_sensor_hal.getsensors() + sys.exit(0) +except Exception as e: + pass + def get_machine_info(): if not os.path.isfile('/host/machine.conf'): diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_sensors_hal.py b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_sensors_hal.py new file mode 100755 index 000000000000..7e505b59abe9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_sensors_hal.py @@ -0,0 +1,280 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2024 Micas 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 os +import sys +from plat_hal.interface import interface, getplatform_name +from collections import OrderedDict + +class Platoform_sensor_hal(object): + + # status showed + __STATUS_OK = "OK" + __STATUS_ABSENT = "ABSENT" + __STATUS_NOT_OK = "NOT OK" + __STATUS_FAILED = "GET FAILED" + + def __init__(self): + self.int_case = interface() + + def print_console(self, msg): + print(msg) + + def print_platform(self): + platform_info = getplatform_name() + self.print_console(platform_info) + self.print_console("") + + def print_boardtemp(self): + try: + ''' + eg: cpu temp, mac temp and others + Onboard Temperature Sensors: + BASE_air_inlet : 17.0 C (high = 80.0 C) + MCU_air_inlet0 : 16.5 C (high = 80.0 C) + MCU_air_inlet1 : 16.5 C (high = 80.0 C) + ''' + info_dict = self.int_case.get_temp_info_s3ip() + + monitor_sensor = [] + for sensor_key, sensor_info in info_dict.items(): + monitor_one_sensor_dict = OrderedDict() + monitor_one_sensor_dict['id'] = sensor_key + try: + monitor_one_sensor_dict['temp1_input'] = float(sensor_info["Value"]) / 1000 + monitor_one_sensor_dict['temp1_max'] = float(sensor_info["Max"]) / 1000 + except Exception: + monitor_one_sensor_dict["status"] = self.__STATUS_FAILED + # monitor_one_sensor_dict['temp1_max_hyst'] = sensor_info["High"] + monitor_sensor.append(monitor_one_sensor_dict) + + print_info_str = "" + toptile = "Onboard Temperature Sensors:" + errformat = " {id:<25} : {status}" + # formatstr = " {id:<20} : {temp1_input} C (high = {temp1_max} C, hyst = {temp1_max_hyst} C)" + formatstr = " {id:<25} : {temp1_input} C (high = {temp1_max} C)" + + if len(monitor_sensor) != 0: + print_info_str += toptile + '\n' + for item in monitor_sensor: + realformat = formatstr if item.get('status', self.__STATUS_OK) == self.__STATUS_OK else errformat + print_info_str += realformat.format(**item) + '\n' + self.print_console(print_info_str) + except Exception: + pass + + def print_fan_sensor(self): + try: + ''' + eg: + Onboard fan Sensors: + fan1 : + fan_type :FAN18K8086-F + sn :0000000000000 + hw_version:00 + Speed : + speed_front :12077 RPM + speed_rear :10231 RPM + status :OK + ''' + fans = self.int_case.get_fans() + fan_dict = self.int_case.get_fan_info_all() + monitor_fans = [] + for fan in fans: + monitor_one_fan_dict = OrderedDict() + monitor_one_fan_dict["id"] = fan.name + present = fan_dict.get(fan.name).get("Present") + if present == "no": + monitor_one_fan_dict["status"] = self.__STATUS_ABSENT + else: + monitor_one_fan_dict["fan_type"] = fan_dict.get(fan.name).get("DisplayName") + monitor_one_fan_dict["sn"] = fan_dict.get(fan.name).get("SN") + monitor_one_fan_dict["hw_version"] = fan_dict.get(fan.name).get("HW") + + all_rotors_ok = True + rotor_speeds = {} + for rotor in fan.rotor_list: + rotor_info = fan_dict.get(fan.name).get(rotor.name) + rotor_speeds[rotor.name] = rotor_info.get("Speed") + running = rotor_info.get("Running") + hw_alarm = rotor_info.get("HwAlarm") + if running != "yes" or hw_alarm != "no": + all_rotors_ok = False + monitor_one_fan_dict.update(rotor_speeds) + monitor_one_fan_dict["status"] = self.__STATUS_OK if all_rotors_ok else self.__STATUS_NOT_OK + monitor_one_fan_dict["rotor_num"] = len(fan.rotor_list) + monitor_fans.append(monitor_one_fan_dict) + + print_info_str = "" + toptile = "Onboard fan Sensors:" + errformat = " {id} : {status}\n" # " {id:<20} : {status}" + fan_signle_rotor_format = " {id} : \n" \ + " fan_type : {fan_type}\n" \ + " sn : {sn}\n" \ + " hw_version: {hw_version}\n" \ + " Speed : {Speed} RPM\n" \ + " status : {status} \n" + fan_double_rotor_format = " {id} : \n" \ + " fan_type : {fan_type}\n" \ + " sn : {sn}\n" \ + " hw_version: {hw_version}\n" \ + " Speed :\n" \ + " speed_front : {Rotor1:<5} RPM\n" \ + " speed_rear : {Rotor2:<5} RPM\n" \ + " status : {status} \n" + + if len(monitor_fans) != 0: + print_info_str += toptile + '\n' + for item in monitor_fans: + if item.get("rotor_num", 1) == 2: + realformat = fan_double_rotor_format if item.get('status', self.__STATUS_OK) == self.__STATUS_OK else errformat + else: + realformat = fan_signle_rotor_format if item.get('status', self.__STATUS_OK) == self.__STATUS_OK else errformat + print_info_str += realformat.format(**item) + self.print_console(print_info_str) + except Exception: + pass + + def print_psu_sensor(self): + try: + ''' + Onboard Power Supply Unit Sensors: + psu1 : + type :PSA2000CRPS-F + sn :R693A3D100003 + in_current :1.8 A + in_voltage :237.8 V + out_current:30.1 A + out_voltage:12.2 V + temp :22.5 C + fan_speed :26656 RPM + in_power :413.0 W + out_power :366.5 W + ''' + psus = self.int_case.get_psus() + psu_dict = self.int_case.get_psu_info_all() + monitor_psus = [] + for psu in psus: + monitor_one_psu_dict = OrderedDict() + monitor_one_psu_dict["id"] = psu.name + present = psu_dict.get(psu.name).get("Present") + if present == "no": + monitor_one_psu_dict["status"] = self.__STATUS_ABSENT + else: + monitor_one_psu_dict["type"] = psu_dict.get(psu.name).get("PN") + monitor_one_psu_dict["sn"] = psu_dict.get(psu.name).get("SN") + monitor_one_psu_dict["in_current"] = psu_dict.get(psu.name).get("Inputs").get("Current").get("Value") + monitor_one_psu_dict["in_voltage"] = psu_dict.get(psu.name).get("Inputs").get("Voltage").get("Value") + monitor_one_psu_dict["out_current"] = psu_dict.get(psu.name).get("Outputs").get("Current").get("Value") + monitor_one_psu_dict["out_voltage"] = psu_dict.get(psu.name).get("Outputs").get("Voltage").get("Value") + monitor_one_psu_dict["temp"] = psu_dict.get(psu.name).get("Temperature").get("Value") + monitor_one_psu_dict["fan_speed"] = psu_dict.get(psu.name).get("FanSpeed").get("Value") + monitor_one_psu_dict["in_power"] = psu_dict.get(psu.name).get("Inputs").get("Power").get("Value") + monitor_one_psu_dict["out_power"] = psu_dict.get(psu.name).get("Outputs").get("Power").get("Value") + monitor_psus.append(monitor_one_psu_dict) + + print_info_str = "" + toptile = "Onboard Power Supply Unit Sensors:" + errformat = " {id} : {status}\n" # " {id:<20} : {status}" + psuformat = " {id} : \n" \ + " type : {type}\n" \ + " sn : {sn}\n" \ + " in_current : {in_current} A\n" \ + " in_voltage : {in_voltage} V\n" \ + " out_current: {out_current} A\n" \ + " out_voltage: {out_voltage} V\n" \ + " temp : {temp} C \n" \ + " fan_speed : {fan_speed} RPM\n" \ + " in_power : {in_power} W\n" \ + " out_power : {out_power} W\n" + + if len(monitor_psus) != 0: + print_info_str += toptile + '\r\n' + for item in monitor_psus: + realformat = psuformat if item.get('status', self.__STATUS_OK) == self.__STATUS_OK else errformat + print_info_str += realformat.format(**item) + self.print_console(print_info_str) + except Exception: + pass + + def print_boarddcdc(self): + try: + ''' + eg: + Onboard DCDC Sensors: + CPU_VCCIN : 12.187 V (Min = 1.500 V, Max = 2.000 V) + CPU_P1V8 : 1.780 V (Min = 1.710 V, Max = 1.890 V) + CPU_P1V05 : 12.250 V (Min = 1.000 V, Max = 1.120 V) + CPU_VNN_PCH : 1.060 V (Min = 0.600 V, Max = 1.200 V) + CPU_P1V2_VDDQ : 12.125 V (Min = 1.140 V, Max = 1.260 V) + CPU_VNN_NAC : 12.187 V (Min = 0.600 V, Max = 1.200 V) + CPU_VCC_ANA : 0.845 V (Min = 0.950 V, Max = 1.050 V) + CPU_P1V05 : 1.057 V (Min = 0.990 V, Max = 1.130 V) + ''' + + dcdc_dict = self.int_case.get_dcdc_all_info() + monitor_sensor = [] + for sensor_key, sensor_info in dcdc_dict.items(): + monitor_one_sensor_dict = OrderedDict() + monitor_one_sensor_dict['id'] = sensor_key + try: + monitor_one_sensor_dict['dcdc_input'] = float(sensor_info["Value"]) / 1000 + monitor_one_sensor_dict['dcdc_unit'] = sensor_info["Unit"] + monitor_one_sensor_dict['dcdc_min'] = float(sensor_info["Min"]) / 1000 + monitor_one_sensor_dict['dcdc_unit'] = sensor_info["Unit"] + monitor_one_sensor_dict['dcdc_max'] = float(sensor_info["Max"]) / 1000 + monitor_one_sensor_dict['dcdc_unit'] = sensor_info["Unit"] + monitor_one_sensor_dict["status"] = sensor_info["Status"] + except Exception: + monitor_one_sensor_dict["status"] = self.__STATUS_FAILED + monitor_sensor.append(monitor_one_sensor_dict) + + print_info_str = "" + toptile = "Onboard DCDC Sensors:" + errformat = " {id:<26} : {errmsg}" + ok_formatstr = " {id:<26} : {dcdc_input:<6} {dcdc_unit:<1} (Min = {dcdc_min:<6} {dcdc_unit:<1}, Max = {dcdc_max:<6} {dcdc_unit:<1})" + nok_formatstr = " {id:<26} : {dcdc_input:<6} {dcdc_unit:<1} (Min = {dcdc_min:<6} {dcdc_unit:<1}, Max = {dcdc_max:<6} {dcdc_unit:<1}) ({status:<6})" + + if len(monitor_sensor) != 0: + print_info_str += toptile + '\n' + for item in monitor_sensor: + if item.get("status", self.__STATUS_OK) == self.__STATUS_OK: + realformat = ok_formatstr + elif item.get("status", self.__STATUS_OK) == self.__STATUS_NOT_OK: + realformat = nok_formatstr + else: + realformat = errformat + print_info_str += realformat.format(**item) + '\n' + self.print_console(print_info_str) + except Exception: + pass + + def getsensors(self): + self.print_platform() + self.print_boardtemp() + # self.print_macpower_sensors() + self.print_fan_sensor() + self.print_psu_sensor() + # self.print_slot_sensor() + self.print_boarddcdc() + + def get_sensor_print_src(self): + return self.int_case.get_sensor_print_src() + +if __name__ == "__main__": + platform_sensor_hal = Platoform_sensor_hal() + platform_sensor_hal.getsensors() diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_test.py b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_test.py index da7119a9ce49..a7c39264c791 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_test.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_test.py @@ -1,5 +1,19 @@ #!/usr/bin/env python3 -# -*- coding: UTF-8 -*- +# +# Copyright (C) 2024 Micas 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 . try: import click diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_util.py b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_util.py index fe4d564ad604..2187b391a230 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/platform_util.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/platform_util.py @@ -1,4 +1,19 @@ #!/usr/bin/python3 +# +# Copyright (C) 2024 Micas 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 sys import os @@ -69,6 +84,8 @@ def get_op_value(self, node): value = node.n elif isinstance(node, ast.Str): # node is Str Constant value = node.s + elif isinstance(node, ast.List): # node is List Constant + value = [element.value for element in node.elts] else: raise NotImplementedError("Unsupport operand type: %s" % type(node)) return value @@ -117,7 +134,7 @@ def visit_Call(self, node): int support one or two parameters, eg: int(xxx) or int(xxx, 16) xxx can be ast.Call/ast.Constant(ast.Num/ast.Str)/ast.BinOp ''' - calc_tuple = ("float", "int", "str") + calc_tuple = ("float", "int", "str", "max", "min") if node.func.id not in calc_tuple: raise NotImplementedError("Unsupport function call type: %s" % node.func.id) @@ -125,7 +142,10 @@ def visit_Call(self, node): args_val_list = [] for item in node.args: ret = self.get_op_value(item) - args_val_list.append(ret) + if isinstance(ret, list): + args_val_list.extend(ret) + else: + args_val_list.append(ret) if node.func.id == "str": if len(args_val_list) != 1: @@ -140,6 +160,16 @@ def visit_Call(self, node): value = float(args_val_list[0]) self.value = value return value + + if node.func.id == "max": + value = max(args_val_list) + self.value = value + return value + + if node.func.id == "min": + value = min(args_val_list) + self.value = value + return value # int if len(args_val_list) == 1: value = int(args_val_list[0]) @@ -375,14 +405,20 @@ def dev_file_write(path, offset, buf_list): msg = "" fd = -1 - if not isinstance(buf_list, list) or len(buf_list) == 0: - msg = "buf:%s is not list type or is NONE !" % buf_list - return False, msg - if not os.path.exists(path): msg = path + " not found !" return False, msg + if isinstance(buf_list, list): + if len(buf_list) == 0: + msg = "buf_list:%s is NONE !" % buf_list + return False, msg + elif isinstance(buf_list, int): + buf_list = [buf_list] + else: + msg = "buf_list:%s is not list type or not int type !" % buf_list + return False, msg + try: fd = os.open(path, os.O_WRONLY) os.lseek(fd, offset, os.SEEK_SET) @@ -565,6 +601,9 @@ def get_value_once(config): read_len = config.get("read_len") ret, val_list = dev_file_read(path, offset, read_len) if ret is True: + if read_len == 1: + val = val_list[0] + return True, val return True, val_list return False, ("devfile read failed. path:%s, offset:0x%x, read_len:%d" % (path, offset, read_len)) if way == 'cmd': @@ -578,7 +617,16 @@ def get_value_once(config): if os.path.exists(judge_file): return True, True return True, False - return False, "not support read type" + if way == 'pci': + pcibus = config.get("pcibus") + slot = config.get("slot") + fn = config.get("fn") + bar = config.get("bar") + offset = config.get("offset") + data = config.get("data") + return wbpcird(pcibus, slot, fn, bar, offset, data) + + return False, ("%s is not support read type" % way) except Exception as e: return False, ("get_value_once exception:%s happen" % str(e)) @@ -668,7 +716,7 @@ def set_value_once(config): ret, log = dev_file_write(path, offset, buf_list) if ret is True: return True, ("devfile write path:%s, offset:0x%x, buf_list:%s success." % (path, offset, buf_list)) - return False, ("devfile read path:%s, offset:0x%x, buf_list:%s failed.log:%s" % + return False, ("devfile write path:%s, offset:0x%x, buf_list:%s failed.log:%s" % (path, offset, buf_list, log)) if way == 'cmd': cmd = config.get("cmd") @@ -703,7 +751,16 @@ def set_value_once(config): return False, ("remove file %s failed, log: %s" % (file_name, log)) exec_os_cmd("sync") return True, ("remove file %s success" % file_name) - return False, "not support write type" + if way == 'pci': + pcibus = config.get("pcibus") + slot = config.get("slot") + fn = config.get("fn") + bar = config.get("bar") + offset = config.get("offset") + data = config.get("data") + return wbpciwr(pcibus, slot, fn, bar, offset, data) + + return False, ("%s not support write type" % way) except Exception as e: return False, ("set_value_once exception:%s happen" % str(e)) diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/pmon_syslog.py b/platform/broadcom/sonic-platform-modules-micas/common/script/pmon_syslog.py index 8bdceef8c1b5..95c1eebe5ab2 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/pmon_syslog.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/pmon_syslog.py @@ -1,8 +1,20 @@ #!/usr/bin/python3 -# * onboard interval check -# * FAN trays -# * PSU -# * SFF +# +# Copyright (C) 2024 Micas 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 time import syslog import traceback diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/power_ctrl.py b/platform/broadcom/sonic-platform-modules-micas/common/script/power_ctrl.py new file mode 100755 index 000000000000..bc43168c68f2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/power_ctrl.py @@ -0,0 +1,333 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2024 Micas 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 syslog +import click +import os +import fcntl +import time +import sys +from platform_util import get_value, set_value +from platform_config import POWER_CTRL_CONF + + +POWERCTLDEBUG = 0 +OE_SUPPROT_OPERATE = ("status", "off", "on", "reset") +STATUS_OFF = "off" +STATUS_ON = "on" +STATUS_UNKNOWN = "unknown" +CLI_CONFIRM = True +POWER_CTRL_DEBUG_FILE = "/etc/.power_control_debug" +CONTEXT_SETTINGS = {"help_option_names": ['-h', '--help']} + + +class AliasedGroup(click.Group): + def get_command(self, ctx, cmd_name): + rv = click.Group.get_command(self, ctx, cmd_name) + if rv is not None: + return rv + matches = [x for x in self.list_commands(ctx) + if x.startswith(cmd_name)] + if not matches: + return None + if len(matches) == 1: + return click.Group.get_command(self, ctx, matches[0]) + ctx.fail('Too many matches: %s' % ', '.join(sorted(matches))) + return None + + +def debug_init(): + global POWERCTLDEBUG + if os.path.exists(POWER_CTRL_DEBUG_FILE): + POWERCTLDEBUG = 1 + else: + POWERCTLDEBUG = 0 + + +def powerctrldebug(s): + # s = s.decode('utf-8').encode('gb2312') + if POWERCTLDEBUG == 1: + syslog.openlog("POWERCTRL", syslog.LOG_PID) + syslog.syslog(syslog.LOG_DEBUG, s) + + +def get_status_once(conf): + val_conf = conf.get("val_conf", {}) + ret, val = get_value(val_conf) + if ret is False: + powerctrldebug("get_status_once failure, val_conf: %s, msg: %s" % (val_conf, val)) + return STATUS_UNKNOWN + + if isinstance(val, str): + val_tmp = int(val, 16) + else: + val_tmp = val + + mask = val_conf.get("mask") + if mask is not None: + value = val_tmp & mask + else: + value = val_tmp + + powerctrldebug("val_conf: %s, value: %s, val_tmp: %s, mask: %s" % (val_conf, value, val_tmp, mask)) + off_val_list = conf.get("off", []) + if value in off_val_list: + powerctrldebug("value: %s, is in off_val_list: %s, status is off" % (value, off_val_list)) + return STATUS_OFF + + on_val_list = conf.get("on", []) + if value in on_val_list: + powerctrldebug("value: %s, is in on_val_list: %s, status is on" % (value, on_val_list)) + return STATUS_ON + + powerctrldebug("value: %s, not in off_val_list: %s, and on_val_list: %s" % (value, off_val_list, on_val_list)) + return STATUS_UNKNOWN + + +def get_status(conf): + status_list = [] + for item in conf: + status = get_status_once(item) + break_status = item.get("break_status", []) + if status in break_status: + powerctrldebug("status: %s is in break status: %s, return" % (status, break_status)) + return status + status_list.append(status) + if len(set(status_list)) == 1: # All states are consistent + powerctrldebug("All states are consistent, status_list: %s, return status: %s" % (status_list, status_list[0])) + return status_list[0] + # status list inconsistent + powerctrldebug("The status in the status list is inconsistent, status_list: %s" % status_list) + return STATUS_UNKNOWN + + +def do_power_operation(conf): + for item in conf: + ret, msg = set_value(item) + if ret is False: + powerctrldebug("set value failed, conf: %s, msg %s" % (item, msg)) + return ret, msg + powerctrldebug("set value success, conf: %s" % item) + return True, "" + + +def do_power_off(name, conf, cli_confirm): + power_conf = conf.get("off") + if power_conf is None: + msg = ("power off config is none, can't do power off operation.") + return False, msg + + if cli_confirm is True and not click.confirm("Are you sure you want to power off %s?" % name): + click.echo('Aborted.') + sys.exit(0) + ret, msg = do_power_operation(power_conf) + return ret, msg + + +def do_power_on(name, conf, cli_confirm): + power_conf = conf.get("on") + if power_conf is None: + msg = ("power on config is none, can't do power on operation.") + return False, msg + + if cli_confirm is True and not click.confirm("Are you sure you want to power on %s?" % name): + click.echo('Aborted.') + sys.exit(0) + ret, msg = do_power_operation(power_conf) + return ret, msg + + +def do_power_cycle(name, conf, cli_confirm): + if cli_confirm is True and not click.confirm("Are you sure you want to power cycle %s?" % name): + click.echo('Aborted.') + sys.exit(0) + + power_conf = conf.get("cycle") + if power_conf is not None: + ret, msg = do_power_operation(power_conf) + return ret, msg + # power cycle config is none, try to power off then power on + ret, msg = do_power_off(name, conf, False) + if ret is False: + return ret, msg + ret, msg = do_power_on(name, conf, False) + return ret, msg + + +def do_power_reset(name, conf, cli_confirm): + power_conf = conf.get("reset") + if power_conf is None: + msg = ("power reset config is none, can't do power reset operation.") + return False, msg + + if cli_confirm is True and not click.confirm("Are you sure you want to power on %s?" % name): + click.echo('Aborted.') + sys.exit(0) + + ret, msg = do_power_operation(power_conf) + return ret, msg + + +def do_operation(conf, command): + name = conf.get("name") + + # First get the current status before any operation + curr_status = None + status_conf = conf.get("status") + if status_conf is None: + powerctrldebug("%s status config is None" % name) + else: + curr_status = get_status(status_conf) + powerctrldebug("%s get_status %s" % (name, curr_status)) + + # get status command + if command == "status": + if curr_status is None: + print("Can't get %s %s config" % (name, command)) + else: + print("Power status for %s: %s" % (name, curr_status)) + return + + # power off command + if command == "off": + if curr_status == "off": + print("%s is already powered off..." % name) + return + ret, msg = do_power_off(name, conf, CLI_CONFIRM) + if ret is False: + print("%s powered off failure, msg: %s" % (name, msg)) + else: + print("%s powered off successfully" % name) + return + + # power on command + if command == "on": + if curr_status == "on": + print("%s is already powered on..." % name) + return + ret, msg = do_power_on(name, conf, CLI_CONFIRM) + if ret is False: + print("%s powered on failure, msg: %s" % (name, msg)) + else: + print("%s powered on successfully" % name) + return + + # power cycle command + if command == "cycle": + if curr_status == "off": + # current status is off, do powered on to powered cycle + powerctrldebug("%s current status is off, try to do powered on" % name) + ret, msg = do_power_on(name, conf, CLI_CONFIRM) + else: + # current status is not off, do powered cycle + powerctrldebug("%s current status is not off, try to do powered cycle" % name) + ret, msg = do_power_cycle(name, conf, CLI_CONFIRM) + + if ret is False: + print("%s powered cycle failure, msg: %s" % (name, msg)) + else: + print("%s powered cycle successfully" % name) + return + + # power reset command + if curr_status == "off": + print("%s is currently powered off. Please power it on before performing the reset operation." % name) + return + ret, msg = do_power_reset(name, conf, CLI_CONFIRM) + if ret is False: + print("%s powered reset failure, msg: %s" % (name, msg)) + else: + print("%s powered reset successfully" % name) + return + + +def do_oe_power_ctrl(oe_index, command): + oe_power_conf = POWER_CTRL_CONF.get("oe", []) + oe_num = len(oe_power_conf) + if oe_num == 0: + print("OE power control config is none, don't support oe power control.") + return + + if oe_index < 0 or oe_index >= oe_num: + print("Invalid oe index: %d, oe index must [0~%d]" % (oe_index, oe_num -1)) + return + + if command not in OE_SUPPROT_OPERATE: + print("Unsupported operation command: %s" % command) + return + + oe_power_conf_item = oe_power_conf[oe_index] + + do_operation(oe_power_conf_item, command) + return + + +pidfile = 0 +def ApplicationInstance(): + global pidfile + pidfile = open(os.path.realpath(__file__), "r") + try: + fcntl.flock(pidfile, fcntl.LOCK_EX | fcntl.LOCK_NB) + return True + except Exception: + return False + + +# Single-process execution only +def cli_ready_check(): + start_time = time.time() + while True: + ret = ApplicationInstance() + if ret is True: + break + + if time.time() - start_time < 0: + start_time = time.time() + + if time.time() - start_time > 10: + print("Please wait for the power_ctrl command to complete before performing further operations") + sys.exit(1) + time.sleep(0.1) + return + + +@click.group(cls=AliasedGroup, context_settings=CONTEXT_SETTINGS) +@click.help_option('-h', '--help', help='show help info') +@click.option('-y', '--yes', is_flag=True, help='Automatically confirm and skip the prompt.', hidden=True) +def main(yes): + '''power control script''' + global CLI_CONFIRM + if yes is True: + CLI_CONFIRM = False + + +# oe power control +@main.command() +@click.argument('oe_index', required=True, type=int) +@click.argument('command', required=True) +def oe(oe_index, command): + '''OE_INDEX: start from 0, COMMAND: off, on, reset, status''' + do_oe_power_ctrl(oe_index, command) + + +if __name__ == '__main__': + if os.geteuid() != 0: + print("Root privileges are required for this operation") + sys.exit(1) + cli_ready_check() + debug_init() + main() diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/reboot_cause.py b/platform/broadcom/sonic-platform-modules-micas/common/script/reboot_cause.py index 2f125c5084c2..0020dd32b9d1 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/reboot_cause.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/reboot_cause.py @@ -1,5 +1,20 @@ #!/usr/bin/python3 -# -*- coding: UTF-8 -*- +# +# Copyright (C) 2024 Micas 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 sys import os import time @@ -45,8 +60,12 @@ def monitor_point_check(self, item): ret, value = get_value(item) if ret is True: if compare_mode == "equal": - if value == okval: - return True + if isinstance(okval, list): + if value in okval: + return True + else: + if value == okval: + return True elif compare_mode == "great": if value > okval: return True diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/reboot_ctrl.py b/platform/broadcom/sonic-platform-modules-micas/common/script/reboot_ctrl.py deleted file mode 100755 index 17d3f5902b9d..000000000000 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/reboot_ctrl.py +++ /dev/null @@ -1,150 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: UTF-8 -*- -import time -import syslog -import click -from platform_util import write_sysfs, wbi2cset, io_wr, wbi2csetWord -from platform_config import REBOOT_CTRL_PARAM - - -REBOOTCTLDEBUG = 0 - -CONTEXT_SETTINGS = {"help_option_names": ['-h', '--help']} - - -class AliasedGroup(click.Group): - def get_command(self, ctx, cmd_name): - rv = click.Group.get_command(self, ctx, cmd_name) - if rv is not None: - return rv - matches = [x for x in self.list_commands(ctx) - if x.startswith(cmd_name)] - if not matches: - return None - if len(matches) == 1: - return click.Group.get_command(self, ctx, matches[0]) - ctx.fail('Too many matches: %s' % ', '.join(sorted(matches))) - return None - - -def rebootctrlwarning(s): - # s = s.decode('utf-8').encode('gb2312') - syslog.openlog("REBOOTCTRL", syslog.LOG_PID) - syslog.syslog(syslog.LOG_WARNING, s) - - -def rebootctrlcritical(s): - # s = s.decode('utf-8').encode('gb2312') - syslog.openlog("REBOOTCTRL", syslog.LOG_PID) - syslog.syslog(syslog.LOG_CRIT, s) - - -def rebootctrlerror(s): - # s = s.decode('utf-8').encode('gb2312') - syslog.openlog("REBOOTCTRL", syslog.LOG_PID) - syslog.syslog(syslog.LOG_ERR, s) - - -def rebootctrldebug(s): - # s = s.decode('utf-8').encode('gb2312') - if REBOOTCTLDEBUG == 1: - syslog.openlog("REBOOTCTRL", syslog.LOG_PID) - syslog.syslog(syslog.LOG_DEBUG, s) - - -class RebootCtrl(): - def __init__(self): - self.config = REBOOT_CTRL_PARAM.copy() - - def set_value(self, config, val): - way = config.get("gettype") - if way == 'sysfs': - loc = config.get("loc") - value = config.get(val) - rebootctrldebug("sysfs type.loc:0x%x, value:0x%x" % (loc, value)) - return write_sysfs(loc, "0x%02x" % value) - if way == "i2c": - bus = config.get("bus") - addr = config.get("loc") - offset = config.get("offset") - value = config.get(val) - rebootctrldebug("i2c type.bus:0x%x, addr:0x%x, offset:0x%x, value:0x%x" % (bus, addr, offset, value)) - return wbi2cset(bus, addr, offset, value) - if way == "io": - io_addr = config.get('io_addr') - value = config.get(val) - rebootctrldebug("io type.io_addr:0x%x, value:0x%x" % (io_addr, value)) - ret = io_wr(io_addr, value) - if ret is not True: - return False, ("write 0x%x failed" % io_addr) - return True, ("write 0x%x success" % io_addr) - if way == 'i2cword': - bus = config.get("bus") - addr = config.get("loc") - offset = config.get("offset") - value = config.get(val) - rebootctrldebug("i2cword type.bus:0x%x, addr:0x%x, offset:0x%x, value:0x%x" % (bus, addr, offset, value)) - return wbi2csetWord(bus, addr, offset, value) - return False, "unsupport way: %s" % way - - def reset_operate(self, config): - ret, log = self.set_value(config, "rst_val") - rst_delay = config.get("rst_delay", 0) - time.sleep(rst_delay) - return ret, log - - def unlock_reset_operate(self, config): - ret, log = self.set_value(config, "unlock_rst_val") - unlock_rst_delay = config.get("unlock_rst_delay", 0) - time.sleep(unlock_rst_delay) - return ret, log - - def do_rebootctrl(self, option): - if self.config is None: - rebootctrlerror("Reset failed, REBOOT_CTRL_PARAM cfg get failed.") - return - try: - name_conf = self.config.get(option, None) - if name_conf is None: - print("Reset %s not support" % option) - return - try: - click.confirm("Are you sure you want to reset " + option + "?", - default=False, abort=True, show_default=True) - except Exception as e: - print("Aborted, msg: %s" % str(e)) - return - print("Reset %s start" % option) - ret, log = self.reset_operate(name_conf) - if ret is False: - rebootctrlerror(log) - print("Reset %s failed" % option) - return - if "unlock_rst_val" in name_conf: - ret, log = self.unlock_reset_operate(name_conf) - if ret is False: - rebootctrlerror(log) - print("%s unlock reset failed" % option) - return - print("Reset %s success" % option) - except Exception: - rebootctrlerror("do_rebootctrl Exception error") - return - - -@click.group(cls=AliasedGroup, context_settings=CONTEXT_SETTINGS) -def main(): - '''reboot_ctrl reset [option]''' - - -@main.command() -@click.argument('option', required=True) -def reset(option): - '''reset device''' - rebootctrldebug("reboot ctrl option %s" % option) - rebootctrl = RebootCtrl() - rebootctrl.do_rebootctrl(option) - - -if __name__ == '__main__': - main() diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/sensors b/platform/broadcom/sonic-platform-modules-micas/common/script/sensors index a2c72b123a43..f81cc18bfb7a 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/sensors +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/sensors @@ -1,6 +1,21 @@ #!/bin/bash -#docker exec -i pmon sensors "$@" +# +# Copyright (C) 2024 Micas 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 . +# docker exec -i pmon sensors "$@" #To probe sensors not part of lm-sensors if [ -r /usr/local/bin/platform_sensors.py ]; then diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/set_eth_mac.py b/platform/broadcom/sonic-platform-modules-micas/common/script/set_eth_mac.py index f4727d802753..227bc8e00e61 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/set_eth_mac.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/set_eth_mac.py @@ -1,5 +1,20 @@ #!/usr/bin/env python -# -*- coding: UTF-8 -*- +# +# Copyright (C) 2024 Micas 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 syslog import os import re diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/sfp_highest_temperatue.py b/platform/broadcom/sonic-platform-modules-micas/common/script/sfp_highest_temperatue.py index 4dd98f3a36b3..21e14b048873 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/sfp_highest_temperatue.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/sfp_highest_temperatue.py @@ -1,4 +1,20 @@ #!/usr/bin/python3 +# +# Copyright (C) 2024 Micas 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 os import importlib.machinery import time @@ -13,6 +29,10 @@ SFP_TEMP_RECORD_ERROR = 2 debuglevel = 0 +# For TH5 CPO only +cpo_temperature_oe_file = "/etc/sonic/highest_oe_temp" +cpo_temperature_rlm_file = "/etc/sonic/highest_rlm_temp" +cpo_onie_platform = "x86_64-micas_m2-w6940-128x1-fr4-r0" def sfp_temp_debug(s): if SFP_TEMP_RECORD_DEBUG & debuglevel: @@ -25,28 +45,21 @@ def sfp_temp_error(s): syslog.openlog("SFP_TEMP_ERROR", syslog.LOG_PID) syslog.syslog(syslog.LOG_ERR, s) - -pidfile = None - - -def file_rw_lock(): - global pidfile - pidfile = open(sfp_temperature_file, "r") +def file_rw_lock(file_path): + pidfile = open(file_path, "r") try: fcntl.flock(pidfile, fcntl.LOCK_EX | fcntl.LOCK_NB) sfp_temp_debug("file lock success") - return True + return True, pidfile except Exception: if pidfile is not None: pidfile.close() pidfile = None - return False + return False, pidfile -def file_rw_unlock(): +def file_rw_unlock(pidfile): try: - global pidfile - if pidfile is not None: fcntl.flock(pidfile, fcntl.LOCK_UN) pidfile.close() @@ -70,7 +83,7 @@ def get_sfp_highest_temperature(): sfputil_dir = "/usr/share/sonic/platform/" sfputil_path = sfputil_dir + "/plugins/sfputil.py" else: - cmd = "cat /host/machine.conf | grep onie_build_platform" + cmd = "cat /host/machine.conf | grep onie_platform" ret, output = subprocess.getstatusoutput(cmd) if ret != 0: sfp_temp_error("cmd: %s execution fail, output: %s" % (cmd, output)) @@ -86,21 +99,22 @@ def get_sfp_highest_temperature(): highest_temperature = int(temperature) * 1000 except Exception as e: sfp_temp_error("get sfp temperature error, msg:%s" % str(e)) - highest_temperature = -9999000 + highest_temperature = -9999000 # fix me in future, should be -99999000 return highest_temperature -def write_sfp_highest_temperature(temperature): +def write_sfp_highest_temperature(temperature, path): loop = 1000 ret = False + pidfile = None try: - if os.path.exists(sfp_temperature_file) is False: - with open(sfp_temperature_file, 'w') as sfp_f: + if os.path.exists(path) is False: + with open(path, 'w') as sfp_f: pass for i in range(0, loop): - ret = file_rw_lock() + ret, pidfile = file_rw_lock(path) if ret is True: break time.sleep(0.001) @@ -109,16 +123,89 @@ def write_sfp_highest_temperature(temperature): sfp_temp_error("take file lock timeout") return - with open(sfp_temperature_file, 'w') as sfp_f: + with open(path, 'w') as sfp_f: sfp_f.write("%s\n" % str(temperature)) - file_rw_unlock() + file_rw_unlock(pidfile) return except Exception as e: sfp_temp_error("write sfp temperature error, msg:%s" % str(e)) - file_rw_unlock() + file_rw_unlock(pidfile) return +def get_cpo_highest_temperature(): + + oe_temp = get_cpo_highest_temperature_oe() + rlm_temp = get_cpo_highest_temperature_rlm() + + return oe_temp, rlm_temp + +def get_cpo_highest_temperature_oe(): + highest_temperature = 0 + platform_sfputil = None + sfputil_dir = "/usr/share/sonic/device/" + try: + if not os.path.exists(sfputil_dir): + sfputil_dir = "/usr/share/sonic/platform/" + sfputil_path = sfputil_dir + "/plugins/sfputil.py" + else: + cmd = "cat /host/machine.conf | grep onie_platform" + ret, output = subprocess.getstatusoutput(cmd) + if ret != 0: + sfp_temp_error("cmd: %s execution fail, output: %s" % (cmd, output)) + + onie_platform = output.split("=")[1] + sfputil_path = sfputil_dir + onie_platform + "/plugins/sfputil.py" + module = importlib.machinery.SourceFileLoader("sfputil", sfputil_path).load_module() + platform_sfputil_class = getattr(module, "SfpUtil") + platform_sfputil = platform_sfputil_class() + + temperature = platform_sfputil.get_highest_temperature_cpo_oe() + highest_temperature = int(temperature) * 1000 + except Exception as e: + sfp_temp_error("get sfp temperature error, msg:%s" % str(e)) + highest_temperature = -99999000 + + return highest_temperature + +def get_cpo_highest_temperature_rlm(): + highest_temperature = 0 + platform_sfputil = None + sfputil_dir = "/usr/share/sonic/device/" + try: + if not os.path.exists(sfputil_dir): + sfputil_dir = "/usr/share/sonic/platform/" + sfputil_path = sfputil_dir + "/plugins/sfputil.py" + else: + cmd = "cat /host/machine.conf | grep onie_platform" + ret, output = subprocess.getstatusoutput(cmd) + if ret != 0: + sfp_temp_error("cmd: %s execution fail, output: %s" % (cmd, output)) + + onie_platform = output.split("=")[1] + sfputil_path = sfputil_dir + onie_platform + "/plugins/sfputil.py" + + module = importlib.machinery.SourceFileLoader("sfputil", sfputil_path).load_module() + platform_sfputil_class = getattr(module, "SfpUtil") + platform_sfputil = platform_sfputil_class() + + temperature = platform_sfputil.get_highest_temperature_cpo_rlm() + highest_temperature = int(temperature) * 1000 + except Exception as e: + sfp_temp_error("get sfp temperature error, msg:%s" % str(e)) + highest_temperature = -99999000 + + return highest_temperature + +def is_th5_cpo(): + cmd = "cat /host/machine.conf | grep onie_platform" + ret, output = subprocess.getstatusoutput(cmd) + if ret != 0: + sfp_temp_error("cmd: %s execution fail, output: %s" % (cmd, output)) + if output.split("=")[1] == cpo_onie_platform: + return True + + return False def debug_init(): global debuglevel @@ -132,16 +219,35 @@ def debug_init(): def main(): - while True: - debug_init() - temperature = 0 - try: - temperature = get_sfp_highest_temperature() - write_sfp_highest_temperature(temperature) - except Exception as e: - sfp_temp_error("get/write sfp temperature error, msg:%s" % str(e)) - write_sfp_highest_temperature(-9999000) - time.sleep(5) + if is_th5_cpo(): + while True: + debug_init() + temperature_oe = 0 + try: + temperature_oe = get_cpo_highest_temperature_oe() + write_sfp_highest_temperature(temperature_oe, cpo_temperature_oe_file) + except Exception as e: + sfp_temp_error("get/write sfp temperature error, msg:%s" % str(e)) + write_sfp_highest_temperature(-99999000, cpo_temperature_oe_file) + temperature_rlm = 0 + try: + temperature_rlm = get_cpo_highest_temperature_rlm() + write_sfp_highest_temperature(temperature_rlm, cpo_temperature_rlm_file) + except Exception as e: + sfp_temp_error("get/write sfp temperature error, msg:%s" % str(e)) + write_sfp_highest_temperature(-99999000, cpo_temperature_rlm_file) + time.sleep(5) + else: + while True: + debug_init() + temperature = 0 + try: + temperature = get_sfp_highest_temperature() + write_sfp_highest_temperature(temperature, sfp_temperature_file) + except Exception as e: + sfp_temp_error("get/write sfp temperature error, msg:%s" % str(e)) + write_sfp_highest_temperature(-9999000, sfp_temperature_file) + time.sleep(5) if __name__ == '__main__': diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/slot_monitor.py b/platform/broadcom/sonic-platform-modules-micas/common/script/slot_monitor.py index 0385f50b6f50..633fc028964e 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/slot_monitor.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/slot_monitor.py @@ -1,5 +1,20 @@ #!/usr/bin/env python3 -# -*- coding: UTF-8 -*- +# +# Copyright (C) 2024 Micas 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 time import syslog import traceback diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/ssdmon b/platform/broadcom/sonic-platform-modules-micas/common/script/ssdmon index 4290b0a68725..2b79aed0a276 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/ssdmon +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/ssdmon @@ -1,9 +1,21 @@ #!/usr/bin/env python3 # -# ssdmon +# Copyright (C) 2024 Micas Networks Inc. # -# Command-line utility to check SSD health and parameters +# 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 . + +# Command-line utility to check SSD health and parameters try: import argparse diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/subnetwork.py b/platform/broadcom/sonic-platform-modules-micas/common/script/subnetwork.py index 5f9df14c8696..376da42231be 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/subnetwork.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/subnetwork.py @@ -1,5 +1,20 @@ #!/usr/bin/env python3 -# -*- coding: UTF-8 -*- +# +# Copyright (C) 2024 Micas 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 os import re import subprocess diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/tty_console.py b/platform/broadcom/sonic-platform-modules-micas/common/script/tty_console.py index 4fae02f5128e..793f9b5aea3e 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/tty_console.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/tty_console.py @@ -1,5 +1,19 @@ #!/usr/bin/python3 -# -*- coding: UTF-8 -*- +# +# Copyright (C) 2024 Micas 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 logging.handlers import subprocess diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/upgrade.py b/platform/broadcom/sonic-platform-modules-micas/common/script/upgrade.py index 1b2523198ed8..5e10afd85414 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/upgrade.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/upgrade.py @@ -1,5 +1,20 @@ #!/usr/bin/env python3 -# -*- coding: UTF-8 -*- +# +# Copyright (C) 2024 Micas 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 sys import os import time @@ -7,7 +22,7 @@ import signal import click from platform_util import get_value, set_value, exec_os_cmd, exec_os_cmd_log -from platform_config import UPGRADE_SUMMARY, WARM_UPGRADE_STARTED_FLAG +from platform_config import UPGRADE_SUMMARY, WARM_UPGRADE_STARTED_FLAG, FW_UPGRADE_STARTED_FLAG from warm_upgrade import WarmBasePlatform @@ -679,7 +694,11 @@ def do_test(self, device, slot): def do_test_main(self, device, slot): print("+================================+") print("|Doing upgrade test, please wait.|") + exec_os_cmd("touch %s" % FW_UPGRADE_STARTED_FLAG) + exec_os_cmd("sync") ret, log = self.do_test(device, slot) + exec_os_cmd("rm -rf %s" % FW_UPGRADE_STARTED_FLAG) + exec_os_cmd("sync") if ret == FIRMWARE_SUCCESS: print("| test succeeded! |") print("+================================+") @@ -694,8 +713,12 @@ def do_test_main(self, device, slot): def do_bmc_upgrade_main(self, file, chip_select, erase_type): bmc_upgrade_config = self.upgrade_param.get("BMC", {}) + exec_os_cmd("touch %s" % FW_UPGRADE_STARTED_FLAG) + exec_os_cmd("sync") ret, log = self.upgrading(bmc_upgrade_config, file, self.devtype, self.subtype, chip_select, BMC_UPGRADE, erase_type) + exec_os_cmd("rm -rf %s" % FW_UPGRADE_STARTED_FLAG) + exec_os_cmd("sync") if ret is True: print("===========upgrade succeeded!============") sys.exit(0) @@ -925,7 +948,11 @@ def do_fw_upg(self, path, slot, upg_type): def fw_upg(self, path, slot, upg_type): print("+================================+") print("| Doing upgrade, please wait... |") + exec_os_cmd("touch %s" % FW_UPGRADE_STARTED_FLAG) + exec_os_cmd("sync") ret, log = self.do_fw_upg(path, slot, upg_type) + exec_os_cmd("rm -rf %s" % FW_UPGRADE_STARTED_FLAG) + exec_os_cmd("sync") if ret == FIRMWARE_SUCCESS: print("| upgrade succeeded! |") print("+================================+") diff --git a/platform/broadcom/sonic-platform-modules-micas/common/script/warm_upgrade.py b/platform/broadcom/sonic-platform-modules-micas/common/script/warm_upgrade.py index 69a310faa606..919bed2ec694 100755 --- a/platform/broadcom/sonic-platform-modules-micas/common/script/warm_upgrade.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/script/warm_upgrade.py @@ -1,5 +1,20 @@ #!/usr/bin/env python3 -# -*- coding: UTF-8 -*- +# +# Copyright (C) 2024 Micas 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 sys import os import time @@ -199,6 +214,9 @@ def do_fw_upg_finish_cmd(self, finish_cmd_list): return True, msg def access_test(self, config): + skip = config.get("skip", 0) + if skip == 1: + return True # polling execute command polling_cmd_list = config.get("polling_cmd", []) for polling_cmd_config in polling_cmd_list: diff --git a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/chassis.py index b0ddc8691f2e..8f07567207a0 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/chassis.py @@ -1,12 +1,19 @@ #!/usr/bin/env python3 - -############################################################################# # +# Copyright (C) 2024 Micas 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. # -# Module contains an implementation of SONiC Platform Base API and -# provides the platform information +# 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 . try: import time @@ -306,6 +313,8 @@ def get_reboot_cause(self): reboot_cause_type = self.REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC elif "Thermal Overload: Other" in reboot_cause_msg: reboot_cause_type = self.REBOOT_CAUSE_THERMAL_OVERLOAD_OTHER + elif "CPU reboot" in reboot_cause_msg: + reboot_cause_type = self.REBOOT_CAUSE_HARDWARE_CPU elif "Other" in reboot_cause_msg: reboot_cause_type = self.REBOOT_CAUSE_NON_HARDWARE else: diff --git a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/component.py index fa674a98a6bf..6e775c3045c3 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/component.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/component.py @@ -1,12 +1,19 @@ #!/usr/bin/env python3 - -######################################################################## # -# Module contains an implementation of SONiC Platform Base API and -# provides the Components' (e.g., BIOS, CPLD, FPGA, etc.) available in -# the platform +# Copyright (C) 2024 Micas 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 . try: import time diff --git a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/dcdc.py b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/dcdc.py index 494d4aa610dc..920f4c2d3f68 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/dcdc.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/dcdc.py @@ -1,11 +1,20 @@ #!/usr/bin/env python3 - -######################################################################## # -# Module contains an implementation of SONiC Platform Base API and -# provides the Thermals' information which are available in the platform +# Copyright (C) 2024 Micas 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 time diff --git a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/eeprom.py index 05fcc3c25678..7987e3368781 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/eeprom.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/eeprom.py @@ -1,16 +1,19 @@ #!/usr/bin/env python3 -######################################################################## # -# Module contains platform specific implementation of SONiC Platform -# Base API and provides the EEPROMs' information. +# Copyright (C) 2024 Micas 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. # -# The different EEPROMs available are as follows: -# - System EEPROM : Contains Serial number, Service tag, Base MA -# address, etc. in ONIE TlvInfo EEPROM format. -# - PSU EEPROM : Contains Serial number, Part number, Service Tag, -# PSU type, Revision. -# - Fan EEPROM : Contains Serial number, Part number, Service Tag, -# Fan type, Number of Fans in Fantray, Revision. +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . ######################################################################## try: diff --git a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/fan_drawer.py index f0b039648158..4864f435cf36 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/fan_drawer.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/fan_drawer.py @@ -1,11 +1,19 @@ #!/usr/bin/env python3 # -# fan_drawer_base.py +# Copyright (C) 2024 Micas Networks Inc. # -# Abstract base class for implementing a platform-specific class with which -# to interact with a fan drawer module in SONiC +# 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 . try: import time from sonic_platform_base.fan_drawer_base import FanDrawerBase diff --git a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/pcie.py b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/pcie.py index 8ea66f339e96..627a43f56a26 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/pcie.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/pcie.py @@ -1,12 +1,19 @@ #!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -######################################################################## # -# Module contains a platform specific implementation of SONiC Platform -# Base PCIe class +# Copyright (C) 2024 Micas 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 . try: from sonic_platform_base.sonic_pcie.pcie_common import PcieUtil diff --git a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/platform.py b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/platform.py index 4d6fe03d93ac..6d8aaf5ce9ab 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/platform.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/platform.py @@ -1,11 +1,19 @@ #!/usr/bin/env python3 - -############################################################################# # -# Module contains an implementation of SONiC Platform Base API and -# provides the platform information +# Copyright (C) 2024 Micas 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 . try: from sonic_platform_base.platform_base import PlatformBase diff --git a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/psu.py index de661dacdff6..63cde88413c9 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/psu.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/psu.py @@ -1,10 +1,19 @@ #!/usr/bin/env python3 -######################################################################## # -# Module contains an implementation of SONiC Platform Base API and -# provides the PSUs' information which are available in the platform +# Copyright (C) 2024 Micas 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 . try: diff --git a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/sfp.py index 3fc22b4b6618..4d789d6d4602 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/sfp.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/sfp.py @@ -1,5 +1,19 @@ #!/usr/bin/python -# -*- coding: UTF-8 -*- +# +# Copyright (C) 2024 Micas 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 . ############################################################################# # @@ -34,6 +48,7 @@ ############################################################################# import sys import time +import fcntl import syslog import traceback from abc import abstractmethod @@ -50,8 +65,10 @@ raise ImportError(str(error) + "- required module not found") from error LOG_DEBUG_LEVEL = 1 -LOG_WARNING_LEVEL = 2 -LOG_ERROR_LEVEL = 3 +LOG_INFO_LEVEL = 2 +LOG_NOTICE_LEVEL = 3 +LOG_WARNING_LEVEL = 4 +LOG_ERROR_LEVEL = 5 class Sfp(SfpOptoeBase): @@ -75,6 +92,8 @@ def __init__(self, index): self._sfp_api = SfpV1(index) elif vers == 2: self._sfp_api = SfpV2(index) + elif vers == 3: + self._sfp_api = SfpV3CPO(index) else: self._sfplog(LOG_ERROR_LEVEL, "Get SfpVer Error!") @@ -84,23 +103,35 @@ def get_eeprom_path(self): def read_eeprom(self, offset, num_bytes): return self._sfp_api.read_eeprom(offset, num_bytes) + def write_eeprom(self, offset, num_bytes, write_buffer): + return self._sfp_api.write_eeprom(offset, num_bytes, write_buffer) + def get_presence(self): return self._sfp_api.get_presence() def get_transceiver_info(self): - # temporary solution for a sonic202111 bug - transceiver_info = super().get_transceiver_info() - try: - if transceiver_info == None: - return None - if transceiver_info['cable_type'] == None: - transceiver_info['cable_type'] = 'N/A' - if transceiver_info["vendor_rev"] is not None: - transceiver_info["hardware_rev"] = transceiver_info["vendor_rev"] - except BaseException: - print(traceback.format_exc()) - return None - return transceiver_info + api_get = self._sfp_api.get_transceiver_info(SfpOptoeBase, self) + return api_get if api_get is not None else super().get_transceiver_info() + + def get_transceiver_bulk_status(self): + api_get = self._sfp_api.get_transceiver_bulk_status(SfpOptoeBase, self) + return api_get if api_get is not None else super().get_transceiver_bulk_status() + + def get_transceiver_threshold_info(self): + api_get = self._sfp_api.get_transceiver_threshold_info(SfpOptoeBase, self) + return api_get if api_get is not None else super().get_transceiver_threshold_info() + + def get_transceiver_status(self): + api_get = self._sfp_api.get_transceiver_status(SfpOptoeBase, self) + return api_get if api_get is not None else super().get_transceiver_status() + + def get_transceiver_loopback(self): + api_get = self._sfp_api.get_transceiver_loopback(SfpOptoeBase, self) + return api_get if api_get is not None else super().get_transceiver_loopback() + + def get_transceiver_pm(self): + api_get = self._sfp_api.get_transceiver_pm(SfpOptoeBase, self) + return api_get if api_get is not None else super().get_transceiver_pm() def get_reset_status(self): if self.get_presence() is False: @@ -142,7 +173,7 @@ def get_lpmode(self): if self.sfp_type is None: self.refresh_xcvr_api() - if self.sfp_type == 'QSFP' or self.sfp_type == 'QSFP-DD': + if self.sfp_type == 'QSFP' or self.sfp_type == 'QSFP_DD': return SfpOptoeBase.get_lpmode(self) self._sfplog(LOG_WARNING_LEVEL, 'SFP does not support lpmode') @@ -155,7 +186,7 @@ def set_lpmode(self, lpmode): if self.sfp_type is None or self._xcvr_api is None: self.refresh_xcvr_api() - if self.sfp_type == 'QSFP-DD' or self.sfp_type == 'QSFP': + if self.sfp_type == 'QSFP_DD' or self.sfp_type == 'QSFP': return SfpOptoeBase.set_lpmode(self, lpmode) self._sfplog(LOG_WARNING_LEVEL, 'SFP does not support lpmode') @@ -226,7 +257,7 @@ def refresh_xcvr_api(self): optoe_type = None # set sfp_type if 'CmisApi' in class_name: - self.sfp_type = 'QSFP-DD' + self.sfp_type = 'QSFP_DD' optoe_type = self.OPTOE_DRV_TYPE3 elif 'Sff8472Api' in class_name: self.sfp_type = 'SFP' @@ -244,8 +275,12 @@ def _sfplog(self, log_level, msg): syslog.openlog("Sfp") if log_level == LOG_DEBUG_LEVEL: syslog.syslog(syslog.LOG_DEBUG, msg) + if log_level == LOG_INFO_LEVEL: + syslog.syslog(syslog.LOG_INFO, msg) + if log_level == LOG_NOTICE_LEVEL: + syslog.syslog(syslog.LOG_NOTICE, msg) elif log_level == LOG_WARNING_LEVEL: - syslog.syslog(syslog.LOG_DEBUG, msg) + syslog.syslog(syslog.LOG_WARNING, msg) elif log_level == LOG_ERROR_LEVEL: syslog.syslog(syslog.LOG_ERR, msg) syslog.closelog() @@ -269,10 +304,44 @@ def _init_config(self, index): def _get_eeprom_path(self): return self.eeprom_path or None + @abstractmethod + def _pre_get_transceiver_info(self): + pass + @abstractmethod def get_presence(self): pass + def get_transceiver_info(self, class_optoeBase, class_sfp): + # temporary solution for a sonic202111 bug + transceiver_info = class_optoeBase.get_transceiver_info(class_sfp) + try: + if transceiver_info == None: + return None + if transceiver_info['cable_type'] == None: + transceiver_info['cable_type'] = 'N/A' + if transceiver_info["vendor_rev"] is not None: + transceiver_info["hardware_rev"] = transceiver_info["vendor_rev"] + except BaseException: + self._sfplog(LOG_ERROR_LEVEL, traceback.format_exc()) + return None + return transceiver_info + + def get_transceiver_bulk_status(self, class_optoeBase, class_sfp): + pass + + def get_transceiver_threshold_info(self, class_optoeBase, class_sfp): + pass + + def get_transceiver_status(self, class_optoeBase, class_sfp): + pass + + def get_transceiver_loopback(self, class_optoeBase, class_sfp): + pass + + def get_transceiver_pm(self, class_optoeBase, class_sfp): + pass + def read_eeprom(self, offset, num_bytes): try: for i in range(self.eeprom_retry_times): @@ -292,18 +361,16 @@ def read_eeprom(self, offset, num_bytes): return None def write_eeprom(self, offset, num_bytes, write_buffer): - try: - for i in range(self.eeprom_retry_times): - ret = SfpOptoeBase.write_eeprom(self, offset, num_bytes, write_buffer) - if ret is False: - time.sleep(self.eeprom_retry_break_sec) - continue - break - - return ret - except BaseException: - self._sfplog(LOG_ERROR_LEVEL, traceback.format_exc()) - return False + for i in range(self.eeprom_retry_times): + try: + with open(self._get_eeprom_path(), mode='r+b', buffering=0) as f: + f.seek(offset) + f.write(write_buffer[0:num_bytes]) + return True + except (OSError, IOError): + time.sleep(self.eeprom_retry_break_sec) + pass + return False @abstractmethod def set_optoe_type(self, optoe_type): @@ -337,8 +404,12 @@ def _sfplog(self, log_level, msg): syslog.openlog("SfpCust") if log_level == LOG_DEBUG_LEVEL: syslog.syslog(syslog.LOG_DEBUG, msg) + if log_level == LOG_INFO_LEVEL: + syslog.syslog(syslog.LOG_INFO, msg) + if log_level == LOG_NOTICE_LEVEL: + syslog.syslog(syslog.LOG_NOTICE, msg) elif log_level == LOG_WARNING_LEVEL: - syslog.syslog(syslog.LOG_DEBUG, msg) + syslog.syslog(syslog.LOG_WARNING, msg) elif log_level == LOG_ERROR_LEVEL: syslog.syslog(syslog.LOG_ERR, msg) syslog.closelog() @@ -382,10 +453,12 @@ def get_presence(self): if dev_id == -1: return False ret, info = platform_reg_read(0, dev_id, offset, 1) - if (ret is False - or info is None): + if ((ret is False) or (info is None)): return False return info[0] & (1 << offset_bit) == self.presence_val_is_present + except SystemExit: + self._sfplog(LOG_WARNING_LEVEL, "SystemExit") + return False except BaseException: self._sfplog(LOG_ERROR_LEVEL, traceback.format_exc()) return False @@ -405,6 +478,9 @@ def get_reset_status(self): return False return (info[0] & (1 << offset_bit) == self.reset_val_is_reset) + except SystemExit: + self._sfplog(LOG_WARNING_LEVEL, "SystemExit") + return False except BaseException: self._sfplog(LOG_ERROR_LEVEL, traceback.format_exc()) return False @@ -428,6 +504,9 @@ def get_tx_disable(self): tx_disable_list.append(info[0] & (1 << offset_bit) != 0) else: tx_disable_list.append(info[0] & (1 << offset_bit) == 0) + except SystemExit: + self._sfplog(LOG_WARNING_LEVEL, "SystemExit") + return None except BaseException: self._sfplog(LOG_ERROR_LEVEL, traceback.format_exc()) return None @@ -506,7 +585,9 @@ def set_reset(self, reset): if ret is False: self._sfplog(LOG_ERROR_LEVEL, "platform_reg_write error!") return False - + except SystemExit: + self._sfplog(LOG_WARNING_LEVEL, "SystemExit") + return False except BaseException: self._sfplog(LOG_ERROR_LEVEL, traceback.format_exc()) return False @@ -543,7 +624,9 @@ def set_tx_disable(self, tx_disable): if ret is False: self._sfplog(LOG_ERROR_LEVEL, "platform_reg_write error!") return False - + except SystemExit: + self._sfplog(LOG_WARNING_LEVEL, "SystemExit") + return False except BaseException: self._sfplog(LOG_ERROR_LEVEL, traceback.format_exc()) return False @@ -632,3 +715,197 @@ def set_optoe_type(self, optoe_type): self._sfplog(LOG_ERROR_LEVEL, traceback.format_exc()) return False return True + +class SfpV3CPO(SfpCust): + def _init_config(self, index): + super()._init_config(index) + sfp_config = baseutil.get_config().get("sfps", None) + + eeprom_path_config = sfp_config.get("eeprom_path", None) + eeprom_path_key = sfp_config.get("eeprom_path_key")[self._port_id - 1] + self.eeprom_path = None if eeprom_path_config is None else eeprom_path_config % ( + eeprom_path_key, eeprom_path_key) + self._sfplog(LOG_DEBUG_LEVEL, "Done init eeprom path: %s" % self.eeprom_path) + + # CPO always present + def get_presence(self): + return True + + def read_eeprom(self, offset, num_bytes): + # temp solution for CPO byte0 bug, remove me when it fixed + if offset == 0: + if self._file_rw_lock() is False: + return None + self._switch_page(0) + result = self._read_eeprom(offset, num_bytes) + self._file_rw_unlock() + return result + + if offset < 128: # page 0L + return self._read_eeprom(offset, num_bytes) + + if self._file_rw_lock() is False: + return None + + # for other page, need to convert flat_mem offset to single page offset + result = self._convert_to_single_page_offset_read(offset, num_bytes) + self._file_rw_unlock() + return result + + def write_eeprom(self, offset, num_bytes, write_buffer): + # temp solution for CPO byte0 bug, remove me when it fixed + if offset == 0: + if self._file_rw_lock() is False: + return None + self._switch_page(0) + result = self._write_eeprom(offset, num_bytes, write_buffer) + self._file_rw_unlock() + return result + + if offset < 128: # page 0L + return self._write_eeprom(offset, num_bytes, write_buffer) + + if self._file_rw_lock() is False: + return None + + # for other page, need to convert flat_mem offset to single page offset + result = self._convert_to_single_page_offset_write(offset, num_bytes, write_buffer) + self._file_rw_unlock() + return result + + def set_optoe_type(self, optoe_type): + ret, info = platform_get_optoe_type(self._port_id) + if ret is True and info != optoe_type: + try: + ret, _ = platform_set_optoe_type(self._port_id, optoe_type) + except Exception as err: + self._sfplog(LOG_ERROR_LEVEL, "Set optoe err %s" % err) + + def _read_eeprom(self, offset, num_bytes): + try: + for i in range(self.eeprom_retry_times): + with open(self._get_eeprom_path(), mode='rb', buffering=0) as f: + f.seek(offset) + result = f.read(num_bytes) + # temporary solution for a sonic202111 bug + if len(result) < num_bytes: + result = result[::-1].zfill(num_bytes)[::-1] + if result is not None: + return bytearray(result) + time.sleep(self.eeprom_retry_break_sec) + continue + + except BaseException: + self._sfplog(LOG_ERROR_LEVEL, traceback.format_exc()) + return None + + def _write_eeprom(self, offset, num_bytes, write_buffer): + for i in range(self.eeprom_retry_times): + try: + with open(self._get_eeprom_path(), mode='r+b', buffering=0) as f: + f.seek(offset) + f.write(write_buffer[0:num_bytes]) + return True + except BaseException: + print(traceback.format_exc()) + time.sleep(self.eeprom_retry_break_sec) + pass + return False + + def _switch_page(self, page): + page_offset = 127 #0x7f + num_bytes = 1 + cur_page = self._read_eeprom(page_offset, num_bytes)[0] + if cur_page is None: + self._sfplog(LOG_ERROR_LEVEL, "CPO read PAGE ERROR!") + return False + + if cur_page == page: + return True + + return self._write_eeprom(page_offset, num_bytes, bytearray([page])) + + def _switch_bank(self, bank): + bank_offset = 126 #0x7e + num_bytes = 1 + cur_bank = self._read_eeprom(bank_offset, num_bytes)[0] + if cur_bank is None: + self._sfplog(LOG_ERROR_LEVEL, "CPO read BANK ERROR!") + return False + + if cur_bank == bank: + return True + + return self._write_eeprom(bank_offset, num_bytes, bytearray([bank])) + + def _convert_to_single_page_offset_read(self, offset, num_bytes): + page_list = [0, 1, 2, 16, 17, 19, 20, 159] # page 0 1 2 10h 11h 13h 14h 9Fh + for p in page_list: + if (256 + (p - 1) * 128) <= offset < (256 + 128 * p): + self._switch_page(p) + single_page_offset = offset - 128 * p + + if p in [16, 17, 19, 20]: # need to switch Bank + port_id_abs = (self._port_id - 1) % 16 + bank_id = port_id_abs // 2 + self._switch_bank(bank_id) + + return self._read_eeprom(single_page_offset, num_bytes) + + self._sfplog(LOG_WARNING_LEVEL, "cannot find page! offset: %d num_bytes: %d" % (offset, num_bytes)) + return None + + def _convert_to_single_page_offset_write(self, offset, num_bytes, write_buffer): + page_list = [0, 1, 2, 16, 17, 19, 20, 159] # page 0 1 2 10h 11h 13h 14h 9Fh + for p in page_list: + if (256 + (p - 1) * 128) <= offset < (256 + 128 * p): + self._switch_page(p) + single_page_offset = offset - 128 * p + + if p in [16, 17, 19, 20]: # need to switch Bank + port_id_abs = (self._port_id - 1) % 16 + bank_id = port_id_abs // 2 + self._switch_bank(bank_id) + + return self._write_eeprom(single_page_offset, num_bytes, write_buffer) + + self._sfplog(LOG_WARNING_LEVEL, "cannot find page! offset: %d num_bytes: %d" % (offset, num_bytes)) + return None + + pidfile = None + + def _file_rw_lock(self): + global pidfile + pidfile = open(self._get_eeprom_path(), "r") + file_lock_flag = False + # Retry 100 times to lock file + for i in range(0, 100): + try: + fcntl.flock(pidfile, fcntl.LOCK_EX | fcntl.LOCK_NB) + file_lock_flag = True + self._sfplog(LOG_DEBUG_LEVEL, "file lock success") + return True + except Exception: + time.sleep(0.001) + continue + + if file_lock_flag == False: + if pidfile is not None: + pidfile.close() + pidfile = None + return False + + def _file_rw_unlock(self): + try: + global pidfile + if pidfile is not None: + fcntl.flock(pidfile, fcntl.LOCK_UN) + pidfile.close() + pidfile = None + self._sfplog(LOG_DEBUG_LEVEL, "file unlock success") + else: + self._sfplog(LOG_DEBUG_LEVEL, "pidfile is invalid, do nothing") + return True + except Exception as e: + self._sfplog(LOG_ERROR_LEVEL, "file unlock err, msg:%s" % (str(e))) + return False \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/watchdog.py b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/watchdog.py index 948337f47a9a..1326d1671e6f 100644 --- a/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/watchdog.py +++ b/platform/broadcom/sonic-platform-modules-micas/common/sonic_platform/watchdog.py @@ -1,12 +1,19 @@ #!/usr/bin/env python3 - -######################################################################## # +# Copyright (C) 2024 Micas 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. # -# Abstract base class for implementing a platform-specific class with -# which to interact with a hardware watchdog module in SONiC +# 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 fcntl import os diff --git a/platform/broadcom/sonic-platform-modules-micas/debian/control b/platform/broadcom/sonic-platform-modules-micas/debian/control index 8a4fbd115814..819647fdbfc3 100644 --- a/platform/broadcom/sonic-platform-modules-micas/debian/control +++ b/platform/broadcom/sonic-platform-modules-micas/debian/control @@ -10,4 +10,8 @@ Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-micas-m2-w6510-48gt4v Architecture: amd64 -Description: kernel modules for platform devices such as fan, led, sfp \ No newline at end of file +Description: kernel modules for platform devices such as fan, led, sfp + +Package: platform-modules-micas-m2-w6520-24dc8qc +Architecture: amd64 +Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-micas/debian/platform-modules-micas-m2-w6520-24dc8qc.install b/platform/broadcom/sonic-platform-modules-micas/debian/platform-modules-micas-m2-w6520-24dc8qc.install new file mode 100644 index 000000000000..3a94db8f4428 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/debian/platform-modules-micas-m2-w6520-24dc8qc.install @@ -0,0 +1 @@ +m2-w6520-24dc8qc/modules/sonic_platform-1.0-py3-none-any.whl /usr/share/sonic/device/x86_64-micas_m2-w6520-24dc8qc-r0 diff --git a/platform/broadcom/sonic-platform-modules-micas/debian/platform-modules-micas-m2-w6520-24dc8qc.postinst b/platform/broadcom/sonic-platform-modules-micas/debian/platform-modules-micas-m2-w6520-24dc8qc.postinst new file mode 100644 index 000000000000..a8132f4f65a9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/debian/platform-modules-micas-m2-w6520-24dc8qc.postinst @@ -0,0 +1,10 @@ +#!/bin/sh +# postinst + +kernel_version=$(uname -r) + +if [ -e /boot/System.map-${kernel_version} ]; then + depmod -a -F /boot/System.map-${kernel_version} ${kernel_version} || true +fi + +#DEBHELPER# diff --git a/platform/broadcom/sonic-platform-modules-micas/debian/rule.mk b/platform/broadcom/sonic-platform-modules-micas/debian/rule.mk index b6b2cd492660..4ed55c469bc7 100644 --- a/platform/broadcom/sonic-platform-modules-micas/debian/rule.mk +++ b/platform/broadcom/sonic-platform-modules-micas/debian/rule.mk @@ -2,5 +2,6 @@ currentdir = $(shell pwd) MODULE_DIRS := m2-w6510-48v8c MODULE_DIRS += m2-w6510-48gt4v +MODULE_DIRS += m2-w6520-24dc8qc export MODULE_DIRS diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/Makefile b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/Makefile new file mode 100644 index 000000000000..052a5a6a0773 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/Makefile @@ -0,0 +1,25 @@ +PWD = $(shell pwd) +DIR_KERNEL_SRC = $(PWD)/modules/driver +EXTRA_CFLAGS:= -I$(M)/include +EXTRA_CFLAGS+= -Wall +SUB_BUILD_DIR = $(PWD)/build +INSTALL_DIR = $(SUB_BUILD_DIR)/$(KERNEL_SRC)/$(INSTALL_MOD_DIR) +INSTALL_SCRIPT_DIR = $(SUB_BUILD_DIR)/usr/local/bin +INSTALL_LIB_DIR = $(SUB_BUILD_DIR)/usr/lib/python3/dist-packages +INSTALL_SYSFS_CFG_DIR = $(SUB_BUILD_DIR)/etc/plat_sysfs_cfg + +all: + $(MAKE) -C $(KBUILD_OUTPUT) M=$(DIR_KERNEL_SRC) modules + @if [ ! -d ${INSTALL_DIR} ]; then mkdir -p ${INSTALL_DIR} ;fi + cp -r $(DIR_KERNEL_SRC)/*.ko $(INSTALL_DIR) + @if [ ! -d ${INSTALL_SCRIPT_DIR} ]; then mkdir -p ${INSTALL_SCRIPT_DIR} ;fi + cp -r $(PWD)/config/* $(INSTALL_SCRIPT_DIR) + @if [ ! -d ${INSTALL_LIB_DIR} ]; then mkdir -p ${INSTALL_LIB_DIR} ;fi + @if [ -d $(PWD)/hal-config/ ]; then cp -r $(PWD)/hal-config/* ${INSTALL_LIB_DIR} ;fi + @if [ ! -d ${INSTALL_SYSFS_CFG_DIR} ]; then mkdir -p ${INSTALL_SYSFS_CFG_DIR} ;fi + @if [ -d $(PWD)/plat_sysfs_cfg/ ]; then cp -r $(PWD)/plat_sysfs_cfg/* ${INSTALL_SYSFS_CFG_DIR} ;fi +clean: + rm -f ${DIR_KERNEL_SRC}/*.o ${DIR_KERNEL_SRC}/*.ko ${DIR_KERNEL_SRC}/*.mod.c ${DIR_KERNEL_SRC}/.*.cmd + rm -f ${DIR_KERNEL_SRC}/Module.markers ${DIR_KERNEL_SRC}/Module.symvers ${DIR_KERNEL_SRC}/modules.order + rm -rf ${DIR_KERNEL_SRC}/.tmp_versions + rm -rf $(SUB_BUILD_DIR) diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/config/x86_64_micas_m2_w6520_24dc8qc_r0_config.py b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/config/x86_64_micas_m2_w6520_24dc8qc_r0_config.py new file mode 100644 index 000000000000..6cbadc907a0d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/config/x86_64_micas_m2_w6520_24dc8qc_r0_config.py @@ -0,0 +1,1424 @@ +#!/usr/bin/python +# -*- coding: UTF-8 -*- +from platform_common import * + +STARTMODULE = { + "hal_fanctrl": 1, + "hal_ledctrl": 1, + "avscontrol": 0, + "dev_monitor": 1, + "tty_console": 1, + "reboot_cause": 1, + "pmon_syslog": 1, + "sff_temp_polling": 1, + "generate_airflow": 0, +} + +DEV_MONITOR_PARAM = { + "polling_time": 10, + "psus": [ + { + "name": "psu1", + "present": {"gettype": "i2c", "bus": 2, "loc": 0x1d, "offset": 0x34, "presentbit": 0, "okval": 0}, + "device": [ + {"id": "psu1pmbus", "name": "wb_fsp1200", "bus": 41, "loc": 0x58, "attr": "hwmon"}, + {"id": "psu1frue2", "name": "24c02", "bus": 41, "loc": 0x50, "attr": "eeprom"}, + ], + }, + { + "name": "psu2", + "present": {"gettype": "i2c", "bus": 2, "loc": 0x1d, "offset": 0x34, "presentbit": 4, "okval": 0}, + "device": [ + {"id": "psu2pmbus", "name": "wb_fsp1200", "bus": 42, "loc": 0x58, "attr": "hwmon"}, + {"id": "psu2frue2", "name": "24c02", "bus": 42, "loc": 0x50, "attr": "eeprom"}, + ], + }, + ], + "fans": [ + { + "name": "fan1", + "present": {"gettype": "i2c", "bus": 4, "loc": 0x3d, "offset": 0x37, "presentbit": 5, "okval": 0}, + "device": [ + {"id": "fan1frue2", "name": "24c64", "bus": 35, "loc": 0x50, "attr": "eeprom"}, + ], + }, + { + "name": "fan2", + "present": {"gettype": "i2c", "bus": 4, "loc": 0x3d, "offset": 0x37, "presentbit": 4, "okval": 0}, + "device": [ + {"id": "fan2frue2", "name": "24c64", "bus": 34, "loc": 0x50, "attr": "eeprom"}, + ], + }, + { + "name": "fan3", + "present": {"gettype": "i2c", "bus": 4, "loc": 0x3d, "offset": 0x37, "presentbit": 3, "okval": 0}, + "device": [ + {"id": "fan3frue2", "name": "24c64", "bus": 33, "loc": 0x50, "attr": "eeprom"}, + ], + }, + { + "name": "fan4", + "present": {"gettype": "i2c", "bus": 4, "loc": 0x3d, "offset": 0x37, "presentbit": 2, "okval": 0}, + "device": [ + {"id": "fan4frue2", "name": "24c64", "bus":32, "loc": 0x50, "attr": "eeprom"}, + ], + }, + { + "name": "fan5", + "present": {"gettype": "i2c", "bus": 4, "loc": 0x3d, "offset": 0x37, "presentbit": 1, "okval": 0}, + "device": [ + {"id": "fan5frue2", "name": "24c64", "bus": 31, "loc": 0x50, "attr": "eeprom"}, + ], + }, + { + "name": "fan6", + "present": {"gettype": "i2c", "bus": 4, "loc": 0x3d, "offset": 0x37, "presentbit": 0, "okval": 0}, + "device": [ + {"id": "fan6frue2", "name": "24c64", "bus": 30, "loc": 0x50, "attr": "eeprom"}, + ], + }, + ], + "others": [ + { + "name": "eeprom", + "device": [ + {"id": "eeprom_1", "name": "24c02", "bus": 1, "loc": 0x56, "attr": "eeprom"}, + ], + }, + { + "name": "lm75", + "device": [ + {"id": "lm75_1", "name": "lm75", "bus": 36, "loc": 0x48, "attr": "hwmon"}, + {"id": "lm75_2", "name": "lm75", "bus": 36, "loc": 0x49, "attr": "hwmon"}, + {"id": "lm75_3", "name": "lm75", "bus": 39, "loc": 0x4b, "attr": "hwmon"}, + {"id": "lm75_4", "name": "lm75", "bus": 40, "loc": 0x4e, "attr": "hwmon"}, + {"id": "lm75_5", "name": "lm75", "bus": 40, "loc": 0x4f, "attr": "hwmon"}, + ], + }, + { + "name": "mac_bsc", + "device": [ + {"id": "mac_bsc_1", "name": "wb_mac_bsc_td4", "bus": 44, "loc": 0x44, "attr": "hwmon"}, + ], + }, + { + "name":"tmp411", + "device":[ + {"id":"tmp411_1", "name":"tmp411","bus":39, "loc":0x4c, "attr":"hwmon"}, + {"id":"tmp411_2", "name":"tmp411","bus":40, "loc":0x4c, "attr":"hwmon"}, + ], + }, + { + "name": "ina3221", + "device": [ + {"id": "ina3221_1", "name": "ina3221", "bus": 25, "loc": 0x43, "attr": "hwmon"}, + ], + }, + { + "name": "tps53622", + "device": [ + {"id": "tps53622_1", "name": "tps53688", "bus": 25, "loc": 0x67, "attr": "hwmon"}, + {"id": "tps53622_2", "name": "tps53688", "bus": 25, "loc": 0x6c, "attr": "hwmon"}, + ], + }, + { + "name": "ucd90160", + "device": [ + {"id": "ucd90160_1", "name": "ucd90160", "bus": 24, "loc": 0x5b, "attr": "hwmon"}, + {"id": "ucd90160_2", "name": "ucd90160", "bus": 45, "loc": 0x5b, "attr": "hwmon"}, + ], + }, + ], +} + +MANUINFO_CONF = { + "bios": { + "key": "BIOS", + "head": True, + "next": "onie" + }, + "bios_vendor": { + "parent": "bios", + "key": "Vendor", + "cmd": "dmidecode -t 0 |grep Vendor", + "pattern": r".*Vendor", + "separator": ":", + "arrt_index": 1, + }, + "bios_version": { + "parent": "bios", + "key": "Version", + "cmd": "dmidecode -t 0 |grep Version", + "pattern": r".*Version", + "separator": ":", + "arrt_index": 2, + }, + "bios_date": { + "parent": "bios", + "key": "Release Date", + "cmd": "dmidecode -t 0 |grep Release", + "pattern": r".*Release Date", + "separator": ":", + "arrt_index": 3, + }, + "onie": { + "key": "ONIE", + "next": "cpu" + }, + "onie_date": { + "parent": "onie", + "key": "Build Date", + "file": "/host/machine.conf", + "pattern": r"^onie_build_date", + "separator": "=", + "arrt_index": 1, + }, + "onie_version": { + "parent": "onie", + "key": "Version", + "file": "/host/machine.conf", + "pattern": r"^onie_version", + "separator": "=", + "arrt_index": 2, + }, + + "cpu": { + "key": "CPU", + "next": "ssd" + }, + "cpu_vendor": { + "parent": "cpu", + "key": "Vendor", + "cmd": "dmidecode --type processor |grep Manufacturer", + "pattern": r".*Manufacturer", + "separator": ":", + "arrt_index": 1, + }, + "cpu_model": { + "parent": "cpu", + "key": "Device Model", + "cmd": "dmidecode --type processor | grep Version", + "pattern": r".*Version", + "separator": ":", + "arrt_index": 2, + }, + "cpu_core": { + "parent": "cpu", + "key": "Core Count", + "cmd": "dmidecode --type processor | grep \"Core Count\"", + "pattern": r".*Core Count", + "separator": ":", + "arrt_index": 3, + }, + "cpu_thread": { + "parent": "cpu", + "key": "Thread Count", + "cmd": "dmidecode --type processor | grep \"Thread Count\"", + "pattern": r".*Thread Count", + "separator": ":", + "arrt_index": 4, + }, + "ssd": { + "key": "SSD", + "next": "cpld" + }, + "ssd_model": { + "parent": "ssd", + "key": "Device Model", + "cmd": "smartctl -i /dev/sda |grep \"Device Model\"", + "pattern": r".*Device Model", + "separator": ":", + "arrt_index": 1, + }, + "ssd_fw": { + "parent": "ssd", + "key": "Firmware Version", + "cmd": "smartctl -i /dev/sda |grep \"Firmware Version\"", + "pattern": r".*Firmware Version", + "separator": ":", + "arrt_index": 2, + }, + "ssd_user_cap": { + "parent": "ssd", + "key": "User Capacity", + "cmd": "smartctl -i /dev/sda |grep \"User Capacity\"", + "pattern": r".*User Capacity", + "separator": ":", + "arrt_index": 3, + }, + + "cpld": { + "key": "CPLD", + "next": "psu" + }, + + "cpld1": { + "key": "CPLD1", + "parent": "cpld", + "arrt_index": 1, + }, + "cpld1_model": { + "key": "Device Model", + "parent": "cpld1", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld1_vender": { + "key": "Vendor", + "parent": "cpld1", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld1_desc": { + "key": "Description", + "parent": "cpld1", + "config": "CPU_CPLD", + "arrt_index": 3, + }, + "cpld1_version": { + "key": "Firmware Version", + "parent": "cpld1", + "reg": { + "loc": "/dev/port", + "offset": 0x700, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + + "cpld2": { + "key": "CPLD2", + "parent": "cpld", + "arrt_index": 2, + }, + "cpld2_model": { + "key": "Device Model", + "parent": "cpld2", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld2_vender": { + "key": "Vendor", + "parent": "cpld2", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld2_desc": { + "key": "Description", + "parent": "cpld2", + "config": "CONNECT_CPLD", + "arrt_index": 3, + }, + "cpld2_version": { + "key": "Firmware Version", + "parent": "cpld2", + "reg": { + "loc": "/dev/port", + "offset": 0x900, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + + "cpld3": { + "key": "CPLD3", + "parent": "cpld", + "arrt_index": 3, + }, + "cpld3_model": { + "key": "Device Model", + "parent": "cpld3", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld3_vender": { + "key": "Vendor", + "parent": "cpld3", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld3_desc": { + "key": "Description", + "parent": "cpld3", + "config": "MAC_CPLDA", + "arrt_index": 3, + }, + "cpld3_version": { + "key": "Firmware Version", + "parent": "cpld3", + "i2c": { + "bus": "2", + "loc": "0x1d", + "offset": 0, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + + "cpld4": { + "key": "CPLD4", + "parent": "cpld", + "arrt_index": 4, + }, + "cpld4_model": { + "key": "Device Model", + "parent": "cpld4", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld4_vender": { + "key": "Vendor", + "parent": "cpld4", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld4_desc": { + "key": "Description", + "parent": "cpld4", + "config": "MAC_CPLDB", + "arrt_index": 3, + }, + "cpld4_version": { + "key": "Firmware Version", + "parent": "cpld4", + "i2c": { + "bus": "2", + "loc": "0x2d", + "offset": 0, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + + "cpld5": { + "key": "CPLD5", + "parent": "cpld", + "arrt_index": 5, + }, + "cpld5_model": { + "key": "Device Model", + "parent": "cpld5", + "config": "LCMXO3LF-2100C-5BG256C", + "arrt_index": 1, + }, + "cpld5_vender": { + "key": "Vendor", + "parent": "cpld5", + "config": "LATTICE", + "arrt_index": 2, + }, + "cpld5_desc": { + "key": "Description", + "parent": "cpld5", + "config": "FAN_CPLD", + "arrt_index": 3, + }, + "cpld5_version": { + "key": "Firmware Version", + "parent": "cpld5", + "i2c": { + "bus": "4", + "loc": "0x3d", + "offset": 0, + "size": 4 + }, + "callback": "cpld_format", + "arrt_index": 4, + }, + + "psu": { + "key": "PSU", + "next": "fan" + }, + + "psu1": { + "parent": "psu", + "key": "PSU1", + "arrt_index": 1, + }, + "psu1_hw_version": { + "key": "Hardware Version", + "parent": "psu1", + "extra": { + "funcname": "getPsu", + "id": "psu1", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "psu1_fw_version": { + "key": "Firmware Version", + "parent": "psu1", + "config": "NA", + "arrt_index": 2, + }, + + "psu2": { + "parent": "psu", + "key": "PSU2", + "arrt_index": 2, + }, + "psu2_hw_version": { + "key": "Hardware Version", + "parent": "psu2", + "extra": { + "funcname": "getPsu", + "id": "psu2", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "psu2_fw_version": { + "key": "Firmware Version", + "parent": "psu2", + "config": "NA", + "arrt_index": 2, + }, + + "fan": { + "key": "FAN", + "next": "i210" + }, + + "fan1": { + "key": "FAN1", + "parent": "fan", + "arrt_index": 1, + }, + "fan1_hw_version": { + "key": "Hardware Version", + "parent": "fan1", + "extra": { + "funcname": "checkFan", + "id": "fan1", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan1_fw_version": { + "key": "Firmware Version", + "parent": "fan1", + "config": "NA", + "arrt_index": 2, + }, + + "fan2": { + "key": "FAN2", + "parent": "fan", + "arrt_index": 2, + }, + "fan2_hw_version": { + "key": "Hardware Version", + "parent": "fan2", + "extra": { + "funcname": "checkFan", + "id": "fan2", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan2_fw_version": { + "key": "Firmware Version", + "parent": "fan2", + "config": "NA", + "arrt_index": 2, + }, + + "fan3": { + "key": "FAN3", + "parent": "fan", + "arrt_index": 3, + }, + "fan3_hw_version": { + "key": "Hardware Version", + "parent": "fan3", + "extra": { + "funcname": "checkFan", + "id": "fan3", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan3_fw_version": { + "key": "Firmware Version", + "parent": "fan3", + "config": "NA", + "arrt_index": 2, + }, + + "fan4": { + "key": "FAN4", + "parent": "fan", + "arrt_index": 4, + }, + "fan4_hw_version": { + "key": "Hardware Version", + "parent": "fan4", + "extra": { + "funcname": "checkFan", + "id": "fan4", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan4_fw_version": { + "key": "Firmware Version", + "parent": "fan4", + "config": "NA", + "arrt_index": 2, + }, + + "fan5": { + "key": "FAN5", + "parent": "fan", + "arrt_index": 5, + }, + "fan5_hw_version": { + "key": "Hardware Version", + "parent": "fan5", + "extra": { + "funcname": "checkFan", + "id": "fan5", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan5_fw_version": { + "key": "Firmware Version", + "parent": "fan5", + "config": "NA", + "arrt_index": 2, + }, + + "fan6": { + "key": "FAN6", + "parent": "fan", + "arrt_index": 6, + }, + "fan6_hw_version": { + "key": "Hardware Version", + "parent": "fan6", + "extra": { + "funcname": "checkFan", + "id": "fan6", + "key": "hw_version" + }, + "arrt_index": 1, + }, + "fan6_fw_version": { + "key": "Firmware Version", + "parent": "fan6", + "config": "NA", + "arrt_index": 2, + }, + + "i210": { + "key": "NIC", + "next": "fpga" + }, + "i210_model": { + "parent": "i210", + "config": "NA", + "key": "Device Model", + "arrt_index": 1, + }, + "i210_vendor": { + "parent": "i210", + "config": "INTEL", + "key": "Vendor", + "arrt_index": 2, + }, + "i210_version": { + "parent": "i210", + "cmd": "ethtool -i eth0", + "pattern": r"firmware-version", + "separator": ":", + "key": "Firmware Version", + "arrt_index": 3, + }, + + "fpga": { + "key": "FPGA", + }, + "fpga_model": { + "parent": "fpga", + "config": "XC7A100T-2FGG484C", + "key": "Device Model", + "arrt_index": 1, + }, + "fpga_vendor": { + "parent": "fpga", + "config": "XILINX", + "key": "Vendor", + "arrt_index": 2, + }, + "fpga_desc": { + "parent": "fpga", + "config": "NA", + "key": "Description", + "arrt_index": 3, + }, + "fpga_hw_version": { + "parent": "fpga", + "config": "NA", + "key": "Hardware Version", + "arrt_index": 4, + }, + "fpga_fw_version": { + "parent": "fpga", + "pci": { + "bus": 8, + "slot": 0, + "fn": 0, + "bar": 0, + "offset": 0 + }, + "key": "Firmware Version", + "arrt_index": 5, + }, + "fpga_date": { + "parent": "fpga", + "pci": { + "bus": 8, + "slot": 0, + "fn": 0, + "bar": 0, + "offset": 4 + }, + "key": "Build Date", + "arrt_index": 6, + }, + "others": { + "key": "OTHERS", + }, + "5387": { + "parent": "others", + "key": "CPU-BMC-SWITCH", + "arrt_index": 1, + }, + "5387_model": { + "parent": "5387", + "config": "BCM5387", + "key": "Device Model", + "arrt_index": 1, + }, + "5387_vendor": { + "parent": "5387", + "config": "Broadcom", + "key": "Vendor", + "arrt_index": 2, + }, + "5387_hw_version": { + "parent": "5387", + "key": "Hardware Version", + "func": { + "funcname": "get_bcm5387_version", + "params": { + "before": [ + {"gettype": "io", "io_addr": 0x94d, "value": 0xfe}, # enable 5387 + {"gettype": "cmd", "cmd": "modprobe wb_spi_gpio"}, + {"gettype": "cmd", "cmd": "modprobe wb_spi_gpio_device sck=67 miso=32 mosi=65 bus=0"}, + {"gettype": "cmd", "cmd": "modprobe wb_spi_93xx46 spi_bus_num=0 spi_cs_gpio=6"}, + ], + "get_version": "md5sum /sys/bus/spi/devices/spi0.0/eeprom | awk '{print $1}'", + "after": [], + "finally": [ + {"gettype": "cmd", "cmd": "rmmod wb_spi_93xx46"}, + {"gettype": "cmd", "cmd": "rmmod wb_spi_gpio_device"}, + {"gettype": "cmd", "cmd": "rmmod wb_spi_gpio"}, + {"gettype": "io", "io_addr": 0x94d, "value": 0xff}, # disable 5387 + ], + }, + }, + "arrt_index": 3, + }, +} + +PMON_SYSLOG_STATUS = { + "polling_time": 3, + "sffs": { + "present": {"path": ["/sys/wb_plat/sff/*/present"], "ABSENT": 0}, + "nochangedmsgflag": 0, + "nochangedmsgtime": 60, + "noprintfirsttimeflag": 1, + "alias": { + "sff1": "Ethernet1", + "sff2": "Ethernet2", + "sff3": "Ethernet3", + "sff4": "Ethernet4", + "sff5": "Ethernet5", + "sff6": "Ethernet6", + "sff7": "Ethernet7", + "sff8": "Ethernet8", + "sff9": "Ethernet9", + "sff10": "Ethernet10", + "sff11": "Ethernet11", + "sff12": "Ethernet12", + "sff13": "Ethernet13", + "sff14": "Ethernet14", + "sff15": "Ethernet15", + "sff16": "Ethernet16", + "sff17": "Ethernet17", + "sff18": "Ethernet18", + "sff19": "Ethernet19", + "sff20": "Ethernet20", + "sff21": "Ethernet21", + "sff22": "Ethernet22", + "sff23": "Ethernet23", + "sff24": "Ethernet24", + "sff25": "Ethernet25", + "sff26": "Ethernet26", + "sff27": "Ethernet27", + "sff28": "Ethernet28", + "sff29": "Ethernet29", + "sff30": "Ethernet30", + "sff31": "Ethernet31", + "sff32": "Ethernet32", + } + }, + "fans": { + "present": {"path": ["/sys/wb_plat/fan/*/present"], "ABSENT": 0}, + "status": [ + {"path": "/sys/wb_plat/fan/%s/motor0/status", 'okval': 1}, + {"path": "/sys/wb_plat/fan/%s/motor1/status", 'okval': 1}, + ], + "nochangedmsgflag": 1, + "nochangedmsgtime": 60, + "noprintfirsttimeflag": 0, + "alias": { + "fan1": "FAN1", + "fan2": "FAN2", + "fan3": "FAN3", + "fan4": "FAN4", + "fan5": "FAN5", + "fan6": "FAN6" + } + }, + "psus": { + "present": {"path": ["/sys/wb_plat/psu/*/present"], "ABSENT": 0}, + "status": [ + {"path": "/sys/wb_plat/psu/%s/output", "okval": 1}, + {"path": "/sys/wb_plat/psu/%s/alert", "okval": 0}, + ], + "nochangedmsgflag": 1, + "nochangedmsgtime": 60, + "noprintfirsttimeflag": 0, + "alias": { + "psu1": "PSU1", + "psu2": "PSU2" + } + } +} + +##################### MAC Voltage adjust#################################### +MAC_DEFAULT_PARAM = [ + { + "name": "mac_core", # AVS name + "type": 1, # 1: used default value, if rov value not in range. 0: do nothing, if rov value not in range + "default": 0x82, # default value, if rov value not in range + "sdkreg": "TOP_AVS_SEL_REG", # SDK register name + "sdktype": 0, # 0: No shift operation required, 1: shift operation required + "macregloc": 24, # Shift right 24 bits + "mask": 0xff, # Use with macregloc + "rov_source": 0, # 0: get rov value from cpld, 1: get rov value from SDK + "cpld_avs": {"bus":2, "loc":0x2d, "offset":0x3f, "gettype":"i2c"}, + "set_avs": { + "loc": "/sys/bus/i2c/devices/43-005b/avs_vout", + "gettype": "sysfs", "formula": "int((%f)*1000000)" + }, + "mac_avs_param": { + 0x72:0.90000, + 0x73:0.89375, + 0x74:0.88750, + 0x75:0.88125, + 0x76:0.87500, + 0x77:0.86875, + 0x78:0.86250, + 0x79:0.85625, + 0x7a:0.85000, + 0x7b:0.84375, + 0x7c:0.83750, + 0x7d:0.83125, + 0x7e:0.82500, + 0x7f:0.81875, + 0x80:0.81250, + 0x81:0.80625, + 0x82:0.80000, + 0x83:0.79375, + 0x84:0.78750, + 0x85:0.78125, + 0x86:0.77500, + 0x87:0.76875, + 0x88:0.76250, + 0x89:0.75625, + 0x8A:0.75000, + 0x8B:0.74375, + 0x8C:0.73750, + 0x8D:0.73125, + 0x8E:0.72500, + } + } +] + +BLACKLIST_DRIVERS = [ + {"name": "i2c_i801", "delay": 0}, +] + +DRIVERLISTS = [ + {"name": "i2c_i801", "delay": 1}, + {"name": "wb_gpio_d1500", "delay": 0}, + {"name": "i2c_dev", "delay": 0}, + {"name": "i2c_algo_bit", "delay": 0}, + {"name": "i2c_gpio", "delay": 0}, + {"name": "i2c_mux", "delay": 0}, + {"name": "wb_gpio_device", "delay": 0}, + {"name": "wb_i2c_gpio_device gpio_sda=17 gpio_scl=1 gpio_udelay=2", "delay": 0}, + {"name": "platform_common dfd_my_type=0x20000056", "delay": 0}, + {"name": "wb_fpga_pcie", "delay": 0}, + {"name": "wb_pcie_dev", "delay": 0}, + {"name": "wb_pcie_dev_device", "delay": 0}, + {"name": "wb_lpc_drv", "delay": 0}, + {"name": "wb_lpc_drv_device", "delay": 0}, + {"name": "wb_io_dev", "delay": 0}, + {"name": "wb_io_dev_device", "delay": 0}, + {"name": "wb_spi_dev", "delay": 0}, + {"name": "wb_i2c_dev", "delay": 0}, + {"name": "wb_fpga_i2c_bus_drv", "delay": 0}, + {"name": "wb_fpga_i2c_bus_device", "delay": 0}, + {"name": "wb_i2c_dev_device", "delay": 0}, + {"name": "wb_fpga_pca954x_drv", "delay": 0}, + {"name": "wb_fpga_pca954x_device", "delay": 0}, + {"name": "wb_wdt", "delay": 0}, + {"name": "lm75", "delay": 0}, + {"name": "tmp401", "delay": 0}, + {"name": "optoe", "delay": 0}, + {"name": "at24", "delay": 0}, + {"name": "wb_mac_bsc", "delay": 0}, + {"name": "pmbus_core", "delay": 0}, + {"name": "wb_csu550", "delay": 0}, + {"name": "ina3221", "delay": 0}, + {"name": "tps53679", "delay": 0}, + {"name": "ucd9000", "delay": 0}, + {"name": "wb_xdpe132g5c", "delay": 0}, + {"name": "plat_dfd", "delay": 0}, + {"name": "plat_switch", "delay": 0}, + {"name": "plat_fan", "delay": 0}, + {"name": "plat_psu", "delay": 0}, + {"name": "plat_sff", "delay": 0}, +] + +DEVICE = [ + {"name": "24c02", "bus": 1, "loc": 0x56}, + {"name": "wb_mac_bsc_td4", "bus": 44, "loc": 0x44}, + # fan + {"name": "24c64", "bus": 30, "loc": 0x50}, + {"name": "24c64", "bus": 31, "loc": 0x50}, + {"name": "24c64", "bus": 32, "loc": 0x50}, + {"name": "24c64", "bus": 33, "loc": 0x50}, + {"name": "24c64", "bus": 34, "loc": 0x50}, + {"name": "24c64", "bus": 35, "loc": 0x50}, + # psu + {"name": "24c02", "bus": 41, "loc": 0x50}, + {"name": "wb_fsp1200", "bus": 41, "loc": 0x58}, + {"name": "24c02", "bus": 42, "loc": 0x50}, + {"name": "wb_fsp1200", "bus": 42, "loc": 0x58}, + # temp + {"name": "lm75", "bus": 36, "loc": 0x48}, + {"name": "lm75", "bus": 36, "loc": 0x49}, + {"name": "lm75", "bus": 39, "loc": 0x4b}, + {"name": "tmp411", "bus": 39, "loc": 0x4c}, + {"name": "tmp411", "bus": 40, "loc": 0x4c}, + {"name": "lm75", "bus": 40, "loc": 0x4e}, + {"name": "lm75", "bus": 40, "loc": 0x4f}, + # dcdc + {"name": "ucd90160", "bus": 24, "loc": 0x5b}, + {"name": "ucd90160", "bus": 45, "loc": 0x5b}, + {"name": "ina3221", "bus": 25, "loc": 0x43}, + {"name": "tps53688", "bus": 25, "loc": 0x67}, + {"name": "tps53688", "bus": 25, "loc": 0x6c}, + #avs + {"name": "wb_xdpe132g5c", "bus": 43, "loc": 0x5b}, +] + +OPTOE = [ + {"name": "optoe1", "startbus": 46, "endbus": 69}, + {"name": "optoe3", "startbus": 70, "endbus": 77}, +] + +REBOOT_CTRL_PARAM = { + "cpu": {"io_addr": 0x920, "rst_val": 0xfe, "rst_delay": 0, "gettype": "io"}, + "mac": {"bus": 2, "loc": 0x1d, "offset": 0x20, "rst_val": 0xfd, "rst_delay": 0, "gettype": "i2c"}, + "phy": {"io_addr": 0x923, "rst_val": 0xef, "rst_delay": 1, "unlock_rst_val": 0xff, "unlock_rst_delay": 1, "gettype": "io"}, + "power": {"io_addr": 0x9ce, "rst_val": 0, "rst_delay": 0, "gettype": "io"}, +} + +# INIT_PARAM_PRE = [ +# {"loc": "43-005b/avs_vout_max", "value": "900000"}, +# {"loc": "43-005b/avs_vout_min", "value": "725000"}, +# ] + +INIT_PARAM = [] + +INIT_COMMAND_PRE = [ + # sfp power enable + "i2cset -f -y 2 0x2d 0x45 0xff", + "i2cset -f -y 2 0x2d 0x46 0xff", + "i2cset -f -y 2 0x2d 0x34 0xff", + "i2cset -f -y 2 0x2d 0x35 0xff", + "i2cset -f -y 2 0x1d 0x39 0xff", + "i2cset -f -y 2 0x1d 0x3a 0xff", + # enable tty_console monitor + "dfd_debug io_wr 0x956 0x01", +] + +INIT_COMMAND = [ + # led enable + "i2cset -f -y 2 0x2d 0x3a 0xff", + "i2cset -f -y 2 0x1d 0x3b 0xff", + + # port led off + "i2cset -f -y 2 0x2d 0x3b 0x0", + "i2cset -f -y 2 0x2d 0x3c 0x0", + "i2cset -f -y 2 0x2d 0x3d 0x0", + "i2cset -f -y 2 0x2d 0x3e 0x0", + "i2cset -f -y 2 0x1d 0x3c 0x0", + "i2cset -f -y 2 0x1d 0x3d 0x0", + "i2cset -f -y 2 0x1d 0x3e 0x0", + "i2cset -f -y 2 0x1d 0x3f 0x0", +] + +WARM_UPGRADE_PARAM = { + "slot0": { + "VME": { + "chain1": [ + {"name": "CPU_CPLD", + "refresh_file_judge_flag": 1, + "refresh_file": "/etc/.cpld_refresh/refresh_cpu_cpld_header.vme", + "init_cmd": [ + {"cmd": "echo 7 > /sys/class/gpio/export", "gettype": "cmd"}, + {"cmd": "echo high > /sys/class/gpio/gpio7/direction", "gettype": "cmd"}, + {"io_addr": 0x7cc, "value": 0, "gettype": "io"}, + ], + "rw_recover_reg": [ + {"io_addr": 0x705, "value": None, "gettype": "io"}, + {"io_addr": 0x713, "value": None, "gettype": "io"}, + {"io_addr": 0x715, "value": None, "gettype": "io"}, + {"io_addr": 0x721, "value": None, "gettype": "io"}, + {"io_addr": 0x722, "value": None, "gettype": "io"}, + {"io_addr": 0x772, "value": None, "gettype": "io"}, + {"io_addr": 0x774, "value": None, "gettype": "io"}, + {"io_addr": 0x776, "value": None, "gettype": "io"}, + {"io_addr": 0x778, "value": None, "gettype": "io"}, + {"io_addr": 0x77a, "value": None, "gettype": "io"}, + {"io_addr": 0x77c, "value": None, "gettype": "io"}, + {"io_addr": 0x780, "value": None, "gettype": "io"}, + ], + "after_upgrade_delay": 1, + "after_upgrade_delay_timeout": 30, + "access_check_reg": {"io_addr": 0x705, "value": 0x5a, "gettype": "io"}, + "finish_cmd": [ + {"io_addr": 0x7cc, "value": 0xff, "gettype": "io"}, + {"cmd": "echo 0 > /sys/class/gpio/gpio7/value", "gettype": "cmd"}, + {"cmd": "echo 7 > /sys/class/gpio/unexport", "gettype": "cmd"}, + ], + }, + {"name": "CONNECT_CPLD", + "refresh_file_judge_flag": 1, + "refresh_file": "/etc/.cpld_refresh/refresh_base_cpld_header.vme", + "init_cmd": [ + {"bus": 2, "loc": 0x2d, "offset": 0xcd, "value": 1, "gettype": "i2c"}, + {"io_addr": 0x9cc, "value": 0, "gettype": "io"}, + ], + "rw_recover_reg": [ + {"io_addr": 0x9aa, "value": None, "gettype": "io"}, + {"io_addr": 0x955, "value": None, "gettype": "io"}, + {"io_addr": 0x911, "value": None, "gettype": "io"}, + {"io_addr": 0x923, "value": None, "gettype": "io"}, + {"io_addr": 0x924, "value": None, "gettype": "io"}, + {"io_addr": 0x930, "value": None, "gettype": "io"}, + {"io_addr": 0x932, "value": None, "gettype": "io"}, + {"io_addr": 0x933, "value": None, "gettype": "io"}, + {"io_addr": 0x934, "value": None, "gettype": "io"}, + {"io_addr": 0x937, "value": None, "gettype": "io"}, + {"io_addr": 0x938, "value": None, "gettype": "io"}, + {"io_addr": 0x939, "value": None, "gettype": "io"}, + {"io_addr": 0x93a, "value": None, "gettype": "io"}, + {"io_addr": 0x941, "value": None, "gettype": "io"}, + {"io_addr": 0x942, "value": None, "gettype": "io"}, + {"io_addr": 0x947, "value": None, "gettype": "io"}, + {"io_addr": 0x948, "value": None, "gettype": "io"}, + {"io_addr": 0x949, "value": None, "gettype": "io"}, + {"io_addr": 0x94d, "value": None, "gettype": "io"}, + {"io_addr": 0x94e, "value": None, "gettype": "io"}, + {"io_addr": 0x94f, "value": None, "gettype": "io"}, + {"io_addr": 0x950, "value": None, "gettype": "io"}, + {"io_addr": 0x951, "value": None, "gettype": "io"}, + {"io_addr": 0x952, "value": None, "gettype": "io"}, + {"io_addr": 0x953, "value": None, "gettype": "io"}, + ], + "after_upgrade_delay": 30, + "after_upgrade_delay_timeout": 60, + "refresh_finish_flag_check": {"io_addr": 0x9cb, "value": 0x5a, "gettype": "io"}, + "access_check_reg": {"io_addr": 0x9aa, "value": 0x5a, "gettype": "io"}, + "finish_cmd": [ + {"bus": 2, "loc": 0x2d, "offset": 0xcd, "value": 0, "gettype": "i2c"}, + ], + }, + + {"name": "MACA_CPLD", + "refresh_file_judge_flag": 1, + "refresh_file": "/etc/.cpld_refresh/refresh_maca_cpld_header.vme", + "init_cmd": [ + {"cmd": "touch /etc/sonic/.warm_upg_flag", "gettype": "cmd"}, + {"cmd": "sync", "gettype": "cmd"}, + {"path": "/dev/fpga0", "offset": 0xb4, "value": [0x1], "gettype":"devfile", "delay":0.1}, + {"bus": 2, "loc": 0x1d, "offset": 0xcc, "value": 0, "gettype": "i2c"}, + ], + "rw_recover_reg": [ + {"bus": 2, "loc": 0x1d, "offset": 0xaa, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x55, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x11, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x14, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x15, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x1a, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x1b, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x1c, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x1d, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x1f, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x21, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x22, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x35, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x36, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x37, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x38, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x39, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x3a, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x3b, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x3c, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x3d, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x3e, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x3f, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x40, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x41, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x42, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x1d, "offset": 0x44, "value": None, "gettype": "i2c"}, + ], + "after_upgrade_delay": 1, + "after_upgrade_delay_timeout": 30, + "refresh_finish_flag_check": {"bus": 2, "loc": 0x1d, "offset": 0xcb, "value": 0x5a, "gettype": "i2c"}, + "access_check_reg": {"bus": 2, "loc": 0x1d, "offset": 0xaa, "value": 0x5a, "gettype": "i2c"}, + "finish_cmd": [ + {"path": "/dev/fpga0", "offset": 0xb4, "value": [0x0], "gettype":"devfile"}, + {"cmd": "rm -rf /etc/sonic/.warm_upg_flag", "gettype": "cmd"}, + {"cmd": "sync", "gettype": "cmd"}, + ], + }, + + {"name": "MACB_CPLD", + "refresh_file_judge_flag": 1, + "refresh_file": "/etc/.cpld_refresh/refresh_macb_cpld_header.vme", + "init_cmd": [ + {"cmd": "touch /etc/sonic/.warm_upg_flag", "gettype": "cmd"}, + {"cmd": "sync", "gettype": "cmd"}, + {"path": "/dev/fpga0", "offset": 0xb0, "value": [0x1], "gettype":"devfile", "delay":0.1}, + {"bus": 2, "loc": 0x2d, "offset": 0xcc, "value": 0, "gettype": "i2c"}, + ], + "rw_recover_reg": [ + {"bus": 2, "loc": 0x2d, "offset": 0xaa, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x55, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x11, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x14, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x15, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x1a, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x1b, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x1c, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x1d, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x1f, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x21, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x22, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x23, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x30, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x31, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x32, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x33, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x34, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x35, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x3a, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x3b, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x3c, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x3d, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x3e, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x40, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x42, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x43, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x44, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x45, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x46, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x4c, "value": None, "gettype": "i2c"}, + {"bus": 2, "loc": 0x2d, "offset": 0x4d, "value": None, "gettype": "i2c"}, + ], + "after_upgrade_delay": 1, + "after_upgrade_delay_timeout": 30, + "refresh_finish_flag_check": {"bus": 2, "loc": 0x2d, "offset": 0xcb, "value": 0x5a, "gettype": "i2c"}, + "access_check_reg": {"bus": 2, "loc": 0x2d, "offset": 0xaa, "value": 0x5a, "gettype": "i2c"}, + "finish_cmd": [ + {"path": "/dev/fpga0", "offset": 0xb0, "value": [0x0], "gettype":"devfile"}, + {"cmd": "rm -rf /etc/sonic/.warm_upg_flag", "gettype": "cmd"}, + {"cmd": "sync", "gettype": "cmd"}, + ], + }, + + {"name": "FAN_CPLD", + "refresh_file_judge_flag": 1, + "refresh_file": "/etc/.cpld_refresh/refresh_fan_cpld_header.vme", + "rw_recover_reg": [ + {"bus": 4, "loc": 0x3d, "offset": 0xaa, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x55, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x11, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x13, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x15, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x17, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x19, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x30, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x31, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x33, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x35, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x3a, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x3c, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x3d, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x3e, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x3f, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x40, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x41, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x60, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x61, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x62, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x63, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x64, "value": None, "gettype": "i2c"}, + {"bus": 4, "loc": 0x3d, "offset": 0x65, "value": None, "gettype": "i2c"}, + ], + "after_upgrade_delay": 1, + "after_upgrade_delay_timeout": 30, + "access_check_reg": {"bus": 4, "loc": 0x3d, "offset": 0xaa, "value": 0x5a, "gettype": "i2c"}, + }, + ], + }, + + "SPI-LOGIC-DEV": { + "chain1": [ + {"name": "FPGA", + "init_cmd": [ + {"file": WARM_UPG_FLAG, "gettype": "creat_file"}, + {"cmd": "setpci -s 00:03.2 0xA0.W=0x0050", "gettype": "cmd"}, # link_disable + {"io_addr": 0x9cd, "value": 0, "gettype": "io"}, + ], + "after_upgrade_delay": 10, + "after_upgrade_delay_timeout": 180, + "refresh_finish_flag_check": {"io_addr": 0x9cd, "value": 0xff, "gettype": "io"}, + "access_check_reg": { + "path": "/dev/fpga0", "offset": 0x8, "value": [0x55, 0xaa, 0x5a, 0xa5], "read_len":4, "gettype":"devfile", + "polling_cmd":[ + {"cmd": "setpci -s 00:03.2 0xA0.W=0x0060", "gettype": "cmd"},# retrain_link + {"cmd": "rmmod wb_fpga_pcie", "gettype": "cmd"}, + {"cmd": "modprobe wb_fpga_pcie", "gettype": "cmd", "delay": 0.1}, + ], + "polling_delay": 0.1 + }, + "finish_cmd": [ + {"cmd": "setpci -s 00:03.2 0xA0.W=0x0060", "gettype": "cmd"},# retrain_link + {"file": WARM_UPG_FLAG, "gettype": "remove_file"}, + ], + }, + ], + }, + }, + "stop_services_cmd": [ + "/usr/local/bin/platform_process.py stop", + ], + "start_services_cmd": [ + "/usr/local/bin/platform_process.py start", + ], +} + +REBOOT_CAUSE_PARA = { + "reboot_cause_list": [ + { + "name": "cold_reboot", + "monitor_point": {"gettype": "io", "io_addr": 0x988, "okval": 0}, + "record": [ + {"record_type": "file", "mode": "cover", "log": "Power Loss, ", + "path": "/etc/sonic/.reboot/.previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "Power Loss, ", + "path": "/etc/sonic/.reboot/.history-reboot-cause.txt", "file_max_size": 1 * 1024 * 1024} + ] + }, + { + "name": "wdt_reboot", + "monitor_point": {"gettype": "io", "io_addr": 0x989, "okval": 1}, + "record": [ + {"record_type": "file", "mode": "cover", "log": "Watchdog, ", + "path": "/etc/sonic/.reboot/.previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "Watchdog, ", + "path": "/etc/sonic/.reboot/.history-reboot-cause.txt", "file_max_size":1*1024*1024} + ], + "finish_operation": [ + {"gettype": "io", "io_addr": 0x987, "value": 0xfc}, + ] + }, + { + "name": "bmc_reboot", + "monitor_point": {"gettype": "io", "io_addr": 0x98a, "okval": 1}, + "record": [ + {"record_type": "file", "mode": "cover", "log": "BMC reboot, ", + "path": "/etc/sonic/.reboot/.previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "BMC reboot, ", "path": "/etc/sonic/.reboot/.history-reboot-cause.txt"} + ], + "finish_operation": [ + {"gettype": "io", "io_addr": 0x987, "value": 0xfa}, + ] + }, + { + "name": "bmc_powerdown", + "monitor_point": {"gettype": "io", "io_addr": 0x98b, "okval": 1}, + "record": [ + {"record_type": "file", "mode": "cover", "log": "BMC powerdown, ", + "path": "/etc/sonic/.reboot/.previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "BMC powerdown, ", "path": "/etc/sonic/.reboot/.history-reboot-cause.txt"} + ], + "finish_operation": [ + {"gettype": "io", "io_addr": 0x987, "value": 0xf6}, + ] + }, + { + "name": "otp_switch_reboot", + "monitor_point": {"gettype": "file_exist", "judge_file": "/etc/.otp_switch_reboot_flag", "okval": True}, + "record": [ + {"record_type": "file", "mode": "cover", "log": "Thermal Overload: ASIC, ", + "path": "/etc/sonic/.reboot/.previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "Thermal Overload: ASIC, ", + "path": "/etc/sonic/.reboot/.history-reboot-cause.txt", "file_max_size": 1 * 1024 * 1024} + ], + "finish_operation": [ + {"gettype": "cmd", "cmd": "rm -rf /etc/.otp_switch_reboot_flag"}, + ] + }, + { + "name": "otp_other_reboot", + "monitor_point": {"gettype": "file_exist", "judge_file": "/etc/.otp_other_reboot_flag", "okval": True}, + "record": [ + {"record_type": "file", "mode": "cover", "log": "Thermal Overload: Other, ", + "path": "/etc/sonic/.reboot/.previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "Thermal Overload: Other, ", + "path": "/etc/sonic/.reboot/.history-reboot-cause.txt", "file_max_size": 1 * 1024 * 1024} + ], + "finish_operation": [ + {"gettype": "cmd", "cmd": "rm -rf /etc/.otp_other_reboot_flag"}, + ] + }, + ], + "other_reboot_cause_record": [ + {"record_type": "file", "mode": "cover", "log": "Other, ", "path": "/etc/sonic/.reboot/.previous-reboot-cause.txt"}, + {"record_type": "file", "mode": "add", "log": "Other, ", "path": "/etc/sonic/.reboot/.history-reboot-cause.txt"} + ], +} + +UPGRADE_SUMMARY = { + "devtype": 0x20000056, + + "slot0": { + "subtype": 0, + "VME": { + "chain1": { + "name": "CPLD", + "is_support_warm_upg": 1, + }, + }, + + "SPI-LOGIC-DEV": { + "chain1": { + "name": "FPGA", + "is_support_warm_upg": 1, + }, + }, + + "SYSFS": { + "chain2": { + "name": "BCM5387", + "is_support_warm_upg": 0, + "init_cmd": [ + {"cmd": "modprobe wb_spi_gpio", "gettype": "cmd"}, + {"cmd": "modprobe wb_spi_gpio_device sck=67 miso=32 mosi=65 bus=0", "gettype": "cmd"}, + {"cmd": "modprobe wb_spi_93xx46 spi_bus_num=0 spi_cs_gpio=6", "gettype": "cmd", "delay": 0.1}, + ], + "finish_cmd": [ + {"cmd": "rmmod wb_spi_93xx46", "gettype": "cmd"}, + {"cmd": "rmmod wb_spi_gpio_device", "gettype": "cmd"}, + {"cmd": "rmmod wb_spi_gpio", "gettype": "cmd", "delay": 0.1}, + ], + }, + }, + + "MTD": { + "chain3": { + "name": "BIOS", + "is_support_warm_upg": 0, + "filesizecheck": 10240, # bios check file size, Unit: K + "init_cmd": [ + {"io_addr": 0x722, "value": 0x02, "gettype": "io"}, + {"cmd": "modprobe mtd", "gettype": "cmd"}, + {"cmd": "modprobe spi_nor", "gettype": "cmd"}, + {"cmd": "modprobe ofpart", "gettype": "cmd"}, + {"cmd": "modprobe intel_spi writeable=1", "gettype": "cmd"}, + {"cmd": "modprobe intel_spi_platform writeable=1", "gettype": "cmd"}, + ], + "finish_cmd": [ + {"cmd": "rmmod intel_spi_platform", "gettype": "cmd"}, + {"cmd": "rmmod intel_spi", "gettype": "cmd"}, + {"cmd": "rmmod ofpart", "gettype": "cmd"}, + {"cmd": "rmmod spi_nor", "gettype": "cmd"}, + {"cmd": "rmmod mtd", "gettype": "cmd"}, + ], + }, + }, + + "TEST": { + "fpga": [ + {"chain": 1, "file": "/etc/.upgrade_test/fpga_test_header.bin", "display_name": "FPGA"}, + ], + "cpld": [ + {"chain": 1, "file": "/etc/.upgrade_test/cpld_test_header.vme", "display_name": "CPLD"}, + ], + }, + }, + + "BMC": { + "name": "BMC", + "init_cmd": [ + # stop BMC stack watchdog + {"cmd": "ipmitool raw 0x32 0x03 0x02", "gettype": "cmd", "ignore_result": 1}, + ], + "finish_cmd": [], + }, +} + +PLATFORM_E2_CONF = { + "fan": [ + {"name": "fan1", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/35-0050/eeprom"}, + {"name": "fan2", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/34-0050/eeprom"}, + {"name": "fan3", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/33-0050/eeprom"}, + {"name": "fan4", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/32-0050/eeprom"}, + {"name": "fan5", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/31-0050/eeprom"}, + {"name": "fan6", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/30-0050/eeprom"}, + ], + "psu": [ + {"name": "psu1", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/41-0050/eeprom"}, + {"name": "psu2", "e2_type": "fru", "e2_path": "/sys/bus/i2c/devices/42-0050/eeprom"}, + ], + "syseeprom": [ + {"name": "syseeprom", "e2_type": "onie_tlv", "e2_path": "/sys/bus/i2c/devices/1-0056/eeprom"}, + ], +} diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/config/x86_64_micas_m2_w6520_24dc8qc_r0_port_config.py b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/config/x86_64_micas_m2_w6520_24dc8qc_r0_port_config.py new file mode 100644 index 000000000000..fccc59402891 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/config/x86_64_micas_m2_w6520_24dc8qc_r0_port_config.py @@ -0,0 +1,7 @@ +#!/usr/bin/python3 +# -*- coding: UTF-8 -*- + +PLATFORM_INTF_OPTOE = { + "port_num": 32, + "optoe_start_bus": 46, +} diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/hal-config/x86_64_micas_m2_w6520_24dc8qc_r0_device.py b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/hal-config/x86_64_micas_m2_w6520_24dc8qc_r0_device.py new file mode 100644 index 000000000000..6adf2ef004b9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/hal-config/x86_64_micas_m2_w6520_24dc8qc_r0_device.py @@ -0,0 +1,1190 @@ +#!/usr/bin/python3 + +psu_fan_airflow = { + "intake": ['DPS-1300AB-6 S', 'GW-CRPS1300D'], + "exhaust": [] +} + +fanairflow = { + "intake": ['M1HFAN II-F'], + "exhaust": [], +} + +psu_display_name = { + "PA1300I-F": ['GW-CRPS1300D', 'DPS-1300AB-6 S'], +} + +psutypedecode = { + 0x00: 'N/A', + 0x01: 'AC', + 0x02: 'DC', +} + +class Unit: + Temperature = "C" + Voltage = "V" + Current = "A" + Power = "W" + Speed = "RPM" + +class threshold: + PSU_TEMP_MIN = -10 * 1000 + PSU_TEMP_MAX = 60 * 1000 + + PSU_FAN_SPEED_MIN = 2000 + PSU_FAN_SPEED_MAX = 28000 + + PSU_OUTPUT_VOLTAGE_MIN = 11 * 1000 + PSU_OUTPUT_VOLTAGE_MAX = 14 * 1000 + + PSU_AC_INPUT_VOLTAGE_MIN = 200 * 1000 + PSU_AC_INPUT_VOLTAGE_MAX = 240 * 1000 + + PSU_DC_INPUT_VOLTAGE_MIN = 190 * 1000 + PSU_DC_INPUT_VOLTAGE_MAX = 290 * 1000 + + ERR_VALUE = -9999999 + + PSU_OUTPUT_POWER_MIN = 10 * 1000 * 1000 + PSU_OUTPUT_POWER_MAX = 1300 * 1000 * 1000 + + PSU_INPUT_POWER_MIN = 10 * 1000 * 1000 + PSU_INPUT_POWER_MAX = 1444 * 1000 * 1000 + + PSU_OUTPUT_CURRENT_MIN = 2 * 1000 + PSU_OUTPUT_CURRENT_MAX = 107 * 1000 + + PSU_INPUT_CURRENT_MIN = 0.2 * 1000 + PSU_INPUT_CURRENT_MAX = 7 * 1000 + + FRONT_FAN_SPEED_MAX = 25000 + REAR_FAN_SPEED_MAX = 22000 + FAN_SPEED_MIN = 2000 + +devices = { + "onie_e2": [ + { + "name": "ONIE_E2", + "e2loc": {"loc": "/sys/bus/i2c/devices/1-0056/eeprom", "way": "sysfs"}, + "airflow": "intake" + }, + ], + "psus": [ + { + "e2loc": {"loc": "/sys/bus/i2c/devices/41-0050/eeprom", "way": "sysfs"}, + "pmbusloc": {"bus": 41, "addr": 0x58, "way": "i2c"}, + "present": {"loc": "/sys/wb_plat/psu/psu1/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "name": "PSU1", + "psu_display_name": psu_display_name, + "airflow": psu_fan_airflow, + "TempStatus": {"bus": 41, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0004}, + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-41/41-0058/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": threshold.PSU_TEMP_MIN, + "Max": threshold.PSU_TEMP_MAX, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + }, + "FanStatus": {"bus": 41, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0400}, + "FanSpeed": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-41/41-0058/hwmon/hwmon*/fan1_input", "way": "sysfs"}, + "Min": threshold.PSU_FAN_SPEED_MIN, + "Max": threshold.PSU_FAN_SPEED_MAX, + "Unit": Unit.Speed + }, + "psu_fan_tolerance": 40, + "InputsStatus": {"bus":41, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x2000}, + "InputsType": {"bus": 41, "addr": 0x58, "offset": 0x80, "way": "i2c", 'psutypedecode': psutypedecode}, + "InputsVoltage": { + 'AC': { + "value": {"loc": "/sys/bus/i2c/devices/i2c-41/41-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.PSU_AC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_AC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + + }, + 'DC': { + "value": {"loc": "/sys/bus/i2c/devices/i2c-41/41-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.PSU_DC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_DC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + 'other': { + "value": {"loc": "/sys/bus/i2c/devices/i2c-41/41-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.ERR_VALUE, + "Max": threshold.ERR_VALUE, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + } + }, + "InputsCurrent": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-41/41-0058/hwmon/hwmon*/curr1_input", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_CURRENT_MIN, + "Max": threshold.PSU_INPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "InputsPower": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-41/41-0058/hwmon/hwmon*/power1_input", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_POWER_MIN, + "Max": threshold.PSU_INPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + "OutputsStatus": {"bus": 41, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x8800}, + "OutputsVoltage": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-41/41-0058/hwmon/hwmon*/in2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_VOLTAGE_MIN, + "Max": threshold.PSU_OUTPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + "OutputsCurrent": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-41/41-0058/hwmon/hwmon*/curr2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_CURRENT_MIN, + "Max": threshold.PSU_OUTPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "OutputsPower": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-41/41-0058/hwmon/hwmon*/power2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_POWER_MIN, + "Max": threshold.PSU_OUTPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + }, + { + "e2loc": {"loc": "/sys/bus/i2c/devices/42-0050/eeprom", "way": "sysfs"}, + "pmbusloc": {"bus": 42, "addr": 0x58, "way": "i2c"}, + "present": {"loc": "/sys/wb_plat/psu/psu2/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "name": "PSU2", + "psu_display_name": psu_display_name, + "airflow": psu_fan_airflow, + "TempStatus": {"bus": 42, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0004}, + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-42/42-0058/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": threshold.PSU_TEMP_MIN, + "Max": threshold.PSU_TEMP_MAX, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + }, + "FanStatus": {"bus": 42, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x0400}, + "FanSpeed": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-42/42-0058/hwmon/hwmon*/fan1_input", "way": "sysfs"}, + "Min": threshold.PSU_FAN_SPEED_MIN, + "Max": threshold.PSU_FAN_SPEED_MAX, + "Unit": Unit.Speed + }, + "psu_fan_tolerance": 40, + "InputsStatus": {"bus": 42, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x2000}, + "InputsType": {"bus": 42, "addr": 0x58, "offset": 0x80, "way": "i2c", 'psutypedecode': psutypedecode}, + "InputsVoltage": { + 'AC': { + "value": {"loc": "/sys/bus/i2c/devices/i2c-42/42-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.PSU_AC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_AC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + + }, + 'DC': { + "value": {"loc": "/sys/bus/i2c/devices/i2c-42/42-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.PSU_DC_INPUT_VOLTAGE_MIN, + "Max": threshold.PSU_DC_INPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + 'other': { + "value": {"loc": "/sys/bus/i2c/devices/i2c-42/42-0058/hwmon/hwmon*/in1_input", "way": "sysfs"}, + "Min": threshold.ERR_VALUE, + "Max": threshold.ERR_VALUE, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + } + }, + "InputsCurrent": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-42/42-0058/hwmon/hwmon*/curr1_input", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_CURRENT_MIN, + "Max": threshold.PSU_INPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "InputsPower": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-42/42-0058/hwmon/hwmon*/power1_input", "way": "sysfs"}, + "Min": threshold.PSU_INPUT_POWER_MIN, + "Max": threshold.PSU_INPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + "OutputsStatus": {"bus": 42, "addr": 0x58, "offset": 0x79, "way": "i2cword", "mask": 0x8800}, + "OutputsVoltage": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-42/42-0058/hwmon/hwmon*/in2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_VOLTAGE_MIN, + "Max": threshold.PSU_OUTPUT_VOLTAGE_MAX, + "Unit": Unit.Voltage, + "format": "float(float(%s)/1000)" + }, + "OutputsCurrent": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-42/42-0058/hwmon/hwmon*/curr2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_CURRENT_MIN, + "Max": threshold.PSU_OUTPUT_CURRENT_MAX, + "Unit": Unit.Current, + "format": "float(float(%s)/1000)" + }, + "OutputsPower": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-42/42-0058/hwmon/hwmon*/power2_input", "way": "sysfs"}, + "Min": threshold.PSU_OUTPUT_POWER_MIN, + "Max": threshold.PSU_OUTPUT_POWER_MAX, + "Unit": Unit.Power, + "format": "float(float(%s)/1000000)" + }, + } + ], + "temps": [ + { + "name": "BOARD_TEMP", + "temp_id": "TEMP1", + "api_name": "Board", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/40-004e/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": -10000, + "Low": 0, + "High": 70000, + "Max": 80000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "CPU_TEMP", + "temp_id": "TEMP2", + "api_name": "CPU", + "Temperature": { + "value": {"loc": "/sys/bus/platform/devices/coretemp.0/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": 2000, + "Low": 10000, + "High": 100000, + "Max": 104000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "INLET_TEMP", + "temp_id": "TEMP3", + "api_name": "Inlet", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/40-004f/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": -10000, + "Low": 0, + "High": 40000, + "Max": 50000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "OUTLET_TEMP", + "temp_id": "TEMP4", + "api_name": "Outlet", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/36-0048/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": -10000, + "Low": 0, + "High": 70000, + "Max": 80000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "SWITCH_TEMP", + "temp_id": "TEMP5", + "api_name": "ASIC_TEMP", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/44-0044/hwmon/hwmon*/temp99_input", "way": "sysfs"}, + "Min": 2000, + "Low": 10000, + "High": 100000, + "Max": 105000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "PSU1_TEMP", + "temp_id": "TEMP6", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-41/41-0058/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": -10000, + "Low": 0, + "High": 55000, + "Max": 60000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "PSU2_TEMP", + "temp_id": "TEMP7", + "Temperature": { + "value": {"loc": "/sys/bus/i2c/devices/i2c-42/42-0058/hwmon/hwmon*/temp1_input", "way": "sysfs"}, + "Min": -10000, + "Low": 0, + "High": 55000, + "Max": 60000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + } + }, + { + "name": "SFF_TEMP", + "Temperature": { + "value": {"loc": "/tmp/highest_sff_temp", "way": "sysfs", "flock_path": "/tmp/highest_sff_temp"}, + "Min": -15000, + "Low": 0, + "High": 80000, + "Max": 100000, + "Unit": Unit.Temperature, + "format": "float(float(%s)/1000)" + }, + "invalid": -10000, + "error": -9999, + } + ], + "leds": [ + { + "name": "FRONT_SYS_LED", + "led_type": "SYS_LED", + "led": {"bus": 2, "addr": 0x2d, "offset":0x40, "way":"i2c"}, + "led_attrs": { + "off": 0x0, "green": 0x01, "red": 0x02,"default":0x01, + "amber": 0x03, "green_flash": 0x41, "red_flash": 0x42, + "amber_flash": 0x43, "mask": 0xff + }, + }, + { + "name": "FRONT_PSU_LED", + "led_type": "PSU_LED", + "led": {"bus": 2, "addr": 0x2d, "offset":0x43, "way":"i2c"}, + "led_attrs": { + "green":0x04, "red":0x02, "amber":0x06, "default":0x04, + "flash":0xff, "light":0xff, "off": 0, "mask":0x07 + }, + }, + { + "name": "FRONT_FAN_LED", + "led_type": "FAN_LED", + "led": {"bus": 2, "addr": 0x2d, "offset":0x42, "way":"i2c"}, + "led_attrs": { + "green":0x04, "red":0x02, "amber":0x06, "default":0x04, + "flash":0xff, "light":0xff, "off": 0, "mask":0x07 + }, + }, + ], + "fans": [ + { + "name": "FAN1", + "airflow": fanairflow, + "e2loc": {'loc': '/sys/bus/i2c/devices/i2c-35/35-0050/eeprom', 'way': 'sysfs'}, + "present": {"loc": "/sys/wb_plat/fan/fan1/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"bus": 4, "addr": 0x3d, "offset": 0x41, "way": "i2c"}, + "led_attrs": { + "off": 0x0, "red_flash": 0x01, "red": 0x02, + "green_flash": 0x03, "green": 0x04, "amber_flash": 0x05, + "amber": 0x06, "mask": 0x07 + }, + "PowerMax": 38.16, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"bus": 4, "addr": 0x3d, "offset": 0x65, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan1/motor0/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan1/motor0/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan1/motor0/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"bus": 4, "addr": 0x3d, "offset": 0x65, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan1/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan1/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan1/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + { + "name": "FAN2", + "airflow": fanairflow, + "e2loc": {'loc': '/sys/bus/i2c/devices/i2c-34/34-0050/eeprom', 'way': 'sysfs'}, + "present": {"loc": "/sys/wb_plat/fan/fan2/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"bus": 4, "addr": 0x3d, "offset": 0x40, "way": "i2c"}, + "led_attrs": { + "off": 0x0, "red_flash": 0x01, "red": 0x02, + "green_flash": 0x03, "green": 0x04, "amber_flash": 0x05, + "amber": 0x06, "mask": 0x07 + }, + "PowerMax": 38.16, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"bus": 4, "addr": 0x3d, "offset": 0x64, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan2/motor0/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan2/motor0/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan2/motor0/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"bus": 4, "addr": 0x3d, "offset": 0x64, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan2/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan2/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan2/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + { + "name": "FAN3", + "airflow": fanairflow, + "e2loc": {'loc': '/sys/bus/i2c/devices/i2c-33/33-0050/eeprom', 'way': 'sysfs'}, + "present": {"loc": "/sys/wb_plat/fan/fan3/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"bus": 4, "addr": 0x3d, "offset": 0x3f, "way": "i2c"}, + "led_attrs": { + "off": 0x0, "red_flash": 0x01, "red": 0x02, + "green_flash": 0x03, "green": 0x04, "amber_flash": 0x05, + "amber": 0x06, "mask": 0x07 + }, + "PowerMax": 38.16, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"bus": 4, "addr": 0x3d, "offset": 0x63, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan3/motor0/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan3/motor0/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan3/motor0/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"bus": 4, "addr": 0x3d, "offset": 0x63, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan3/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan3/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan3/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + { + "name": "FAN4", + "airflow": fanairflow, + "e2loc": {'loc': '/sys/bus/i2c/devices/i2c-32/32-0050/eeprom', 'way': 'sysfs'}, + "present": {"loc": "/sys/wb_plat/fan/fan4/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"bus": 4, "addr": 0x3d, "offset": 0x3e, "way": "i2c"}, + "led_attrs": { + "off": 0x0, "red_flash": 0x01, "red": 0x02, + "green_flash": 0x03, "green": 0x04, "amber_flash": 0x05, + "amber": 0x06, "mask": 0x07 + }, + "PowerMax": 38.16, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"bus": 4, "addr": 0x3d, "offset": 0x62, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan4/motor0/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan4/motor0/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan4/motor0/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"bus": 4, "addr": 0x3d, "offset": 0x62, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan4/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan4/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan4/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + { + "name": "FAN5", + "airflow": fanairflow, + "e2loc": {'loc': '/sys/bus/i2c/devices/i2c-31/31-0050/eeprom', 'way': 'sysfs'}, + "present": {"loc": "/sys/wb_plat/fan/fan5/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"bus": 4, "addr": 0x3d, "offset": 0x3d, "way": "i2c"}, + "led_attrs": { + "off": 0x0, "red_flash": 0x01, "red": 0x02, + "green_flash": 0x03, "green": 0x04, "amber_flash": 0x05, + "amber": 0x06, "mask": 0x07 + }, + "PowerMax": 38.16, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"bus": 4, "addr": 0x3d, "offset": 0x61, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan5/motor0/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan5/motor0/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan5/motor0/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"bus": 4, "addr": 0x3d, "offset": 0x61, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan5/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan5/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan5/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + { + "name": "FAN6", + "airflow": fanairflow, + "e2loc": {'loc': '/sys/bus/i2c/devices/i2c-30/30-0050/eeprom', 'way': 'sysfs'}, + "present": {"loc": "/sys/wb_plat/fan/fan6/present", "way": "sysfs", "mask": 0x01, "okval": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "led": {"bus": 4, "addr": 0x3d, "offset": 0x3c, "way": "i2c"}, + "led_attrs": { + "off": 0x0, "red_flash": 0x01, "red": 0x02, + "green_flash": 0x03, "green": 0x04, "amber_flash": 0x05, + "amber": 0x06, "mask": 0x07 + }, + "PowerMax": 38.16, + "Rotor": { + "Rotor1_config": { + "name": "Rotor1", + "Set_speed": {"bus": 4, "addr": 0x3d, "offset": 0x60, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan6/motor0/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan6/motor0/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.FRONT_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan6/motor0/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.FRONT_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + "Rotor2_config": { + "name": "Rotor2", + "Set_speed": {"bus": 4, "addr": 0x3d, "offset": 0x60, "way": "i2c"}, + "Running": {"loc": "/sys/wb_plat/fan/fan6/motor1/status", "way": "sysfs", "mask": 0x01, "is_runing": 1}, + "HwAlarm": {"loc": "/sys/wb_plat/fan/fan6/motor1/status", "way": "sysfs", "mask": 0x01, "no_alarm": 1}, + "SpeedMin": threshold.FAN_SPEED_MIN, + "SpeedMax": threshold.REAR_FAN_SPEED_MAX, + "Speed": { + "value": {"loc": "/sys/wb_plat/fan/fan6/motor1/speed", "way": "sysfs"}, + "Min": threshold.FAN_SPEED_MIN, + "Max": threshold.REAR_FAN_SPEED_MAX, + "Unit": Unit.Speed, + }, + }, + }, + }, + ], + "cplds": [ + { + "name": "CPU_CPLD", + "cpld_id": "CPLD1", + "VersionFile": {"loc": "/dev/cpld0", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for system power", + "slot": 0, + "warm": 1, + }, + { + "name": "CONNECT_CPLD", + "cpld_id": "CPLD2", + "VersionFile": {"loc": "/dev/cpld1", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for base functions", + "slot": 0, + "warm": 1, + }, + { + "name": "MAC_CPLDA", + "cpld_id": "CPLD3", + "VersionFile": {"loc": "/dev/cpld4", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for sff modules", + "slot": 0, + "warm": 1, + }, + { + "name": "MAC_CPLDB", + "cpld_id": "CPLD4", + "VersionFile": {"loc": "/dev/cpld5", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for sff modules", + "slot": 0, + "warm": 1, + }, + { + "name": "FAN_CPLD", + "cpld_id": "CPLD5", + "VersionFile": {"loc": "/dev/cpld6", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for fan modules", + "slot": 0, + "warm": 1, + }, + { + "name": "FPGA", + "cpld_id": "CPLD6", + "VersionFile": {"loc": "/dev/fpga0", "offset": 0, "len": 4, "way": "devfile_ascii"}, + "desc": "Used for base functions", + "slot": 0, + "format": "little_endian", + "warm": 1, + }, + { + "name": "BIOS", + "cpld_id": "CPLD7", + "VersionFile": {"cmd": "dmidecode -s bios-version", "way": "cmd"}, + "desc": "Performs initialization of hardware components during booting", + "slot": 0, + "type": "str", + "warm": 0, + }, + ], + "dcdc": [ + { + "name": "VDD5V_CLK_MCU", + "dcdc_id": "DCDC1", + "value": { + "loc": "/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in1_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 4250, + "Max": 5750, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "VDD3.3_CLK", + "dcdc_id": "DCDC2", + "value": { + "loc": "/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in2_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 2805, + "Max": 3795, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "VDD1.0V", + "dcdc_id": "DCDC3", + "value": { + "loc": "/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in3_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 850, + "Max": 1150, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "VDD1.8V", + "dcdc_id": "DCDC4", + "value": { + "loc": "/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in4_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 1530, + "Max": 2070, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "MAC_BOARD_VDD3.3V", + "dcdc_id": "DCDC5", + "value": { + "loc": "/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in5_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 2805, + "Max": 3795, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "VDD1.2V", + "dcdc_id": "DCDC6", + "value": { + "loc": "/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in6_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 1020, + "Max": 1380, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "VDD_CORE", + "dcdc_id": "DCDC7", + "value": { + "loc": "/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in7_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 600, + "Max": 1100, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "ANALOG0.75V", + "dcdc_id": "DCDC8", + "value": { + "loc": "/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in8_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 615, + "Max": 1000, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "MAC_VDD1.2V", + "dcdc_id": "DCDC9", + "value": { + "loc": "/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in9_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 1020, + "Max": 1380, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "VDDO1.8V", + "dcdc_id": "DCDC10", + "value": { + "loc": "/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in10_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 1530, + "Max": 2070, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "MAC_ANA1.2V", + "dcdc_id": "DCDC11", + "value": { + "loc": "/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in11_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 1020, + "Max": 1380, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "MAC_ANA1.8V", + "dcdc_id": "DCDC12", + "value": { + "loc": "/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in12_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 1530, + "Max": 2070, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "QSFP56_VDD3.3V_A", + "dcdc_id": "DCDC13", + "value": { + "loc": "/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in13_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 2805, + "Max": 3795, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "QSFP56_VDD3.3V_B", + "dcdc_id": "DCDC14", + "value": { + "loc": "/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in14_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 2805, + "Max": 3795, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "QSFPDD_VDD3.3V_A", + "dcdc_id": "DCDC15", + "value": { + "loc": "/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in15_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 2805, + "Max": 3795, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "QSFPDD_VDD3.3V_B", + "dcdc_id": "DCDC16", + "value": { + "loc": "/sys/bus/i2c/devices/45-005b/hwmon/hwmon*/in16_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 2805, + "Max": 3795, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "VDD5.0V", + "dcdc_id": "DCDC17", + "value": { + "loc": "/sys/bus/i2c/devices/24-005b/hwmon/hwmon*/in1_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 4250, + "Max": 5750, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "SW_VDD1.2V", + "dcdc_id": "DCDC18", + "value": { + "loc": "/sys/bus/i2c/devices/24-005b/hwmon/hwmon*/in2_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 1020, + "Max": 1380, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "VDD2.5V", + "dcdc_id": "DCDC19", + "value": { + "loc": "/sys/bus/i2c/devices/24-005b/hwmon/hwmon*/in3_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 2125, + "Max": 2875, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "CONNECT_BOARD_VDD3.3V", + "dcdc_id": "DCDC20", + "value": { + "loc": "/sys/bus/i2c/devices/24-005b/hwmon/hwmon*/in4_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 2805, + "Max": 3795, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "VDD12V", + "dcdc_id": "DCDC21", + "value": { + "loc": "/sys/bus/i2c/devices/24-005b/hwmon/hwmon*/in6_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 10200, + "Max": 13800, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "VDD3.3_STBY", + "dcdc_id": "DCDC22", + "value": { + "loc": "/sys/bus/i2c/devices/24-005b/hwmon/hwmon*/in7_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 2805, + "Max": 3795, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "SSD_VDD3.3V", + "dcdc_id": "DCDC23", + "value": { + "loc": "/sys/bus/i2c/devices/24-005b/hwmon/hwmon*/in8_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 2805, + "Max": 3795, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "VCCIN", + "dcdc_id": "DCDC24", + "value": { + "loc": "/sys/bus/i2c/devices/25-0067/hwmon/hwmon*/in2_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 1368, + "Max": 2244, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "P1V05", + "dcdc_id": "DCDC25", + "value": { + "loc": "/sys/bus/i2c/devices/25-0067/hwmon/hwmon*/in3_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 882, + "Max": 1232, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "VCCD_V", + "dcdc_id": "DCDC26", + "value": { + "loc": "/sys/bus/i2c/devices/25-006c/hwmon/hwmon*/in2_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 990, + "Max": 1452, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "VCCSCSUS_V", + "dcdc_id": "DCDC27", + "value": { + "loc": "/sys/bus/i2c/devices/25-006c/hwmon/hwmon*/in3_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 855, + "Max": 1265, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "P3V3_STBY_V", + "dcdc_id": "DCDC28", + "value": { + "loc": "/sys/bus/i2c/devices/25-0043/hwmon/hwmon*/in2_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 2682, + "Max": 4004, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "P5V_AUX_IN", + "dcdc_id": "DCDC29", + "value": { + "loc": "/sys/bus/i2c/devices/25-0043/hwmon/hwmon*/in1_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 3852, + "Max": 6347, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + + { + "name": "P1V7_VCCSCFUSESUS_IN", + "dcdc_id": "DCDC30", + "value": { + "loc": "/sys/bus/i2c/devices/25-0043/hwmon/hwmon*/in3_input", + "way": "sysfs", + }, + "read_times": 1, + "Min": 1377, + "Max": 2057, + "Unit": "V", + "format": "float(float(%s)/1000)", + }, + ], + "cpu": [ + { + "name": "cpu", + "CpuResetCntReg": {"loc": "/dev/cpld1", "offset": 0x88, "len": 1, "way": "devfile_ascii"}, + "reboot_cause_path": "/etc/sonic/.reboot/.previous-reboot-cause.txt" + } + ], + "sfps": { + "ver": '1.0', + "port_index_start": 0, + "port_num": 32, + "log_level": 2, + "eeprom_retry_times": 5, + "eeprom_retry_break_sec": 0.2, + "presence_cpld": { + "dev_id": { + 4: { + "offset": { + 0x30: "1-8", + 0x31: "9-16", + 0x32: "17-24", + 0x33: "25-32" + }, + }, + }, + }, + "presence_val_is_present": 0, + "eeprom_path": "/sys/bus/i2c/devices/i2c-%d/%d-0050/eeprom", + "eeprom_path_key": list(range(46, 78)), + "optoe_driver_path": "/sys/bus/i2c/devices/i2c-%d/%d-0050/dev_class", + "optoe_driver_key": list(range(46, 78)), + "reset_cpld": { + "dev_id": { + 5: { + "offset": { + 0x22: "1-8", + 0x23: "9-16" + }, + }, + 4: { + "offset": { + 0x21: "17-24", + 0x22: "25-32" + }, + }, + }, + }, + "reset_val_is_reset": 0, + } +} diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/hal-config/x86_64_micas_m2_w6520_24dc8qc_r0_monitor.py b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/hal-config/x86_64_micas_m2_w6520_24dc8qc_r0_monitor.py new file mode 100644 index 000000000000..58388d5875f2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/hal-config/x86_64_micas_m2_w6520_24dc8qc_r0_monitor.py @@ -0,0 +1,207 @@ +# coding:utf-8 + + +monitor = { + "openloop": { + "linear": { + "name": "linear", + "flag": 0, + "pwm_min": 0x80, + "pwm_max": 0xff, + "K": 11, + "tin_min": 38, + }, + "curve": { + "name": "curve", + "flag": 1, + "pwm_min": 0x80, + "pwm_max": 0xff, + "a": 0.369, + "b": -15.657, + "c": 289, + "tin_min": 25, + }, + }, + + "pid": { + "CPU_TEMP": { + "name": "CPU_TEMP", + "flag": 1, + "type": "duty", + "pwm_min": 0x80, + "pwm_max": 0xff, + "Kp": 1.5, + "Ki": 1, + "Kd": 0.3, + "target": 80, + "value": [None, None, None], + }, + "SWITCH_TEMP": { + "name": "SWITCH_TEMP", + "flag": 1, + "type": "duty", + "pwm_min": 0x80, + "pwm_max": 0xff, + "Kp": 1.5, + "Ki": 1, + "Kd": 0.3, + "target": 90, + "value": [None, None, None], + }, + "OUTLET_TEMP": { + "name": "OUTLET_TEMP", + "flag": 1, + "type": "duty", + "pwm_min": 0x80, + "pwm_max": 0xff, + "Kp": 2, + "Ki": 0.4, + "Kd": 0.3, + "target": 65, + "value": [None, None, None], + }, + "BOARD_TEMP": { + "name": "BOARD_TEMP", + "flag": 0, + "type": "duty", + "pwm_min": 0x80, + "pwm_max": 0xff, + "Kp": 2, + "Ki": 0.4, + "Kd": 0.3, + "target": 65, + "value": [None, None, None], + }, + "SFF_TEMP": { + "name": "SFF_TEMP", + "flag": 1, + "type": "duty", + "pwm_min": 0x80, + "pwm_max": 0xff, + "Kp": 0.1, + "Ki": 0.4, + "Kd": 0, + "target": 60, + "value": [None, None, None], + }, + }, + + "temps_threshold": { + "SWITCH_TEMP": {"name": "SWITCH_TEMP", "warning": 100, "critical": 105, "invalid": -100000, "error": -99999}, + "INLET_TEMP": {"name": "INLET_TEMP", "warning": 40, "critical": 50, "fix": -3}, + "BOARD_TEMP": {"name": "BOARD_TEMP", "warning": 70, "critical": 75}, + "OUTLET_TEMP": {"name": "OUTLET_TEMP", "warning": 70, "critical": 75}, + "CPU_TEMP": {"name": "CPU_TEMP", "warning": 100, "critical": 102}, + "SFF_TEMP": {"name": "SFF_TEMP", "warning": 999, "critical": 1000, "ignore_threshold": 1, "invalid": -10000, "error": -9999}, + }, + + "fancontrol_para": { + "interval": 5, + "fan_status_interval": 0.5, + "max_pwm": 0xff, + "min_pwm": 0x80, + "abnormal_pwm": 0xff, + "warning_pwm": 0xff, + "temp_invalid_pid_pwm": 0x80, + "temp_error_pid_pwm": 0x80, + "temp_fail_num": 3, + "check_temp_fail": [ + {"temp_name": "INLET_TEMP"}, + {"temp_name": "SWITCH_TEMP"}, + {"temp_name": "CPU_TEMP"}, + ], + "temp_warning_num": 3, # temp over warning 3 times continuously + "temp_critical_num": 3, # temp over critical 3 times continuously + "temp_warning_countdown": 60, # 5 min warning speed after not warning + "temp_critical_countdown": 60, # 5 min full speed after not critical + "rotor_error_count": 2, # fan rotor error 2 times continuously + "inlet_mac_diff": 999, + "check_crit_reboot_flag": 1, + "check_crit_reboot_num": 3, + "check_crit_sleep_time": 20, + "psu_absent_fullspeed_num": 0xFF, + "fan_absent_fullspeed_num": 1, + "rotor_error_fullspeed_num": 1, + "psu_fan_control": 1, + "fan_plug_in_default_countdown": 0, # no use + "fan_plug_in_pwm": 0x80, # fan plug in pwd + "deal_fan_error": 1, + "deal_fan_error_conf": { + "countdown": 2, + "FAN1": [ + {"name": "FAN1", "pwm": 0xff}, + {"name": "FAN2", "pwm": 0x80}, + {"name": "FAN3", "pwm": 0x80}, + {"name": "FAN4", "pwm": 0x80}, + {"name": "FAN5", "pwm": 0x80}, + {"name": "FAN6", "pwm": 0x80}, + ], + "FAN2": [ + {"name": "FAN1", "pwm": 0x80}, + {"name": "FAN2", "pwm": 0xff}, + {"name": "FAN3", "pwm": 0x80}, + {"name": "FAN4", "pwm": 0x80}, + {"name": "FAN5", "pwm": 0x80}, + {"name": "FAN6", "pwm": 0x80}, + ], + "FAN3": [ + {"name": "FAN1", "pwm": 0x80}, + {"name": "FAN2", "pwm": 0x80}, + {"name": "FAN3", "pwm": 0xff}, + {"name": "FAN4", "pwm": 0x80}, + {"name": "FAN5", "pwm": 0x80}, + {"name": "FAN6", "pwm": 0x80}, + ], + "FAN4": [ + {"name": "FAN1", "pwm": 0x80}, + {"name": "FAN2", "pwm": 0x80}, + {"name": "FAN3", "pwm": 0x80}, + {"name": "FAN4", "pwm": 0xff}, + {"name": "FAN5", "pwm": 0x80}, + {"name": "FAN6", "pwm": 0x80}, + ], + "FAN5": [ + {"name": "FAN1", "pwm": 0x80}, + {"name": "FAN2", "pwm": 0x80}, + {"name": "FAN3", "pwm": 0x80}, + {"name": "FAN4", "pwm": 0x80}, + {"name": "FAN5", "pwm": 0xff}, + {"name": "FAN6", "pwm": 0x80}, + ], + "FAN6": [ + {"name": "FAN1", "pwm": 0x80}, + {"name": "FAN2", "pwm": 0x80}, + {"name": "FAN3", "pwm": 0x80}, + {"name": "FAN4", "pwm": 0x80}, + {"name": "FAN5", "pwm": 0x80}, + {"name": "FAN6", "pwm": 0xff}, + ], + }, + }, + + "ledcontrol_para": { + "interval": 5, + "checkpsu": 0, # 0: sys led don't follow psu led + "checkfan": 0, # 0: sys led don't follow fan led + "psu_amber_num": 1, + "fan_amber_num": 1, + "board_sys_led": [ + {"led_name": "FRONT_SYS_LED"}, + ], + "board_psu_led": [ + {"led_name": "FRONT_PSU_LED"}, + ], + "board_fan_led": [ + {"led_name": "FRONT_FAN_LED"}, + ], + "psu_air_flow_monitor": 0, + "fan_air_flow_monitor": 0, + "psu_air_flow_amber_num": 0, + "fan_air_flow_amber_num": 0, + }, + + "otp_reboot_judge_file": { + "otp_switch_reboot_judge_file": "/etc/.otp_switch_reboot_flag", + "otp_other_reboot_judge_file": "/etc/.otp_other_reboot_flag", + }, +} diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/Makefile b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/Makefile new file mode 100644 index 000000000000..cbb6fe83c013 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/Makefile @@ -0,0 +1,12 @@ +MAKEFILE_FILE_PATH = $(abspath $(lastword $(MAKEFILE_LIST))) +MODULES_DIR = $(abspath $(MAKEFILE_FILE_PATH)/../../../../common/modules) + +EXTRA_CFLAGS+= -I$(MODULES_DIR) + +obj-m := wb_pcie_dev_device.o +obj-m += wb_fpga_pca954x_device.o +obj-m += wb_fpga_i2c_bus_device.o +obj-m += wb_lpc_drv_device.o +obj-m += wb_i2c_dev_device.o +obj-m += wb_io_dev_device.o + diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_fpga_i2c_bus_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_fpga_i2c_bus_device.c new file mode 100644 index 000000000000..71bfc520e801 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_fpga_i2c_bus_device.c @@ -0,0 +1,874 @@ +/* + * An wb_fpga_i2c_bus_device driver for fpga i2c device function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include + +#include +#include + +static int g_wb_fpga_i2c_debug = 0; +static int g_wb_fpga_i2c_error = 0; + +module_param(g_wb_fpga_i2c_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_fpga_i2c_error, int, S_IRUGO | S_IWUSR); + +#define WB_FPGA_I2C_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_fpga_i2c_debug) { \ + printk(KERN_INFO "[WB_FPGA_I2C][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_FPGA_I2C_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_fpga_i2c_error) { \ + printk(KERN_ERR "[WB_FPGA_I2C][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static fpga_i2c_bus_device_t fpga_i2c_bus_device_data0 = { + .adap_nr = 2, + .i2c_timeout = 3000, + .i2c_scale = 0x500, + .i2c_filter = 0x504, + .i2c_stretch = 0x508, + .i2c_ext_9548_exits_flag = 0x50c, + .i2c_ext_9548_addr = 0x510, + .i2c_ext_9548_chan = 0x514, + .i2c_in_9548_chan = 0x518, + .i2c_slave = 0x51c, + .i2c_reg = 0x520, + .i2c_reg_len = 0x530, + .i2c_data_len = 0x534, + .i2c_ctrl = 0x538, + .i2c_status = 0x53c, + .i2c_data_buf = 0x580, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x80, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga_i2c_bus_device_data1 = { + .adap_nr = 3, + .i2c_timeout = 3000, + .i2c_scale = 0x600, + .i2c_filter = 0x604, + .i2c_stretch = 0x608, + .i2c_ext_9548_exits_flag = 0x60c, + .i2c_ext_9548_addr = 0x610, + .i2c_ext_9548_chan = 0x614, + .i2c_in_9548_chan = 0x618, + .i2c_slave = 0x61c, + .i2c_reg = 0x620, + .i2c_reg_len = 0x630, + .i2c_data_len = 0x634, + .i2c_ctrl = 0x638, + .i2c_status = 0x63c, + .i2c_data_buf = 0x680, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x84, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga_i2c_bus_device_data2 = { + .adap_nr = 4, + .i2c_timeout = 3000, + .i2c_scale = 0x700, + .i2c_filter = 0x704, + .i2c_stretch = 0x708, + .i2c_ext_9548_exits_flag = 0x70c, + .i2c_ext_9548_addr = 0x710, + .i2c_ext_9548_chan = 0x714, + .i2c_in_9548_chan = 0x718, + .i2c_slave = 0x71c, + .i2c_reg = 0x720, + .i2c_reg_len = 0x730, + .i2c_data_len = 0x734, + .i2c_ctrl = 0x738, + .i2c_status = 0x73c, + .i2c_data_buf = 0x780, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x88, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga_i2c_bus_device_data3 = { + .adap_nr = 5, + .i2c_timeout = 3000, + .i2c_scale = 0x800, + .i2c_filter = 0x804, + .i2c_stretch = 0x808, + .i2c_ext_9548_exits_flag = 0x80c, + .i2c_ext_9548_addr = 0x810, + .i2c_ext_9548_chan = 0x814, + .i2c_in_9548_chan = 0x818, + .i2c_slave = 0x81c, + .i2c_reg = 0x820, + .i2c_reg_len = 0x830, + .i2c_data_len = 0x834, + .i2c_ctrl = 0x838, + .i2c_status = 0x83c, + .i2c_data_buf = 0x880, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x8c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga_dom_i2c_bus_device_data0 = { + .adap_nr = 6, + .i2c_timeout = 3000, + .i2c_scale = 0x2c00, + .i2c_filter = 0x2c04, + .i2c_stretch = 0x2c08, + .i2c_ext_9548_exits_flag = 0x2c0c, + .i2c_ext_9548_addr = 0x2c10, + .i2c_ext_9548_chan = 0x2c14, + .i2c_in_9548_chan = 0x2c18, + .i2c_slave = 0x2c1c, + .i2c_reg = 0x2c20, + .i2c_reg_len = 0x2c30, + .i2c_data_len = 0x2c34, + .i2c_ctrl = 0x2c38, + .i2c_status = 0x2c3c, + .i2c_data_buf = 0x2c80, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x7c, + .i2c_reset_on = 0x00000001, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga_dom_i2c_bus_device_data1 = { + .adap_nr = 7, + .i2c_timeout = 3000, + .i2c_scale = 0x2d00, + .i2c_filter = 0x2d04, + .i2c_stretch = 0x2d08, + .i2c_ext_9548_exits_flag = 0x2d0c, + .i2c_ext_9548_addr = 0x2d10, + .i2c_ext_9548_chan = 0x2d14, + .i2c_in_9548_chan = 0x2d18, + .i2c_slave = 0x2d1c, + .i2c_reg = 0x2d20, + .i2c_reg_len = 0x2d30, + .i2c_data_len = 0x2d34, + .i2c_ctrl = 0x2d38, + .i2c_status = 0x2d3c, + .i2c_data_buf = 0x2d80, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x7c, + .i2c_reset_on = 0x00000002, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga_dom_i2c_bus_device_data2 = { + .adap_nr = 8, + .i2c_timeout = 3000, + .i2c_scale = 0x2e00, + .i2c_filter = 0x2e04, + .i2c_stretch = 0x2e08, + .i2c_ext_9548_exits_flag = 0x2e0c, + .i2c_ext_9548_addr = 0x2e10, + .i2c_ext_9548_chan = 0x2e14, + .i2c_in_9548_chan = 0x2e18, + .i2c_slave = 0x2e1c, + .i2c_reg = 0x2e20, + .i2c_reg_len = 0x2e30, + .i2c_data_len = 0x2e34, + .i2c_ctrl = 0x2e38, + .i2c_status = 0x2e3c, + .i2c_data_buf = 0x2e80, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x7c, + .i2c_reset_on = 0x00000004, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga_dom_i2c_bus_device_data3 = { + .adap_nr = 9, + .i2c_timeout = 3000, + .i2c_scale = 0x2f00, + .i2c_filter = 0x2f04, + .i2c_stretch = 0x2f08, + .i2c_ext_9548_exits_flag = 0x2f0c, + .i2c_ext_9548_addr = 0x2f10, + .i2c_ext_9548_chan = 0x2f14, + .i2c_in_9548_chan = 0x2f18, + .i2c_slave = 0x2f1c, + .i2c_reg = 0x2f20, + .i2c_reg_len = 0x2f30, + .i2c_data_len = 0x2f34, + .i2c_ctrl = 0x2f38, + .i2c_status = 0x2f3c, + .i2c_data_buf = 0x2f80, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x7c, + .i2c_reset_on = 0x00000008, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga_dom_i2c_bus_device_data4 = { + .adap_nr = 10, + .i2c_timeout = 3000, + .i2c_scale = 0x3000, + .i2c_filter = 0x3004, + .i2c_stretch = 0x3008, + .i2c_ext_9548_exits_flag = 0x300c, + .i2c_ext_9548_addr = 0x3010, + .i2c_ext_9548_chan = 0x3014, + .i2c_in_9548_chan = 0x3018, + .i2c_slave = 0x301c, + .i2c_reg = 0x3020, + .i2c_reg_len = 0x3030, + .i2c_data_len = 0x3034, + .i2c_ctrl = 0x3038, + .i2c_status = 0x303c, + .i2c_data_buf = 0x3080, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x7c, + .i2c_reset_on = 0x00000010, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga_dom_i2c_bus_device_data5 = { + .adap_nr = 11, + .i2c_timeout = 3000, + .i2c_scale = 0x3100, + .i2c_filter = 0x3104, + .i2c_stretch = 0x3108, + .i2c_ext_9548_exits_flag = 0x310c, + .i2c_ext_9548_addr = 0x3110, + .i2c_ext_9548_chan = 0x3114, + .i2c_in_9548_chan = 0x3118, + .i2c_slave = 0x311c, + .i2c_reg = 0x3120, + .i2c_reg_len = 0x3130, + .i2c_data_len = 0x3134, + .i2c_ctrl = 0x3138, + .i2c_status = 0x313c, + .i2c_data_buf = 0x3180, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x7c, + .i2c_reset_on = 0x00000020, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga_dom_i2c_bus_device_data6 = { + .adap_nr = 12, + .i2c_timeout = 3000, + .i2c_scale = 0x3200, + .i2c_filter = 0x3204, + .i2c_stretch = 0x3208, + .i2c_ext_9548_exits_flag = 0x320c, + .i2c_ext_9548_addr = 0x3210, + .i2c_ext_9548_chan = 0x3214, + .i2c_in_9548_chan = 0x3218, + .i2c_slave = 0x321c, + .i2c_reg = 0x3220, + .i2c_reg_len = 0x3230, + .i2c_data_len = 0x3234, + .i2c_ctrl = 0x3238, + .i2c_status = 0x323c, + .i2c_data_buf = 0x3280, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x7c, + .i2c_reset_on = 0x00000040, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga_dom_i2c_bus_device_data7 = { + .adap_nr = 13, + .i2c_timeout = 3000, + .i2c_scale = 0x3300, + .i2c_filter = 0x3304, + .i2c_stretch = 0x3308, + .i2c_ext_9548_exits_flag = 0x330c, + .i2c_ext_9548_addr = 0x3310, + .i2c_ext_9548_chan = 0x3314, + .i2c_in_9548_chan = 0x3318, + .i2c_slave = 0x331c, + .i2c_reg = 0x3320, + .i2c_reg_len = 0x3330, + .i2c_data_len = 0x3334, + .i2c_ctrl = 0x3338, + .i2c_status = 0x333c, + .i2c_data_buf = 0x3380, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x7c, + .i2c_reset_on = 0x00000080, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga_dom_i2c_bus_device_data8 = { + .adap_nr = 14, + .i2c_timeout = 3000, + .i2c_scale = 0x3400, + .i2c_filter = 0x3404, + .i2c_stretch = 0x3408, + .i2c_ext_9548_exits_flag = 0x340c, + .i2c_ext_9548_addr = 0x3410, + .i2c_ext_9548_chan = 0x3414, + .i2c_in_9548_chan = 0x3418, + .i2c_slave = 0x341c, + .i2c_reg = 0x3420, + .i2c_reg_len = 0x3430, + .i2c_data_len = 0x3434, + .i2c_ctrl = 0x3438, + .i2c_status = 0x343c, + .i2c_data_buf = 0x3480, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x7c, + .i2c_reset_on = 0x00000100, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga_dom_i2c_bus_device_data9 = { + .adap_nr = 15, + .i2c_timeout = 3000, + .i2c_scale = 0x3500, + .i2c_filter = 0x3504, + .i2c_stretch = 0x3508, + .i2c_ext_9548_exits_flag = 0x350c, + .i2c_ext_9548_addr = 0x3510, + .i2c_ext_9548_chan = 0x3514, + .i2c_in_9548_chan = 0x3518, + .i2c_slave = 0x351c, + .i2c_reg = 0x3520, + .i2c_reg_len = 0x3530, + .i2c_data_len = 0x3534, + .i2c_ctrl = 0x3538, + .i2c_status = 0x353c, + .i2c_data_buf = 0x3580, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x7c, + .i2c_reset_on = 0x00000200, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga_dom_i2c_bus_device_data10 = { + .adap_nr = 16, + .i2c_timeout = 3000, + .i2c_scale = 0x3600, + .i2c_filter = 0x3604, + .i2c_stretch = 0x3608, + .i2c_ext_9548_exits_flag = 0x360c, + .i2c_ext_9548_addr = 0x3610, + .i2c_ext_9548_chan = 0x3614, + .i2c_in_9548_chan = 0x3618, + .i2c_slave = 0x361c, + .i2c_reg = 0x3620, + .i2c_reg_len = 0x3630, + .i2c_data_len = 0x3634, + .i2c_ctrl = 0x3638, + .i2c_status = 0x363c, + .i2c_data_buf = 0x3680, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x7c, + .i2c_reset_on = 0x00000400, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga_dom_i2c_bus_device_data11 = { + .adap_nr = 17, + .i2c_timeout = 3000, + .i2c_scale = 0x3700, + .i2c_filter = 0x3704, + .i2c_stretch = 0x3708, + .i2c_ext_9548_exits_flag = 0x370c, + .i2c_ext_9548_addr = 0x3710, + .i2c_ext_9548_chan = 0x3714, + .i2c_in_9548_chan = 0x3718, + .i2c_slave = 0x371c, + .i2c_reg = 0x3720, + .i2c_reg_len = 0x3730, + .i2c_data_len = 0x3734, + .i2c_ctrl = 0x3738, + .i2c_status = 0x373c, + .i2c_data_buf = 0x3780, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x7c, + .i2c_reset_on = 0x00000800, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga_dom_i2c_bus_device_data12 = { + .adap_nr = 18, + .i2c_timeout = 3000, + .i2c_scale = 0x3800, + .i2c_filter = 0x3804, + .i2c_stretch = 0x3808, + .i2c_ext_9548_exits_flag = 0x380c, + .i2c_ext_9548_addr = 0x3810, + .i2c_ext_9548_chan = 0x3814, + .i2c_in_9548_chan = 0x3818, + .i2c_slave = 0x381c, + .i2c_reg = 0x3820, + .i2c_reg_len = 0x3830, + .i2c_data_len = 0x3834, + .i2c_ctrl = 0x3838, + .i2c_status = 0x383c, + .i2c_data_buf = 0x3880, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x7c, + .i2c_reset_on = 0x00001000, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga_dom_i2c_bus_device_data13 = { + .adap_nr = 19, + .i2c_timeout = 3000, + .i2c_scale = 0x3900, + .i2c_filter = 0x3904, + .i2c_stretch = 0x3908, + .i2c_ext_9548_exits_flag = 0x390c, + .i2c_ext_9548_addr = 0x3910, + .i2c_ext_9548_chan = 0x3914, + .i2c_in_9548_chan = 0x3918, + .i2c_slave = 0x391c, + .i2c_reg = 0x3920, + .i2c_reg_len = 0x3930, + .i2c_data_len = 0x3934, + .i2c_ctrl = 0x3938, + .i2c_status = 0x393c, + .i2c_data_buf = 0x3980, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x7c, + .i2c_reset_on = 0x00002000, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga_dom_i2c_bus_device_data14 = { + .adap_nr = 20, + .i2c_timeout = 3000, + .i2c_scale = 0x3a00, + .i2c_filter = 0x3a04, + .i2c_stretch = 0x3a08, + .i2c_ext_9548_exits_flag = 0x3a0c, + .i2c_ext_9548_addr = 0x3a10, + .i2c_ext_9548_chan = 0x3a14, + .i2c_in_9548_chan = 0x3a18, + .i2c_slave = 0x3a1c, + .i2c_reg = 0x3a20, + .i2c_reg_len = 0x3a30, + .i2c_data_len = 0x3a34, + .i2c_ctrl = 0x3a38, + .i2c_status = 0x3a3c, + .i2c_data_buf = 0x3a80, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x7c, + .i2c_reset_on = 0x00004000, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static fpga_i2c_bus_device_t fpga_dom_i2c_bus_device_data15 = { + .adap_nr = 21, + .i2c_timeout = 3000, + .i2c_scale = 0x3b00, + .i2c_filter = 0x3b04, + .i2c_stretch = 0x3b08, + .i2c_ext_9548_exits_flag = 0x3b0c, + .i2c_ext_9548_addr = 0x3b10, + .i2c_ext_9548_chan = 0x3b14, + .i2c_in_9548_chan = 0x3b18, + .i2c_slave = 0x3b1c, + .i2c_reg = 0x3b20, + .i2c_reg_len = 0x3b30, + .i2c_data_len = 0x3b34, + .i2c_ctrl = 0x3b38, + .i2c_status = 0x3b3c, + .i2c_data_buf = 0x3b80, + .dev_name = "/dev/fpga0", + .i2c_scale_value = 0x4e, + .i2c_filter_value = 0x7c, + .i2c_stretch_value = 0x7c, + .i2c_func_mode = 3, + .i2c_adap_reset_flag = 1, + .i2c_reset_addr = 0x7c, + .i2c_reset_on = 0x00008000, + .i2c_reset_off = 0x00000000, + .i2c_rst_delay_b = 0, + .i2c_rst_delay = 1, + .i2c_rst_delay_a = 1, +}; + +static void wb_fpga_i2c_bus_device_release(struct device *dev) +{ + return; +} + +static struct platform_device fpga_i2c_bus_device[] = { + { + .name = "wb-fpga-i2c", + .id = 1, + .dev = { + .platform_data = &fpga_i2c_bus_device_data0, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 2, + .dev = { + .platform_data = &fpga_i2c_bus_device_data1, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 3, + .dev = { + .platform_data = &fpga_i2c_bus_device_data2, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 4, + .dev = { + .platform_data = &fpga_i2c_bus_device_data3, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 5, + .dev = { + .platform_data = &fpga_dom_i2c_bus_device_data0, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 6, + .dev = { + .platform_data = &fpga_dom_i2c_bus_device_data1, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 7, + .dev = { + .platform_data = &fpga_dom_i2c_bus_device_data2, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 8, + .dev = { + .platform_data = &fpga_dom_i2c_bus_device_data3, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 9, + .dev = { + .platform_data = &fpga_dom_i2c_bus_device_data4, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 10, + .dev = { + .platform_data = &fpga_dom_i2c_bus_device_data5, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 11, + .dev = { + .platform_data = &fpga_dom_i2c_bus_device_data6, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 12, + .dev = { + .platform_data = &fpga_dom_i2c_bus_device_data7, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 13, + .dev = { + .platform_data = &fpga_dom_i2c_bus_device_data8, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 14, + .dev = { + .platform_data = &fpga_dom_i2c_bus_device_data9, + .release = wb_fpga_i2c_bus_device_release, + } + }, + { + .name = "wb-fpga-i2c", + .id = 15, + .dev = { + .platform_data = &fpga_dom_i2c_bus_device_data10, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 16, + .dev = { + .platform_data = &fpga_dom_i2c_bus_device_data11, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 17, + .dev = { + .platform_data = &fpga_dom_i2c_bus_device_data12, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 18, + .dev = { + .platform_data = &fpga_dom_i2c_bus_device_data13, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 19, + .dev = { + .platform_data = &fpga_dom_i2c_bus_device_data14, + .release = wb_fpga_i2c_bus_device_release, + }, + }, + { + .name = "wb-fpga-i2c", + .id = 20, + .dev = { + .platform_data = &fpga_dom_i2c_bus_device_data15, + .release = wb_fpga_i2c_bus_device_release, + }, + }, +}; + +static int __init wb_fpga_i2c_bus_device_init(void) +{ + int i; + int ret = 0; + fpga_i2c_bus_device_t *fpga_i2c_bus_device_data; + + WB_FPGA_I2C_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(fpga_i2c_bus_device); i++) { + fpga_i2c_bus_device_data = fpga_i2c_bus_device[i].dev.platform_data; + ret = platform_device_register(&fpga_i2c_bus_device[i]); + if (ret < 0) { + fpga_i2c_bus_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "rg-fpga-i2c.%d register failed!\n", i + 1); + } else { + fpga_i2c_bus_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_fpga_i2c_bus_device_exit(void) +{ + int i; + fpga_i2c_bus_device_t *fpga_i2c_bus_device_data; + + WB_FPGA_I2C_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(fpga_i2c_bus_device) - 1; i >= 0; i--) { + fpga_i2c_bus_device_data = fpga_i2c_bus_device[i].dev.platform_data; + if (fpga_i2c_bus_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&fpga_i2c_bus_device[i]); + } + } +} + +module_init(wb_fpga_i2c_bus_device_init); +module_exit(wb_fpga_i2c_bus_device_exit); +MODULE_DESCRIPTION("FPGA I2C Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_fpga_pca954x_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_fpga_pca954x_device.c new file mode 100644 index 000000000000..94a4ca54e512 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_fpga_pca954x_device.c @@ -0,0 +1,329 @@ +/* + * An wb_fpga_pca954x_device driver for fpga pca954x device function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +static int g_wb_fpga_pca954x_device_debug = 0; +static int g_wb_fpga_pca954x_device_error = 0; + +module_param(g_wb_fpga_pca954x_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_fpga_pca954x_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_FPGA_PCA954X_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_fpga_pca954x_device_debug) { \ + printk(KERN_INFO "[WB_FPGA_PCA954X_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_FPGA_PCA954X_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_fpga_pca954x_device_error) { \ + printk(KERN_ERR "[WB_FPGA_PCA954X_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static fpga_pca954x_device_t fpga_pca954x_device_data0 = { + .i2c_bus = 3, + .i2c_addr = 0x77, + .pca9548_base_nr = 22, + .fpga_9548_flag = 2, + .fpga_9548_reset_flag = 1, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data1 = { + .i2c_bus = 4, + .i2c_addr = 0x71, + .pca9548_base_nr = 30, + .fpga_9548_flag = 2, + .fpga_9548_reset_flag = 1, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data2 = { + .i2c_bus = 5, + .i2c_addr = 0x77, + .pca9548_base_nr = 38, + .fpga_9548_flag = 2, + .fpga_9548_reset_flag = 1, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data3 = { + .i2c_bus = 6, + .i2c_addr = 0x70, + .pca9548_base_nr = 46, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data4 = { + .i2c_bus = 7, + .i2c_addr = 0x70, + .pca9548_base_nr = 48, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data5 = { + .i2c_bus = 8, + .i2c_addr = 0x70, + .pca9548_base_nr = 50, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data6 = { + .i2c_bus = 9, + .i2c_addr = 0x70, + .pca9548_base_nr = 52, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data7 = { + .i2c_bus = 10, + .i2c_addr = 0x70, + .pca9548_base_nr = 54, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data8 = { + .i2c_bus = 11, + .i2c_addr = 0x70, + .pca9548_base_nr = 56, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data9 = { + .i2c_bus = 12, + .i2c_addr = 0x70, + .pca9548_base_nr = 58, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data10 = { + .i2c_bus = 13, + .i2c_addr = 0x70, + .pca9548_base_nr = 60, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data11 = { + .i2c_bus = 14, + .i2c_addr = 0x70, + .pca9548_base_nr = 62, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data12 = { + .i2c_bus = 15, + .i2c_addr = 0x70, + .pca9548_base_nr = 64, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data13 = { + .i2c_bus = 16, + .i2c_addr = 0x70, + .pca9548_base_nr = 66, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data14 = { + .i2c_bus = 17, + .i2c_addr = 0x70, + .pca9548_base_nr = 68, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data15 = { + .i2c_bus = 18, + .i2c_addr = 0x70, + .pca9548_base_nr = 70, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data16 = { + .i2c_bus = 19, + .i2c_addr = 0x70, + .pca9548_base_nr = 72, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data17 = { + .i2c_bus = 20, + .i2c_addr = 0x70, + .pca9548_base_nr = 74, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +static fpga_pca954x_device_t fpga_pca954x_device_data18 = { + .i2c_bus = 21, + .i2c_addr = 0x70, + .pca9548_base_nr = 76, + .fpga_9548_flag = 1, + .fpga_9548_reset_flag = 0, +}; + +struct i2c_board_info fpga_pca954x_device_info[] = { + { + .type = "wb_fpga_pca9548", + .platform_data = &fpga_pca954x_device_data0, + }, + { + .type = "wb_fpga_pca9548", + .platform_data = &fpga_pca954x_device_data1, + }, + { + .type = "wb_fpga_pca9548", + .platform_data = &fpga_pca954x_device_data2, + }, + { + .type = "wb_fpga_pca9542", + .platform_data = &fpga_pca954x_device_data3, + }, + { + .type = "wb_fpga_pca9542", + .platform_data = &fpga_pca954x_device_data4, + }, + { + .type = "wb_fpga_pca9542", + .platform_data = &fpga_pca954x_device_data5, + }, + { + .type = "wb_fpga_pca9542", + .platform_data = &fpga_pca954x_device_data6, + }, + { + .type = "wb_fpga_pca9542", + .platform_data = &fpga_pca954x_device_data7, + }, + { + .type = "wb_fpga_pca9542", + .platform_data = &fpga_pca954x_device_data8, + }, + { + .type = "wb_fpga_pca9542", + .platform_data = &fpga_pca954x_device_data9, + }, + { + .type = "wb_fpga_pca9542", + .platform_data = &fpga_pca954x_device_data10, + }, + { + .type = "wb_fpga_pca9542", + .platform_data = &fpga_pca954x_device_data11, + }, + { + .type = "wb_fpga_pca9542", + .platform_data = &fpga_pca954x_device_data12, + }, + { + .type = "wb_fpga_pca9542", + .platform_data = &fpga_pca954x_device_data13, + }, + { + .type = "wb_fpga_pca9542", + .platform_data = &fpga_pca954x_device_data14, + }, + { + .type = "wb_fpga_pca9542", + .platform_data = &fpga_pca954x_device_data15, + }, + { + .type = "wb_fpga_pca9542", + .platform_data = &fpga_pca954x_device_data16, + }, + { + .type = "wb_fpga_pca9542", + .platform_data = &fpga_pca954x_device_data17, + }, + { + .type = "wb_fpga_pca9542", + .platform_data = &fpga_pca954x_device_data18, + }, +}; + +static int __init wb_fpga_pca954x_device_init(void) +{ + int i; + struct i2c_adapter *adap; + struct i2c_client *client; + fpga_pca954x_device_t *fpga_pca954x_device_data; + + WB_FPGA_PCA954X_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(fpga_pca954x_device_info); i++) { + fpga_pca954x_device_data = fpga_pca954x_device_info[i].platform_data; + fpga_pca954x_device_info[i].addr = fpga_pca954x_device_data->i2c_addr; + adap = i2c_get_adapter(fpga_pca954x_device_data->i2c_bus); + if (adap == NULL) { + fpga_pca954x_device_data->client = NULL; + printk(KERN_ERR "get i2c bus %d adapter fail.\n", fpga_pca954x_device_data->i2c_bus); + continue; + } + client = i2c_new_client_device(adap, &fpga_pca954x_device_info[i]); + if (!client) { + fpga_pca954x_device_data->client = NULL; + printk(KERN_ERR "Failed to register fpga pca954x device %d at bus %d!\n", + fpga_pca954x_device_data->i2c_addr, fpga_pca954x_device_data->i2c_bus); + } else { + fpga_pca954x_device_data->client = client; + } + i2c_put_adapter(adap); + } + return 0; +} + +static void __exit wb_fpga_pca954x_device_exit(void) +{ + int i; + fpga_pca954x_device_t *fpga_pca954x_device_data; + + WB_FPGA_PCA954X_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(fpga_pca954x_device_info) - 1; i >= 0; i--) { + fpga_pca954x_device_data = fpga_pca954x_device_info[i].platform_data; + if (fpga_pca954x_device_data->client) { + i2c_unregister_device(fpga_pca954x_device_data->client); + fpga_pca954x_device_data->client = NULL; + } + } +} + +module_init(wb_fpga_pca954x_device_init); +module_exit(wb_fpga_pca954x_device_exit); +MODULE_DESCRIPTION("FPGA PCA954X Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_i2c_dev_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_i2c_dev_device.c new file mode 100644 index 000000000000..89e8f3221300 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_i2c_dev_device.c @@ -0,0 +1,175 @@ +/* + * An wb_i2c_dev_device driver for i2c dev device function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include + +#include + +static int g_wb_i2c_dev_device_debug = 0; +static int g_wb_i2c_dev_device_error = 0; + +module_param(g_wb_i2c_dev_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_i2c_dev_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_I2C_DEV_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_i2c_dev_device_debug) { \ + printk(KERN_INFO "[WB_I2C_DEV_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_I2C_DEV_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_i2c_dev_device_error) { \ + printk(KERN_ERR "[WB_I2C_DEV_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static i2c_dev_device_t i2c_dev_device_data0 = { + .i2c_bus = 2, + .i2c_addr = 0x1d, + .i2c_name = "cpld4", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; + +static i2c_dev_device_t i2c_dev_device_data1 = { + .i2c_bus = 2, + .i2c_addr = 0x2d, + .i2c_name = "cpld5", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; + +static i2c_dev_device_t i2c_dev_device_data2 = { + .i2c_bus = 2, + .i2c_addr = 0x1e, + .i2c_name = "cpld7", + .data_bus_width = 1, + .addr_bus_width = 2, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 0x2000, +}; + +static i2c_dev_device_t i2c_dev_device_data3 = { + .i2c_bus = 4, + .i2c_addr = 0x3d, + .i2c_name = "cpld6", + .data_bus_width = 1, + .addr_bus_width = 1, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 256, +}; + +static i2c_dev_device_t i2c_dev_device_data4 = { + .i2c_bus = 4, + .i2c_addr = 0x3e, + .i2c_name = "cpld8", + .data_bus_width = 1, + .addr_bus_width = 2, + .per_rd_len = 256, + .per_wr_len = 256, + .i2c_len = 0x2000, +}; + +struct i2c_board_info i2c_dev_device_info[] = { + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data0, + }, + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data1, + }, + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data2, + }, + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data3, + }, + { + .type = "wb-i2c-dev", + .platform_data = &i2c_dev_device_data4, + }, +}; + +static int __init wb_i2c_dev_device_init(void) +{ + int i; + struct i2c_adapter *adap; + struct i2c_client *client; + i2c_dev_device_t *i2c_dev_device_data; + + WB_I2C_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(i2c_dev_device_info); i++) { + i2c_dev_device_data = i2c_dev_device_info[i].platform_data; + i2c_dev_device_info[i].addr = i2c_dev_device_data->i2c_addr; + adap = i2c_get_adapter(i2c_dev_device_data->i2c_bus); + if (adap == NULL) { + i2c_dev_device_data->client = NULL; + printk(KERN_ERR "get i2c bus %d adapter fail.\n", i2c_dev_device_data->i2c_bus); + continue; + } + client = i2c_new_client_device(adap, &i2c_dev_device_info[i]); + if (!client) { + i2c_dev_device_data->client = NULL; + printk(KERN_ERR "Failed to register i2c dev device %d at bus %d!\n", + i2c_dev_device_data->i2c_addr, i2c_dev_device_data->i2c_bus); + } else { + i2c_dev_device_data->client = client; + } + i2c_put_adapter(adap); + } + return 0; +} + +static void __exit wb_i2c_dev_device_exit(void) +{ + int i; + i2c_dev_device_t *i2c_dev_device_data; + + WB_I2C_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(i2c_dev_device_info) - 1; i >= 0; i--) { + i2c_dev_device_data = i2c_dev_device_info[i].platform_data; + if (i2c_dev_device_data->client) { + i2c_unregister_device(i2c_dev_device_data->client); + i2c_dev_device_data->client = NULL; + } + } +} + +module_init(wb_i2c_dev_device_init); +module_exit(wb_i2c_dev_device_exit); +MODULE_DESCRIPTION("I2C DEV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_io_dev_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_io_dev_device.c new file mode 100644 index 000000000000..ae7ff5523f63 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_io_dev_device.c @@ -0,0 +1,138 @@ +/* + * An wb_io_dev_device driver for io device function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include + +#include + +static int g_wb_io_dev_device_debug = 0; +static int g_wb_io_dev_device_error = 0; + +module_param(g_wb_io_dev_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_io_dev_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_IO_DEV_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_io_dev_device_debug) { \ + printk(KERN_INFO "[WB_IO_DEV_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_IO_DEV_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_io_dev_device_error) { \ + printk(KERN_ERR "[WB_IO_DEV_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static io_dev_device_t io_dev_device_data0 = { + .io_dev_name = "cpld0", + .io_base = 0x700, + .io_len = 0x100, + .indirect_addr = 0, +}; + +static io_dev_device_t io_dev_device_data1 = { + .io_dev_name = "cpld1", + .io_base = 0x900, + .io_len = 0x100, + .indirect_addr = 0, +}; + +static io_dev_device_t io_dev_device_data2 = { + .io_dev_name = "cpld2", + .io_base = 0xb00, + .io_len = 0x100, + .indirect_addr = 0, +}; + +static void wb_io_dev_device_release(struct device *dev) +{ + return; +} + +static struct platform_device io_dev_device[] = { + { + .name = "wb-io-dev", + .id = 1, + .dev = { + .platform_data = &io_dev_device_data0, + .release = wb_io_dev_device_release, + }, + }, + { + .name = "wb-io-dev", + .id = 2, + .dev = { + .platform_data = &io_dev_device_data1, + .release = wb_io_dev_device_release, + }, + }, + { + .name = "wb-io-dev", + .id = 3, + .dev = { + .platform_data = &io_dev_device_data2, + .release = wb_io_dev_device_release, + }, + }, +}; + +static int __init wb_io_dev_device_init(void) +{ + int i; + int ret = 0; + io_dev_device_t *io_dev_device_data; + + WB_IO_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(io_dev_device); i++) { + io_dev_device_data = io_dev_device[i].dev.platform_data; + ret = platform_device_register(&io_dev_device[i]); + if (ret < 0) { + io_dev_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-io-dev.%d register failed!\n", i + 1); + } else { + io_dev_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_io_dev_device_exit(void) +{ + int i; + io_dev_device_t *io_dev_device_data; + + WB_IO_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(io_dev_device) - 1; i >= 0; i--) { + io_dev_device_data = io_dev_device[i].dev.platform_data; + if (io_dev_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&io_dev_device[i]); + } + } +} + +module_init(wb_io_dev_device_init); +module_exit(wb_io_dev_device_exit); +MODULE_DESCRIPTION("IO DEV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_lpc_drv_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_lpc_drv_device.c new file mode 100644 index 000000000000..27dbd87d71b2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_lpc_drv_device.c @@ -0,0 +1,150 @@ +/* + * An wb_lpc_drv_device driver for lpc device function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include + +#include + +static int g_wb_lpc_drv_device_debug = 0; +static int g_wb_lpc_drv_device_error = 0; + +module_param(g_wb_lpc_drv_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_lpc_drv_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_LPC_DRV_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_lpc_drv_device_debug) { \ + printk(KERN_INFO "[WB_LPC_DRV_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_LPC_DRV_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_lpc_drv_device_error) { \ + printk(KERN_ERR "[WB_LPC_DRV_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static lpc_drv_device_t lpc_drv_device_data_0 = { + .lpc_io_name = "wb_lpc", + .pci_domain = 0x0000, + .pci_bus = 0x00, + .pci_slot = 0x1f, + .pci_fn = 0, + .lpc_io_base = 0x700, + .lpc_io_size = 0x100, + .lpc_gen_dec = 0x84, +}; + +static lpc_drv_device_t lpc_drv_device_data_1 = { + .lpc_io_name = "wb_lpc", + .pci_domain = 0x0000, + .pci_bus = 0x00, + .pci_slot = 0x1f, + .pci_fn = 0, + .lpc_io_base = 0x900, + .lpc_io_size = 0x100, + .lpc_gen_dec = 0x88, +}; + +static lpc_drv_device_t lpc_drv_device_data_2 = { + .lpc_io_name = "wb_lpc", + .pci_domain = 0x0000, + .pci_bus = 0x00, + .pci_slot = 0x1f, + .pci_fn = 0, + .lpc_io_base = 0xb00, + .lpc_io_size = 0x100, + .lpc_gen_dec = 0x90, +}; + +static void wb_lpc_drv_device_release(struct device *dev) +{ + return; +} + +static struct platform_device lpc_drv_device[] = { + { + .name = "wb-lpc", + .id = 1, + .dev = { + .platform_data = &lpc_drv_device_data_0, + .release = wb_lpc_drv_device_release, + }, + }, + { + .name = "wb-lpc", + .id = 2, + .dev = { + .platform_data = &lpc_drv_device_data_1, + .release = wb_lpc_drv_device_release, + }, + }, + { + .name = "wb-lpc", + .id = 3, + .dev = { + .platform_data = &lpc_drv_device_data_2, + .release = wb_lpc_drv_device_release, + }, + }, +}; + +static int __init wb_lpc_drv_device_init(void) +{ + int i; + int ret = 0; + lpc_drv_device_t *lpc_drv_device_data; + + WB_LPC_DRV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(lpc_drv_device); i++) { + lpc_drv_device_data = lpc_drv_device[i].dev.platform_data; + ret = platform_device_register(&lpc_drv_device[i]); + if (ret < 0) { + lpc_drv_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-lpc.%d register failed!\n", i + 1); + } else { + lpc_drv_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_lpc_drv_device_exit(void) +{ + int i; + lpc_drv_device_t *lpc_drv_device_data; + + WB_LPC_DRV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(lpc_drv_device) - 1; i >= 0; i--) { + lpc_drv_device_data = lpc_drv_device[i].dev.platform_data; + if (lpc_drv_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&lpc_drv_device[i]); + } + } +} + +module_init(wb_lpc_drv_device_init); +module_exit(wb_lpc_drv_device_exit); +MODULE_DESCRIPTION("LPC DRV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_pcie_dev_device.c b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_pcie_dev_device.c new file mode 100644 index 000000000000..561e64d449b4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/modules/driver/wb_pcie_dev_device.c @@ -0,0 +1,113 @@ +/* + * An wb_pcie_dev_device driver for pcie device function + * + * Copyright (C) 2024 Micas 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include + +#include + +static int g_wb_pcie_dev_device_debug = 0; +static int g_wb_pcie_dev_device_error = 0; + +module_param(g_wb_pcie_dev_device_debug, int, S_IRUGO | S_IWUSR); +module_param(g_wb_pcie_dev_device_error, int, S_IRUGO | S_IWUSR); + +#define WB_PCIE_DEV_DEVICE_DEBUG_VERBOSE(fmt, args...) do { \ + if (g_wb_pcie_dev_device_debug) { \ + printk(KERN_INFO "[WB_PCIE_DEV_DEVICE][VER][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +#define WB_PCIE_DEV_DEVICE_DEBUG_ERROR(fmt, args...) do { \ + if (g_wb_pcie_dev_device_error) { \ + printk(KERN_ERR "[WB_PCIE_DEV_DEVICE][ERR][func:%s line:%d]\r\n"fmt, __func__, __LINE__, ## args); \ + } \ +} while (0) + +static pci_dev_device_t pcie_dev_device_data0 = { + .pci_dev_name = "fpga0", + .pci_domain = 0x0000, + .pci_bus = 0x08, + .pci_slot = 0x00, + .pci_fn = 0, + .pci_bar = 0, + .bus_width = 4, + .upg_ctrl_base = 0xa00, + .upg_flash_base = 0x2f0000, +}; + +static void wb_pcie_dev_device_release(struct device *dev) +{ + return; +} + +static struct platform_device pcie_dev_device[] = { + { + .name = "wb-pci-dev", + .id = 1, + .dev = { + .platform_data = &pcie_dev_device_data0, + .release = wb_pcie_dev_device_release, + }, + }, +}; + +static int __init wb_pcie_dev_device_init(void) +{ + int i; + int ret = 0; + pci_dev_device_t *pcie_dev_device_data; + + WB_PCIE_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = 0; i < ARRAY_SIZE(pcie_dev_device); i++) { + pcie_dev_device_data = pcie_dev_device[i].dev.platform_data; + ret = platform_device_register(&pcie_dev_device[i]); + if (ret < 0) { + pcie_dev_device_data->device_flag = -1; /* device register failed, set flag -1 */ + printk(KERN_ERR "wb-pci-dev.%d register failed!\n", i + 1); + } else { + pcie_dev_device_data->device_flag = 0; /* device register suucess, set flag 0 */ + } + } + return 0; +} + +static void __exit wb_pcie_dev_device_exit(void) +{ + int i; + pci_dev_device_t *pcie_dev_device_data; + + WB_PCIE_DEV_DEVICE_DEBUG_VERBOSE("enter!\n"); + for (i = ARRAY_SIZE(pcie_dev_device) - 1; i >= 0; i--) { + pcie_dev_device_data = pcie_dev_device[i].dev.platform_data; + if (pcie_dev_device_data->device_flag == 0) { /* device register success, need unregister */ + platform_device_unregister(&pcie_dev_device[i]); + } + } +} + +module_init(wb_pcie_dev_device_init); +module_exit(wb_pcie_dev_device_exit); +MODULE_DESCRIPTION("PCIE DEV Devices"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("support"); diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/plat_sysfs_cfg/WB_PLAT_CPLD.cfg b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/plat_sysfs_cfg/WB_PLAT_CPLD.cfg new file mode 100644 index 000000000000..54364261adbc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/plat_sysfs_cfg/WB_PLAT_CPLD.cfg @@ -0,0 +1,37 @@ +# configuration item: I2C address of CPLD +# format: cpld_i2c_dev.bus_[cpld_slot]_[cpld_id] cpld_i2c_dev.addr_[cpld_slot]_[cpld_id] +# cpld_slot: Main card: 0, linear card: start from 1 +# cpld_id: start from 0 +# bus: I2C bus number of CPLD +# addr: I2C address of CPLD +cpld_i2c_dev.bus_0_2=2 +cpld_i2c_dev.addr_0_2=0x1d +cpld_i2c_dev.bus_0_3=2 +cpld_i2c_dev.addr_0_3=0x2d +cpld_i2c_dev.bus_0_4=4 +cpld_i2c_dev.addr_0_4=0x3d + +# configuration item: LPC address of CPLD +# format: cpld_lpc_addr_[cpld_slot]_[cpld_id] +# cpld_slot: Main card: 0, linear card: start from 1 +# cpld_id: start from 0 +cpld_lpc_dev_0_0=0x700 +cpld_lpc_dev_0_1=0x900 + + +# configuration item: CPLD access method, lpc or i2c +# format: mode_cpld_[cpld_slot][cpld_slot]=lpc/i2c +# cpld_slot: Main card: 0, linear card: start from 1 +# cpld_id: start from 0 +mode_cpld_0_0=lpc +mode_cpld_0_1=lpc +mode_cpld_0_2=i2c +mode_cpld_0_3=i2c +mode_cpld_0_4=i2c + + +# configuration item: the number of CPLD +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: CPLD main_dev is 4 +# minor_dev: CPLD minor_dev not exist +dev_num_4_0=5 diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/plat_sysfs_cfg/WB_PLAT_FAN.cfg b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/plat_sysfs_cfg/WB_PLAT_FAN.cfg new file mode 100644 index 000000000000..bcbfa1d77bbb --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/plat_sysfs_cfg/WB_PLAT_FAN.cfg @@ -0,0 +1,437 @@ +# configuration item: the number of fans +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: fan main_dev is 1 +# minor_dev: fan minor_dev not exist(0) +dev_num_1_0=6 + + +# configuration item: the number of rotors +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: rotor main_dev is 1 +# minor_dev: rotor minor_dev is 5 +dev_num_1_5=2 + + +# configuration item: fan presence status +# format: dev_present_status_[main_dev_id][fan_index] +# main_dev_id: fan main_dev_id is 1 +# fan_index: start from 1 +dev_present_status.mode_1_1=config +dev_present_status.src_1_1=cpld +dev_present_status.frmt_1_1=bit +dev_present_status.pola_1_1=negative +dev_present_status.addr_1_1=0x00040037 +dev_present_status.len_1_1=1 +dev_present_status.bit_offset_1_1=5 + +dev_present_status.mode_1_2=config +dev_present_status.src_1_2=cpld +dev_present_status.frmt_1_2=bit +dev_present_status.pola_1_2=negative +dev_present_status.addr_1_2=0x00040037 +dev_present_status.len_1_2=1 +dev_present_status.bit_offset_1_2=4 + +dev_present_status.mode_1_3=config +dev_present_status.src_1_3=cpld +dev_present_status.frmt_1_3=bit +dev_present_status.pola_1_3=negative +dev_present_status.addr_1_3=0x00040037 +dev_present_status.len_1_3=1 +dev_present_status.bit_offset_1_3=3 + +dev_present_status.mode_1_4=config +dev_present_status.src_1_4=cpld +dev_present_status.frmt_1_4=bit +dev_present_status.pola_1_4=negative +dev_present_status.addr_1_4=0x00040037 +dev_present_status.len_1_4=1 +dev_present_status.bit_offset_1_4=2 + +dev_present_status.mode_1_5=config +dev_present_status.src_1_5=cpld +dev_present_status.frmt_1_5=bit +dev_present_status.pola_1_5=negative +dev_present_status.addr_1_5=0x00040037 +dev_present_status.len_1_5=1 +dev_present_status.bit_offset_1_5=1 + +dev_present_status.mode_1_6=config +dev_present_status.src_1_6=cpld +dev_present_status.frmt_1_6=bit +dev_present_status.pola_1_6=negative +dev_present_status.addr_1_6=0x00040037 +dev_present_status.len_1_6=1 +dev_present_status.bit_offset_1_6=0 + +# configuration item: fan rotor status +# format: fan_roll_status_[fan_id]_[motor_id] +# fan_id: start from 1 +# motor_id: start from 0 +fan_roll_status.mode_1_0=config +fan_roll_status.int_cons_1_0= +fan_roll_status.src_1_0=cpld +fan_roll_status.frmt_1_0=bit +fan_roll_status.pola_1_0=positive +fan_roll_status.fpath_1_0= +fan_roll_status.addr_1_0=0x00040038 +fan_roll_status.len_1_0=1 +fan_roll_status.bit_offset_1_0=5 + +fan_roll_status.mode_1_1=config +fan_roll_status.int_cons_1_1= +fan_roll_status.src_1_1=cpld +fan_roll_status.frmt_1_1=bit +fan_roll_status.pola_1_1=positive +fan_roll_status.fpath_1_1= +fan_roll_status.addr_1_1=0x00040039 +fan_roll_status.len_1_1=1 +fan_roll_status.bit_offset_1_1=5 + +fan_roll_status.mode_2_0=config +fan_roll_status.int_cons_2_0= +fan_roll_status.src_2_0=cpld +fan_roll_status.frmt_2_0=bit +fan_roll_status.pola_2_0=positive +fan_roll_status.fpath_2_0= +fan_roll_status.addr_2_0=0x00040038 +fan_roll_status.len_2_0=1 +fan_roll_status.bit_offset_2_0=4 + +fan_roll_status.mode_2_1=config +fan_roll_status.int_cons_2_1= +fan_roll_status.src_2_1=cpld +fan_roll_status.frmt_2_1=bit +fan_roll_status.pola_2_1=positive +fan_roll_status.fpath_2_1= +fan_roll_status.addr_2_1=0x00040039 +fan_roll_status.len_2_1=1 +fan_roll_status.bit_offset_2_1=4 + +fan_roll_status.mode_3_0=config +fan_roll_status.int_cons_3_0= +fan_roll_status.src_3_0=cpld +fan_roll_status.frmt_3_0=bit +fan_roll_status.pola_3_0=positive +fan_roll_status.fpath_3_0= +fan_roll_status.addr_3_0=0x00040038 +fan_roll_status.len_3_0=1 +fan_roll_status.bit_offset_3_0=3 + +fan_roll_status.mode_3_1=config +fan_roll_status.int_cons_3_1= +fan_roll_status.src_3_1=cpld +fan_roll_status.frmt_3_1=bit +fan_roll_status.pola_3_1=positive +fan_roll_status.fpath_3_1= +fan_roll_status.addr_3_1=0x00040039 +fan_roll_status.len_3_1=1 +fan_roll_status.bit_offset_3_1=3 + +fan_roll_status.mode_4_0=config +fan_roll_status.int_cons_4_0= +fan_roll_status.src_4_0=cpld +fan_roll_status.frmt_4_0=bit +fan_roll_status.pola_4_0=positive +fan_roll_status.fpath_4_0= +fan_roll_status.addr_4_0=0x00040038 +fan_roll_status.len_4_0=1 +fan_roll_status.bit_offset_4_0=2 + +fan_roll_status.mode_4_1=config +fan_roll_status.int_cons_4_1= +fan_roll_status.src_4_1=cpld +fan_roll_status.frmt_4_1=bit +fan_roll_status.pola_4_1=positive +fan_roll_status.fpath_4_1= +fan_roll_status.addr_4_1=0x00040039 +fan_roll_status.len_4_1=1 +fan_roll_status.bit_offset_4_1=2 + +fan_roll_status.mode_5_0=config +fan_roll_status.int_cons_5_0= +fan_roll_status.src_5_0=cpld +fan_roll_status.frmt_5_0=bit +fan_roll_status.pola_5_0=positive +fan_roll_status.fpath_5_0= +fan_roll_status.addr_5_0=0x00040038 +fan_roll_status.len_5_0=1 +fan_roll_status.bit_offset_5_0=1 + +fan_roll_status.mode_5_1=config +fan_roll_status.int_cons_5_1= +fan_roll_status.src_5_1=cpld +fan_roll_status.frmt_5_1=bit +fan_roll_status.pola_5_1=positive +fan_roll_status.fpath_5_1= +fan_roll_status.addr_5_1=0x00040039 +fan_roll_status.len_5_1=1 +fan_roll_status.bit_offset_5_1=1 + +fan_roll_status.mode_6_0=config +fan_roll_status.int_cons_6_0= +fan_roll_status.src_6_0=cpld +fan_roll_status.frmt_6_0=bit +fan_roll_status.pola_6_0=positive +fan_roll_status.fpath_6_0= +fan_roll_status.addr_6_0=0x00040038 +fan_roll_status.len_6_0=1 +fan_roll_status.bit_offset_6_0=0 + +fan_roll_status.mode_6_1=config +fan_roll_status.int_cons_6_1= +fan_roll_status.src_6_1=cpld +fan_roll_status.frmt_6_1=bit +fan_roll_status.pola_6_1=positive +fan_roll_status.fpath_6_1= +fan_roll_status.addr_6_1=0x00040039 +fan_roll_status.len_6_1=1 +fan_roll_status.bit_offset_6_1=0 + +# configuration item: fan speed +# format: fan_speed_[fan_id]_[motor_id] +# fan_id: start from 1 +# motor_id: start from 0 +fan_speed.mode_1_0=config +fan_speed.int_cons_1_0= +fan_speed.src_1_0=cpld +fan_speed.frmt_1_0=num_bytes +fan_speed.pola_1_0=negative +fan_speed.fpath_1_0= +fan_speed.addr_1_0=0x00040070 +fan_speed.len_1_0=2 +fan_speed.bit_offset_1_0= + +fan_speed.mode_1_1=config +fan_speed.int_cons_1_1= +fan_speed.src_1_1=cpld +fan_speed.frmt_1_1=num_bytes +fan_speed.pola_1_1=negative +fan_speed.fpath_1_1= +fan_speed.addr_1_1=0x0004007c +fan_speed.len_1_1=2 +fan_speed.bit_offset_1_1= + +fan_speed.mode_2_0=config +fan_speed.int_cons_2_0= +fan_speed.src_2_0=cpld +fan_speed.frmt_2_0=num_bytes +fan_speed.pola_2_0=negative +fan_speed.fpath_2_0= +fan_speed.addr_2_0=0x0004006e +fan_speed.len_2_0=2 +fan_speed.bit_offset_2_0= + +fan_speed.mode_2_1=config +fan_speed.int_cons_2_1= +fan_speed.src_2_1=cpld +fan_speed.frmt_2_1=num_bytes +fan_speed.pola_2_1=negative +fan_speed.fpath_2_1= +fan_speed.addr_2_1=0x0004007a +fan_speed.len_2_1=2 +fan_speed.bit_offset_2_1= + +fan_speed.mode_3_0=config +fan_speed.int_cons_3_0= +fan_speed.src_3_0=cpld +fan_speed.frmt_3_0=num_bytes +fan_speed.pola_3_0=negative +fan_speed.fpath_3_0= +fan_speed.addr_3_0=0x0004006c +fan_speed.len_3_0=2 +fan_speed.bit_offset_3_0= + +fan_speed.mode_3_1=config +fan_speed.int_cons_3_1= +fan_speed.src_3_1=cpld +fan_speed.frmt_3_1=num_bytes +fan_speed.pola_3_1=negative +fan_speed.fpath_3_1= +fan_speed.addr_3_1=0x00040078 +fan_speed.len_3_1=2 +fan_speed.bit_offset_3_1= + +fan_speed.mode_4_0=config +fan_speed.int_cons_4_0= +fan_speed.src_4_0=cpld +fan_speed.frmt_4_0=num_bytes +fan_speed.pola_4_0=negative +fan_speed.fpath_4_0= +fan_speed.addr_4_0=0x0004006a +fan_speed.len_4_0=2 +fan_speed.bit_offset_4_0= + +fan_speed.mode_4_1=config +fan_speed.int_cons_4_1= +fan_speed.src_4_1=cpld +fan_speed.frmt_4_1=num_bytes +fan_speed.pola_4_1=negative +fan_speed.fpath_4_1= +fan_speed.addr_4_1=0x00040076 +fan_speed.len_4_1=2 +fan_speed.bit_offset_4_1= + +fan_speed.mode_5_0=config +fan_speed.int_cons_5_0= +fan_speed.src_5_0=cpld +fan_speed.frmt_5_0=num_bytes +fan_speed.pola_5_0=negative +fan_speed.fpath_5_0= +fan_speed.addr_5_0=0x00040068 +fan_speed.len_5_0=2 +fan_speed.bit_offset_5_0= + +fan_speed.mode_5_1=config +fan_speed.int_cons_5_1= +fan_speed.src_5_1=cpld +fan_speed.frmt_5_1=num_bytes +fan_speed.pola_5_1=negative +fan_speed.fpath_5_1= +fan_speed.addr_5_1=0x00040074 +fan_speed.len_5_1=2 +fan_speed.bit_offset_5_1= + +fan_speed.mode_6_0=config +fan_speed.int_cons_6_0= +fan_speed.src_6_0=cpld +fan_speed.frmt_6_0=num_bytes +fan_speed.pola_6_0=negative +fan_speed.fpath_6_0= +fan_speed.addr_6_0=0x00040066 +fan_speed.len_6_0=2 +fan_speed.bit_offset_6_0= + +fan_speed.mode_6_1=config +fan_speed.int_cons_6_1= +fan_speed.src_6_1=cpld +fan_speed.frmt_6_1=num_bytes +fan_speed.pola_6_1=negative +fan_speed.fpath_6_1= +fan_speed.addr_6_1=0x00040072 +fan_speed.len_6_1=2 +fan_speed.bit_offset_6_1= + +# configuration item: fan pwm +# format: fan_ratio_[fan_id]_[motor_id] +# fan_id: start from 1 +# motor_id: start from 0 +fan_ratio.mode_1_0=config +fan_ratio.int_cons_1_0= +fan_ratio.src_1_0=cpld +fan_ratio.frmt_1_0=byte +fan_ratio.pola_1_0= +fan_ratio.fpath_1_0= +fan_ratio.addr_1_0=0x00040065 +fan_ratio.len_1_0=1 +fan_ratio.bit_offset_1_0= + +fan_ratio.mode_1_1=config +fan_ratio.int_cons_1_1= +fan_ratio.src_1_1=cpld +fan_ratio.frmt_1_1=byte +fan_ratio.pola_1_1= +fan_ratio.fpath_1_1= +fan_ratio.addr_1_1=0x00040065 +fan_ratio.len_1_1=1 +fan_ratio.bit_offset_1_1= + +fan_ratio.mode_2_0=config +fan_ratio.int_cons_2_0= +fan_ratio.src_2_0=cpld +fan_ratio.frmt_2_0=byte +fan_ratio.pola_2_0= +fan_ratio.fpath_2_0= +fan_ratio.addr_2_0=0x00040064 +fan_ratio.len_2_0=1 +fan_ratio.bit_offset_2_0= + +fan_ratio.mode_2_1=config +fan_ratio.int_cons_2_1= +fan_ratio.src_2_1=cpld +fan_ratio.frmt_2_1=byte +fan_ratio.pola_2_1= +fan_ratio.fpath_2_1= +fan_ratio.addr_2_1=0x00040064 +fan_ratio.len_2_1=1 +fan_ratio.bit_offset_2_1= + +fan_ratio.mode_3_0=config +fan_ratio.int_cons_3_0= +fan_ratio.src_3_0=cpld +fan_ratio.frmt_3_0=byte +fan_ratio.pola_3_0= +fan_ratio.fpath_3_0= +fan_ratio.addr_3_0=0x00040063 +fan_ratio.len_3_0=1 +fan_ratio.bit_offset_3_0= + +fan_ratio.mode_3_1=config +fan_ratio.int_cons_3_1= +fan_ratio.src_3_1=cpld +fan_ratio.frmt_3_1=byte +fan_ratio.pola_3_1= +fan_ratio.fpath_3_1= +fan_ratio.addr_3_1=0x00040063 +fan_ratio.len_3_1=1 +fan_ratio.bit_offset_3_1= + +fan_ratio.mode_4_0=config +fan_ratio.int_cons_4_0= +fan_ratio.src_4_0=cpld +fan_ratio.frmt_4_0=byte +fan_ratio.pola_4_0= +fan_ratio.fpath_4_0= +fan_ratio.addr_4_0=0x00040062 +fan_ratio.len_4_0=1 +fan_ratio.bit_offset_4_0= + +fan_ratio.mode_4_1=config +fan_ratio.int_cons_4_1= +fan_ratio.src_4_1=cpld +fan_ratio.frmt_4_1=byte +fan_ratio.pola_4_1= +fan_ratio.fpath_4_1= +fan_ratio.addr_4_1=0x00040062 +fan_ratio.len_4_1=1 +fan_ratio.bit_offset_4_1= + +fan_ratio.mode_5_0=config +fan_ratio.int_cons_5_0= +fan_ratio.src_5_0=cpld +fan_ratio.frmt_5_0=byte +fan_ratio.pola_5_0= +fan_ratio.fpath_5_0= +fan_ratio.addr_5_0=0x00040061 +fan_ratio.len_5_0=1 +fan_ratio.bit_offset_5_0= + +fan_ratio.mode_5_1=config +fan_ratio.int_cons_5_1= +fan_ratio.src_5_1=cpld +fan_ratio.frmt_5_1=byte +fan_ratio.pola_5_1= +fan_ratio.fpath_5_1= +fan_ratio.addr_5_1=0x00040061 +fan_ratio.len_5_1=1 +fan_ratio.bit_offset_5_1= + +fan_ratio.mode_6_0=config +fan_ratio.int_cons_6_0= +fan_ratio.src_6_0=cpld +fan_ratio.frmt_6_0=byte +fan_ratio.pola_6_0= +fan_ratio.fpath_6_0= +fan_ratio.addr_6_0=0x00040060 +fan_ratio.len_6_0=1 +fan_ratio.bit_offset_6_0= + +fan_ratio.mode_6_1=config +fan_ratio.int_cons_6_1= +fan_ratio.src_6_1=cpld +fan_ratio.frmt_6_1=byte +fan_ratio.pola_6_1= +fan_ratio.fpath_6_1= +fan_ratio.addr_6_1=0x00040060 +fan_ratio.len_6_1=1 +fan_ratio.bit_offset_6_1= \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/plat_sysfs_cfg/WB_PLAT_PSU.cfg b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/plat_sysfs_cfg/WB_PLAT_PSU.cfg new file mode 100644 index 000000000000..26a838bfcfa5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/plat_sysfs_cfg/WB_PLAT_PSU.cfg @@ -0,0 +1,64 @@ +# configuration item: the number of psus +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: psu main_dev is 2 +# minor_dev: psu minor_dev not exist(0) +dev_num_2_0=2 + + +# configuration item: psu status +# format: psu_status_[psu_index]_[status_id] +# psu_index: start from 1 +# status_id: 0: presence 1: output 2: alert +# psu1 presence status +psu_status.mode_1_0=config +psu_status.src_1_0=cpld +psu_status.frmt_1_0=bit +psu_status.pola_1_0=negative +psu_status.addr_1_0=0x00020034 +psu_status.len_1_0=1 +psu_status.bit_offset_1_0=0 + +# psu1 output status +psu_status.mode_1_1=config +psu_status.src_1_1=cpld +psu_status.frmt_1_1=bit +psu_status.pola_1_1=positive +psu_status.addr_1_1=0x00020034 +psu_status.len_1_1=1 +psu_status.bit_offset_1_1=1 + +# psu1 alert status +psu_status.mode_1_2=config +psu_status.src_1_2=cpld +psu_status.frmt_1_2=bit +psu_status.pola_1_2=negative +psu_status.addr_1_2=0x00020034 +psu_status.len_1_2=1 +psu_status.bit_offset_1_2=2 + +# psu2 presence status +psu_status.mode_2_0=config +psu_status.src_2_0=cpld +psu_status.frmt_2_0=bit +psu_status.pola_2_0=negative +psu_status.addr_2_0=0x00020034 +psu_status.len_2_0=1 +psu_status.bit_offset_2_0=4 + +# psu2 output status +psu_status.mode_2_1=config +psu_status.src_2_1=cpld +psu_status.frmt_2_1=bit +psu_status.pola_2_1=positive +psu_status.addr_2_1=0x00020034 +psu_status.len_2_1=1 +psu_status.bit_offset_2_1=5 + +# psu2 alert status +psu_status.mode_2_2=config +psu_status.src_2_2=cpld +psu_status.frmt_2_2=bit +psu_status.pola_2_2=negative +psu_status.addr_2_2=0x00020034 +psu_status.len_2_2=1 +psu_status.bit_offset_2_2=6 diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/plat_sysfs_cfg/WB_PLAT_SFF.cfg b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/plat_sysfs_cfg/WB_PLAT_SFF.cfg new file mode 100644 index 000000000000..fa45f76b9323 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/plat_sysfs_cfg/WB_PLAT_SFF.cfg @@ -0,0 +1,383 @@ +# configuration item: the number of sffs +# format: dev_num_[main_dev]_[minor_dev] +# main_dev: sff main_dev is 3 +# minor_dev: sff minor_dev not exist(0) +dev_num_3_0=32 + + +# configuration item: The directory name of sff sysfs +# format: sff_dir_name_[sff_index] +# sff_index: start from 1 +sff_dir_name_1 =sff1 +sff_dir_name_2 =sff2 +sff_dir_name_3 =sff3 +sff_dir_name_4 =sff4 +sff_dir_name_5 =sff5 +sff_dir_name_6 =sff6 +sff_dir_name_7 =sff7 +sff_dir_name_8 =sff8 +sff_dir_name_9 =sff9 +sff_dir_name_10 =sff10 +sff_dir_name_11 =sff11 +sff_dir_name_12 =sff12 +sff_dir_name_13 =sff13 +sff_dir_name_14 =sff14 +sff_dir_name_15 =sff15 +sff_dir_name_16 =sff16 +sff_dir_name_17 =sff17 +sff_dir_name_18 =sff18 +sff_dir_name_19 =sff19 +sff_dir_name_20 =sff20 +sff_dir_name_21 =sff21 +sff_dir_name_22 =sff22 +sff_dir_name_23 =sff23 +sff_dir_name_24 =sff24 +sff_dir_name_25 =sff25 +sff_dir_name_26 =sff26 +sff_dir_name_27 =sff27 +sff_dir_name_28 =sff28 +sff_dir_name_29 =sff29 +sff_dir_name_30 =sff30 +sff_dir_name_31 =sff31 +sff_dir_name_32 =sff32 + + +# configuration item: sff cpld register status +# format: sff_cpld_reg_[sff_index]_[cpld_reg] +# sff_index: start from 1 +# cpld_reg: 1: power_on, 2: tx_fault, 3: tx_dis, 4:pre_n, 5:rx_los +# 6: reset, 7: lpmode, 8: module_present, 9: interrupt + +# sff cpld presence status +sff_cpld_reg.mode_1_8=config +sff_cpld_reg.src_1_8=cpld +sff_cpld_reg.frmt_1_8=bit +sff_cpld_reg.pola_1_8=negative +sff_cpld_reg.addr_1_8=0x00020030 +sff_cpld_reg.len_1_8=1 +sff_cpld_reg.bit_offset_1_8=0 + +sff_cpld_reg.mode_2_8=config +sff_cpld_reg.src_2_8=cpld +sff_cpld_reg.frmt_2_8=bit +sff_cpld_reg.pola_2_8=negative +sff_cpld_reg.addr_2_8=0x00020030 +sff_cpld_reg.len_2_8=1 +sff_cpld_reg.bit_offset_2_8=1 + +sff_cpld_reg.mode_3_8=config +sff_cpld_reg.src_3_8=cpld +sff_cpld_reg.frmt_3_8=bit +sff_cpld_reg.pola_3_8=negative +sff_cpld_reg.addr_3_8=0x00020030 +sff_cpld_reg.len_3_8=1 +sff_cpld_reg.bit_offset_3_8=2 + +sff_cpld_reg.mode_4_8=config +sff_cpld_reg.src_4_8=cpld +sff_cpld_reg.frmt_4_8=bit +sff_cpld_reg.pola_4_8=negative +sff_cpld_reg.addr_4_8=0x00020030 +sff_cpld_reg.len_4_8=1 +sff_cpld_reg.bit_offset_4_8=3 + +sff_cpld_reg.mode_5_8=config +sff_cpld_reg.src_5_8=cpld +sff_cpld_reg.frmt_5_8=bit +sff_cpld_reg.pola_5_8=negative +sff_cpld_reg.addr_5_8=0x00020030 +sff_cpld_reg.len_5_8=1 +sff_cpld_reg.bit_offset_5_8=4 + +sff_cpld_reg.mode_6_8=config +sff_cpld_reg.src_6_8=cpld +sff_cpld_reg.frmt_6_8=bit +sff_cpld_reg.pola_6_8=negative +sff_cpld_reg.addr_6_8=0x00020030 +sff_cpld_reg.len_6_8=1 +sff_cpld_reg.bit_offset_6_8=5 + +sff_cpld_reg.mode_7_8=config +sff_cpld_reg.src_7_8=cpld +sff_cpld_reg.frmt_7_8=bit +sff_cpld_reg.pola_7_8=negative +sff_cpld_reg.addr_7_8=0x00020030 +sff_cpld_reg.len_7_8=1 +sff_cpld_reg.bit_offset_7_8=6 + +sff_cpld_reg.mode_8_8=config +sff_cpld_reg.src_8_8=cpld +sff_cpld_reg.frmt_8_8=bit +sff_cpld_reg.pola_8_8=negative +sff_cpld_reg.addr_8_8=0x00020030 +sff_cpld_reg.len_8_8=1 +sff_cpld_reg.bit_offset_8_8=7 + +sff_cpld_reg.mode_9_8=config +sff_cpld_reg.src_9_8=cpld +sff_cpld_reg.frmt_9_8=bit +sff_cpld_reg.pola_9_8=negative +sff_cpld_reg.addr_9_8=0x00020031 +sff_cpld_reg.len_9_8=1 +sff_cpld_reg.bit_offset_9_8=0 + +sff_cpld_reg.mode_10_8=config +sff_cpld_reg.src_10_8=cpld +sff_cpld_reg.frmt_10_8=bit +sff_cpld_reg.pola_10_8=negative +sff_cpld_reg.addr_10_8=0x00020031 +sff_cpld_reg.len_10_8=1 +sff_cpld_reg.bit_offset_10_8=1 + +sff_cpld_reg.mode_11_8=config +sff_cpld_reg.src_11_8=cpld +sff_cpld_reg.frmt_11_8=bit +sff_cpld_reg.pola_11_8=negative +sff_cpld_reg.addr_11_8=0x00020031 +sff_cpld_reg.len_11_8=1 +sff_cpld_reg.bit_offset_11_8=2 + +sff_cpld_reg.mode_12_8=config +sff_cpld_reg.src_12_8=cpld +sff_cpld_reg.frmt_12_8=bit +sff_cpld_reg.pola_12_8=negative +sff_cpld_reg.addr_12_8=0x00020031 +sff_cpld_reg.len_12_8=1 +sff_cpld_reg.bit_offset_12_8=3 + +sff_cpld_reg.mode_13_8=config +sff_cpld_reg.src_13_8=cpld +sff_cpld_reg.frmt_13_8=bit +sff_cpld_reg.pola_13_8=negative +sff_cpld_reg.addr_13_8=0x00020031 +sff_cpld_reg.len_13_8=1 +sff_cpld_reg.bit_offset_13_8=4 + +sff_cpld_reg.mode_14_8=config +sff_cpld_reg.src_14_8=cpld +sff_cpld_reg.frmt_14_8=bit +sff_cpld_reg.pola_14_8=negative +sff_cpld_reg.addr_14_8=0x00020031 +sff_cpld_reg.len_14_8=1 +sff_cpld_reg.bit_offset_14_8=5 + +sff_cpld_reg.mode_15_8=config +sff_cpld_reg.src_15_8=cpld +sff_cpld_reg.frmt_15_8=bit +sff_cpld_reg.pola_15_8=negative +sff_cpld_reg.addr_15_8=0x00020031 +sff_cpld_reg.len_15_8=1 +sff_cpld_reg.bit_offset_15_8=6 + +sff_cpld_reg.mode_16_8=config +sff_cpld_reg.src_16_8=cpld +sff_cpld_reg.frmt_16_8=bit +sff_cpld_reg.pola_16_8=negative +sff_cpld_reg.addr_16_8=0x00020031 +sff_cpld_reg.len_16_8=1 +sff_cpld_reg.bit_offset_16_8=7 + +sff_cpld_reg.mode_17_8=config +sff_cpld_reg.src_17_8=cpld +sff_cpld_reg.frmt_17_8=bit +sff_cpld_reg.pola_17_8=negative +sff_cpld_reg.addr_17_8=0x00020032 +sff_cpld_reg.len_17_8=1 +sff_cpld_reg.bit_offset_17_8=0 + +sff_cpld_reg.mode_18_8=config +sff_cpld_reg.src_18_8=cpld +sff_cpld_reg.frmt_18_8=bit +sff_cpld_reg.pola_18_8=negative +sff_cpld_reg.addr_18_8=0x00020032 +sff_cpld_reg.len_18_8=1 +sff_cpld_reg.bit_offset_18_8=1 + +sff_cpld_reg.mode_19_8=config +sff_cpld_reg.src_19_8=cpld +sff_cpld_reg.frmt_19_8=bit +sff_cpld_reg.pola_19_8=negative +sff_cpld_reg.addr_19_8=0x00020032 +sff_cpld_reg.len_19_8=1 +sff_cpld_reg.bit_offset_19_8=2 + +sff_cpld_reg.mode_20_8=config +sff_cpld_reg.src_20_8=cpld +sff_cpld_reg.frmt_20_8=bit +sff_cpld_reg.pola_20_8=negative +sff_cpld_reg.addr_20_8=0x00020032 +sff_cpld_reg.len_20_8=1 +sff_cpld_reg.bit_offset_20_8=3 + +sff_cpld_reg.mode_21_8=config +sff_cpld_reg.src_21_8=cpld +sff_cpld_reg.frmt_21_8=bit +sff_cpld_reg.pola_21_8=negative +sff_cpld_reg.addr_21_8=0x00020032 +sff_cpld_reg.len_21_8=1 +sff_cpld_reg.bit_offset_21_8=4 + +sff_cpld_reg.mode_22_8=config +sff_cpld_reg.src_22_8=cpld +sff_cpld_reg.frmt_22_8=bit +sff_cpld_reg.pola_22_8=negative +sff_cpld_reg.addr_22_8=0x00020032 +sff_cpld_reg.len_22_8=1 +sff_cpld_reg.bit_offset_22_8=5 + +sff_cpld_reg.mode_23_8=config +sff_cpld_reg.src_23_8=cpld +sff_cpld_reg.frmt_23_8=bit +sff_cpld_reg.pola_23_8=negative +sff_cpld_reg.addr_23_8=0x00020032 +sff_cpld_reg.len_23_8=1 +sff_cpld_reg.bit_offset_23_8=6 + +sff_cpld_reg.mode_24_8=config +sff_cpld_reg.src_24_8=cpld +sff_cpld_reg.frmt_24_8=bit +sff_cpld_reg.pola_24_8=negative +sff_cpld_reg.addr_24_8=0x00020032 +sff_cpld_reg.len_24_8=1 +sff_cpld_reg.bit_offset_24_8=7 + +sff_cpld_reg.mode_25_8=config +sff_cpld_reg.src_25_8=cpld +sff_cpld_reg.frmt_25_8=bit +sff_cpld_reg.pola_25_8=negative +sff_cpld_reg.addr_25_8=0x00020033 +sff_cpld_reg.len_25_8=1 +sff_cpld_reg.bit_offset_25_8=0 + +sff_cpld_reg.mode_26_8=config +sff_cpld_reg.src_26_8=cpld +sff_cpld_reg.frmt_26_8=bit +sff_cpld_reg.pola_26_8=negative +sff_cpld_reg.addr_26_8=0x00020033 +sff_cpld_reg.len_26_8=1 +sff_cpld_reg.bit_offset_26_8=1 + +sff_cpld_reg.mode_27_8=config +sff_cpld_reg.src_27_8=cpld +sff_cpld_reg.frmt_27_8=bit +sff_cpld_reg.pola_27_8=negative +sff_cpld_reg.addr_27_8=0x00020033 +sff_cpld_reg.len_27_8=1 +sff_cpld_reg.bit_offset_27_8=2 + +sff_cpld_reg.mode_28_8=config +sff_cpld_reg.src_28_8=cpld +sff_cpld_reg.frmt_28_8=bit +sff_cpld_reg.pola_28_8=negative +sff_cpld_reg.addr_28_8=0x00020033 +sff_cpld_reg.len_28_8=1 +sff_cpld_reg.bit_offset_28_8=3 + +sff_cpld_reg.mode_29_8=config +sff_cpld_reg.src_29_8=cpld +sff_cpld_reg.frmt_29_8=bit +sff_cpld_reg.pola_29_8=negative +sff_cpld_reg.addr_29_8=0x00020033 +sff_cpld_reg.len_29_8=1 +sff_cpld_reg.bit_offset_29_8=4 + +sff_cpld_reg.mode_30_8=config +sff_cpld_reg.src_30_8=cpld +sff_cpld_reg.frmt_30_8=bit +sff_cpld_reg.pola_30_8=negative +sff_cpld_reg.addr_30_8=0x00020033 +sff_cpld_reg.len_30_8=1 +sff_cpld_reg.bit_offset_30_8=5 + +sff_cpld_reg.mode_31_8=config +sff_cpld_reg.src_31_8=cpld +sff_cpld_reg.frmt_31_8=bit +sff_cpld_reg.pola_31_8=negative +sff_cpld_reg.addr_31_8=0x00020033 +sff_cpld_reg.len_31_8=1 +sff_cpld_reg.bit_offset_31_8=6 + +sff_cpld_reg.mode_32_8=config +sff_cpld_reg.src_32_8=cpld +sff_cpld_reg.frmt_32_8=bit +sff_cpld_reg.pola_32_8=negative +sff_cpld_reg.addr_32_8=0x00020033 +sff_cpld_reg.len_32_8=1 +sff_cpld_reg.bit_offset_32_8=7 + +# configuration item: Optical module polling data size +sff_polling_size=1024 + +# configuration item: Optical module polling data register offset +# sff_polling_data_base_addr_[sff_index]=value +# sff_index: start from 1 +# value : directory name +sff_polling_data_base_addr_1 =0x8000 +sff_polling_data_base_addr_2 =0x8400 +sff_polling_data_base_addr_3 =0x8800 +sff_polling_data_base_addr_4 =0x8c00 +sff_polling_data_base_addr_5 =0x9000 +sff_polling_data_base_addr_6 =0x9400 +sff_polling_data_base_addr_7 =0x9800 +sff_polling_data_base_addr_8 =0x9c00 +sff_polling_data_base_addr_9 =0xa000 +sff_polling_data_base_addr_10 =0xa400 +sff_polling_data_base_addr_11 =0xa800 +sff_polling_data_base_addr_12 =0xac00 +sff_polling_data_base_addr_13 =0xb000 +sff_polling_data_base_addr_14 =0xb400 +sff_polling_data_base_addr_15 =0xb800 +sff_polling_data_base_addr_16 =0xbc00 +sff_polling_data_base_addr_17 =0xc000 +sff_polling_data_base_addr_18 =0xc400 +sff_polling_data_base_addr_19 =0xc800 +sff_polling_data_base_addr_20 =0xcc00 +sff_polling_data_base_addr_21 =0xd000 +sff_polling_data_base_addr_22 =0xd400 +sff_polling_data_base_addr_23 =0xd800 +sff_polling_data_base_addr_24 =0xdc00 +sff_polling_data_base_addr_25 =0xe000 +sff_polling_data_base_addr_26 =0xe400 +sff_polling_data_base_addr_27 =0xe800 +sff_polling_data_base_addr_28 =0xec00 +sff_polling_data_base_addr_29 =0xf000 +sff_polling_data_base_addr_30 =0xf400 +sff_polling_data_base_addr_31 =0xf800 +sff_polling_data_base_addr_32 =0xfc00 + +# configuration item: Optical module polling data device path +# sff_polling_logic_dev_path_[sff_index]=value +# sff_index: start from 1 +# value : directory name +sff_polling_logic_dev_path_1 =/dev/fpga0 +sff_polling_logic_dev_path_2 =/dev/fpga0 +sff_polling_logic_dev_path_3 =/dev/fpga0 +sff_polling_logic_dev_path_4 =/dev/fpga0 +sff_polling_logic_dev_path_5 =/dev/fpga0 +sff_polling_logic_dev_path_6 =/dev/fpga0 +sff_polling_logic_dev_path_7 =/dev/fpga0 +sff_polling_logic_dev_path_8 =/dev/fpga0 +sff_polling_logic_dev_path_9 =/dev/fpga0 +sff_polling_logic_dev_path_10 =/dev/fpga0 +sff_polling_logic_dev_path_11 =/dev/fpga0 +sff_polling_logic_dev_path_12 =/dev/fpga0 +sff_polling_logic_dev_path_13 =/dev/fpga0 +sff_polling_logic_dev_path_14 =/dev/fpga0 +sff_polling_logic_dev_path_15 =/dev/fpga0 +sff_polling_logic_dev_path_16 =/dev/fpga0 +sff_polling_logic_dev_path_17 =/dev/fpga0 +sff_polling_logic_dev_path_18 =/dev/fpga0 +sff_polling_logic_dev_path_19 =/dev/fpga0 +sff_polling_logic_dev_path_20 =/dev/fpga0 +sff_polling_logic_dev_path_21 =/dev/fpga0 +sff_polling_logic_dev_path_22 =/dev/fpga0 +sff_polling_logic_dev_path_23 =/dev/fpga0 +sff_polling_logic_dev_path_24 =/dev/fpga0 +sff_polling_logic_dev_path_25 =/dev/fpga0 +sff_polling_logic_dev_path_26 =/dev/fpga0 +sff_polling_logic_dev_path_27 =/dev/fpga0 +sff_polling_logic_dev_path_28 =/dev/fpga0 +sff_polling_logic_dev_path_29 =/dev/fpga0 +sff_polling_logic_dev_path_30 =/dev/fpga0 +sff_polling_logic_dev_path_31 =/dev/fpga0 +sff_polling_logic_dev_path_32 =/dev/fpga0 \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/plat_sysfs_cfg/cfg_file_name b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/plat_sysfs_cfg/cfg_file_name new file mode 100644 index 000000000000..5f49420441a5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/plat_sysfs_cfg/cfg_file_name @@ -0,0 +1,4 @@ +WB_PLAT_CPLD +WB_PLAT_FAN +WB_PLAT_PSU +WB_PLAT_SFF diff --git a/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/setup.py b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/setup.py new file mode 100644 index 000000000000..6c3916921abb --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-micas/m2-w6520-24dc8qc/setup.py @@ -0,0 +1,39 @@ +from setuptools import setup + +setup( + name='sonic-platform', + version='1.0', + description='SONiC platform API implementation', + license='Apache 2.0', + author='SONiC Team', + author_email='support', + url='', + maintainer='support', + maintainer_email='', + packages=[ + 'sonic_platform', + 'plat_hal', + 'wbutil', + 'eepromutil', + 'hal-config', + 'config', + ], + py_modules=[ + 'hal_pltfm', + 'platform_util', + 'platform_intf', + ], + classifiers=[ + 'Development Status :: 3 - Alpha', + 'Environment :: Plugins', + 'Intended Audience :: Developers', + 'Intended Audience :: Information Technology', + 'Intended Audience :: System Administrators', + 'License :: OSI Approved :: Apache Software License', + 'Natural Language :: English', + 'Operating System :: POSIX :: Linux', + 'Programming Language :: Python :: 3.7', + 'Topic :: Utilities', + ], + keywords='sonic SONiC platform PLATFORM', +) From 193dce03c49e733e79add7cd1f10e9925b0e80eb Mon Sep 17 00:00:00 2001 From: Vijaya Kumar Abbaraju Date: Sat, 26 Oct 2024 00:35:14 +0530 Subject: [PATCH 11/23] PAC infra utils -logging (#18641) --- src/sonic-pac/fpinfra/log/log.c | 66 +++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 src/sonic-pac/fpinfra/log/log.c diff --git a/src/sonic-pac/fpinfra/log/log.c b/src/sonic-pac/fpinfra/log/log.c new file mode 100644 index 000000000000..11b9b1e6c281 --- /dev/null +++ b/src/sonic-pac/fpinfra/log/log.c @@ -0,0 +1,66 @@ +/* + * Copyright 2024 Broadcom Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + + +#include + +/********************************************************************** + * @purpose Format and record a message in the in-memory log. + * + * @param severity @b((input)} See RFC 3164 Section 4.1.1 Table 2 + * @param component @b((input)} Level 7 component id + * @param fileName @b{(input)} file name + * @param lineNum @b{(input)} line number + * @param nfo @b{(input)} extra information - null terminated string + * + * @returns None + * + * @notes This executes on the calling task thread. + * + * @end + *********************************************************************/ + +void l7_log( LOG_SEVERITY_t severity, COMPONENT_IDS_t component, + char8 * fileName, uint32 lineNum, char8 * nfo) +{ + syslog(severity, nfo) +} + + +/********************************************************************* +* @purpose Log error and reset the box. +* +* @param error_code - 32-bit error code. +* @param file_name - File where the error ocurred. +* @param line_num - Line number where the error occurred. +* +* @returns none +* +* @notes This function may be called from an interrupt handler. +* +* @end +*********************************************************************/ +void +log_error_code (uint32 err_code, + char8 *file_name, + uint32 line_num) +{ + syslog(LOG_ERROR:q + + return; +} + From de762b8bb7287f868a7555a856b10b95138c476a Mon Sep 17 00:00:00 2001 From: Vijaya Kumar Abbaraju Date: Sat, 26 Oct 2024 00:37:28 +0530 Subject: [PATCH 12/23] PAC infra sonic interface files (#18638) --- src/sonic-pac/fpinfra/fpSonicUtils.cpp | 74 ++++++ src/sonic-pac/fpinfra/fpnim.cpp | 282 ++++++++++++++++++++++ src/sonic-pac/fpinfra/fpnim.h | 83 +++++++ src/sonic-pac/fpinfra/nimsync.cpp | 315 +++++++++++++++++++++++++ src/sonic-pac/fpinfra/nimsync.h | 56 +++++ 5 files changed, 810 insertions(+) create mode 100644 src/sonic-pac/fpinfra/fpSonicUtils.cpp create mode 100644 src/sonic-pac/fpinfra/fpnim.cpp create mode 100644 src/sonic-pac/fpinfra/fpnim.h create mode 100644 src/sonic-pac/fpinfra/nimsync.cpp create mode 100644 src/sonic-pac/fpinfra/nimsync.h diff --git a/src/sonic-pac/fpinfra/fpSonicUtils.cpp b/src/sonic-pac/fpinfra/fpSonicUtils.cpp new file mode 100644 index 000000000000..9311349b90b7 --- /dev/null +++ b/src/sonic-pac/fpinfra/fpSonicUtils.cpp @@ -0,0 +1,74 @@ +/* + * Copyright 2024 Broadcom Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +using namespace std; + +extern "C" { + +#include "pacinfra_common.h" +#include "fpSonicUtils.h" + +} + +const string INTFS_PREFIX = "E"; + +using namespace std; + +int fpGetIntIfNumFromHostIfName(const char *ifName, uint32 *outIntfNum) + +{ + size_t pos; + std::string::size_type sz; + std::string name = (char*)ifName; + + if(name.find(INTFS_PREFIX) == string::npos) + { + return -1; + } + + if((pos = name.find("/")) == string::npos) + { + pos = name.find("_"); + } + + if(pos == string::npos) + { + pos = 7; // assume Ethernetx format + *outIntfNum = (std::stoi(name.substr(pos+1), &sz)) + 1; + } + else + { + *outIntfNum = std::stoi(name.substr(pos+1), &sz); + } + + return 0; +} + + +int fpGetHostIntfName(uint32 physPort, uchar8 *ifName) +{ + string tmp = "Ethernet" + to_string(physPort-1); + strcpy((char*)ifName, tmp.c_str()); + return 0; +} + + + + diff --git a/src/sonic-pac/fpinfra/fpnim.cpp b/src/sonic-pac/fpinfra/fpnim.cpp new file mode 100644 index 000000000000..092d2b8a2977 --- /dev/null +++ b/src/sonic-pac/fpinfra/fpnim.cpp @@ -0,0 +1,282 @@ +/* + * Copyright 2024 Broadcom Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include +#include "fpnim.h" +#include "netdispatcher.h" +#include "netlink.h" +#include "nimsync.h" +#include "fpinfra.h" + +extern "C" { +#include "datatypes.h" +#include "commdefs.h" +#include "pacinfra_common.h" +#include "log.h" +#include "osapi.h" +#include "resources.h" +#include "nim_cnfgr.h" +#include "sysapi.h" +#include "sysapi_hpc.h" +#include "nim_events.h" +#include "nimapi.h" +#include "osapi_priv.h" +#include "nim_startup.h" +} + +using namespace swss; +using namespace std; + +extern pthread_key_t osapi_task_key; +extern int osapi_task_key_created; + +/* Initialize static member*/ +FpNim *FpNim::instance = 0; + +FpNim::FpNim(DBConnector *applDb, DBConnector *cfgDb) : +m_portTable(applDb, APP_PORT_TABLE_NAME), +m_devMetaTbl(cfgDb, CFG_DEVICE_METADATA_TABLE_NAME){ } + +FpNim* FpNim::getInstance() { + return instance; +} + +FpNim* FpNim::getInstance(DBConnector *applDb, DBConnector * cfgDb) { + if (!instance) { + instance = new FpNim(applDb, cfgDb); + instance->applDb = applDb; + instance->cfgDb = cfgDb; + } + return instance; +} + +void FpNim::init(void) { + if(nimPhaseOneInit() != SUCCESS) + return; + + if(nimPhaseTwoInit() != SUCCESS) + return; + + if(nimPhaseThreeInit() != SUCCESS) + return; + + if(nimPhaseExecInit() != SUCCESS) + return; +} + +void FpNim::nimStartupInvoke(void) { + + /* Wait till the component registers with NIM */ + nimStartUpTreeData_t startupData; + while(nimStartUpFirstGet(&startupData) != SUCCESS) + { + sleep(1); + } + + /* Now make startup callback */ + nimStartupCallbackInvoke(NIM_INTERFACE_CREATE_STARTUP); + nimStartupCallbackInvoke(NIM_INTERFACE_ACTIVATE_STARTUP); +} + +void FpNim::createAllPorts(NimSync & sync) { + int port = 0; + int unit = 1; + int slot = 0; + vector keys; + m_portTable.getKeys(keys); + SWSS_LOG_NOTICE("m_portTable->getKeys %zd", keys.size()); + + SYSAPI_HPC_PORT_DESCRIPTOR_t portData = + { + IANA_GIGABIT_ETHERNET, + PORTCTRL_PORTSPEED_FULL_10GSX, + PHY_CAP_PORTSPEED_ALL, + /* MTRJ,*/ + PORT_FEC_DISABLE, + CAP_FEC_NONE + }; + + enetMacAddr_t macAddr; + if (getSystemMac(macAddr.addr) != 0) + { + SWSS_LOG_ERROR("Failed to read system Mac"); + } + + for (const auto& alias: keys) + { + NimPort p(0, 0); + + if(alias.find(INTFS_PREFIX) == string::npos) + continue; + + SWSS_LOG_NOTICE("Keys %s", alias.c_str()); + sync.setPort(alias, p); + + try + { + if(alias.length() > 8) + { + port = std::stoi(alias.substr(8)) + 1; //FP ports starts from 1 whereas SONiC has Ethernet0 + } + else + { + port = std::stoi(alias.substr(5)); //FP ports starts from 1 whereas SONiC has Eth1/1 + } + } + catch (...) + { + SWSS_LOG_NOTICE("Invalid interface %s", alias.c_str()); + continue; + } + + if(nimCmgrNewIntfChangeCallback(unit, slot, port, 0, CREATE, &portData, &macAddr) != SUCCESS) + { + SWSS_LOG_NOTICE("Failed to add interface %s", alias.c_str()); + continue; + } + + uint32 intIfNum; + nimUSP_t usp; + usp.unit = unit; + usp.slot = slot; + usp.port = port; + /* Set Alias in native (Ethernet0) format for applications to make use of it */ + if(nimGetIntIfNumFromUSP(&usp, &intIfNum) != SUCCESS) + { + SWSS_LOG_NOTICE("Failed to get IntIfNum for interface %s", alias.c_str()); + continue; + } + nimSetIntfifAlias(intIfNum, ( uchar8 *) alias.c_str()); + + NIM_EVENT_NOTIFY_INFO_t eventInfo; + eventInfo.component = CARDMGR_COMPONENT_ID; + eventInfo.pCbFunc = NULL; + NIM_HANDLE_t handle; + + /* Generate Attach event*/ + eventInfo.event = ATTACH; + eventInfo.intIfNum = intIfNum; + if (nimEventIntfNotify(eventInfo,&handle) != SUCCESS) + { + SWSS_LOG_NOTICE("Failed to generate Attach %s event ", alias.c_str()); + } + } +} + +/* To check the port init is done or not */ +bool FpNim::isPortInitDone() { + bool portInit = 0; + long cnt = 0; + + while(!portInit) { + std::vector tuples; + portInit = m_portTable.get("PortInitDone", tuples); + + if(portInit) + break; + sleep(1); + cnt++; + } + SWSS_LOG_NOTICE("PORT_INIT_DONE : %d %ld", portInit, cnt); + return portInit; +} + +std::string FpNim::getSystemMac() { + std::string macStr; + m_devMetaTbl.hget("localhost", "mac", macStr); + SWSS_LOG_NOTICE("getSystemMac(): %s", macStr.c_str()); + return macStr; +} + +int FpNim::getSystemMac(unsigned char *addr) { + return macstr_to_mac(getSystemMac().c_str(), addr); +} + +void pacHandleDumpError(void *cbData) +{ + NetLink *netlink = (NetLink *)cbData; + SWSS_LOG_NOTICE("Netlink dump failed with NLE_DUMP_INTR, resending dump request"); + netlink->dumpRequest(RTM_GETLINK); +} + +void* fpinfraTask(void * nimPtr) { + + FpNim * nim = (FpNim *) nimPtr; + try { + nim->isPortInitDone(); + + NimSync sync; + nim->createAllPorts(sync); + nim->nimStartupInvoke(); + + //register for the table events + NetLink netlink; + netlink.registerGroup(RTNLGRP_LINK); + netlink.dumpRequest(RTM_GETLINK); + cout << "Listen to Netlink messages..." << endl; + NetDispatcher::getInstance().registerMessageHandler(RTM_NEWLINK, (swss::NetMsg*)&sync); + NetDispatcher::getInstance().registerMessageHandler(RTM_DELLINK, (swss::NetMsg*)&sync); + + swss::Select s; + s.addSelectable(&netlink); + + //wait for the events and process them + while (true) + { + SWSS_LOG_NOTICE("Waiting for Netlink Events"); + swss::Selectable *sel = NULL; + s.select(&sel); + } + } catch (const exception &e) { + SWSS_LOG_ERROR("Run-Time error: %s", e.what()); + } +} + +// Glabal variable used to protect against multiple invocation of fpinfraInit() +int fpinfraInitialized; + +int fpinfraInit(void) { + + // Only the first call is serviced + if(fpinfraInitialized) + return 0; + + fpinfraInitialized = 1; + //swss::Logger::linkToDbNative("fpInfra"); + SWSS_LOG_NOTICE("-----Initializing fpInfra -----"); + + /* Initialize sysapi */ + (void)sysapiSystemInit(); + + // connect to the databases + swss::DBConnector *applDb = new swss::DBConnector("APPL_DB", 0); + swss::DBConnector *cfgDb = new swss::DBConnector("CONFIG_DB", 0); + + FpNim * nim = FpNim::getInstance(applDb, cfgDb); + nim->init(); + + if (osapiTaskCreate("nimDbThread", (void*) fpinfraTask, -1, nim, + DEFAULT_STACK_SIZE, + DEFAULT_TASK_PRIORITY, + DEFAULT_TASK_SLICE ) == NULL) + { + return -1; + } + + return 0; +} diff --git a/src/sonic-pac/fpinfra/fpnim.h b/src/sonic-pac/fpinfra/fpnim.h new file mode 100644 index 000000000000..edb25b84ef92 --- /dev/null +++ b/src/sonic-pac/fpinfra/fpnim.h @@ -0,0 +1,83 @@ +/* + * Copyright 2024 Broadcom Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef FPNIM_H +#define FPNIM_H +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "nimsync.h" + +using namespace swss; +using namespace std; + +/* FpNim is singleton class and only one instance of it runs on a process*/ +class FpNim { +public: + /* Delete default constructor. */ + FpNim() = delete; + + /* Delete copy constructor. */ + FpNim(FpNim &other) = delete; + + /* delete assingment operator. */ + void operator=(const FpNim &) = delete; + + /** + * Static method controls the access to the singleton instance. + * On the first run, it creates a singleton object and places it + * into the static field. On subsequent runs, it returns the client existing + * object stored in the static field. + */ + static FpNim *getInstance(DBConnector *applDb, DBConnector *cfgDb); + + /* This overloaded getInstance returns the current instance pointer. + * It can return NULL when called before fpinfraInt() call + */ + static FpNim *getInstance(); + + bool processDbEvent(Selectable *source); + void init(); + bool isPortInitDone(); + void createAllPorts(NimSync & sync); + void nimStartupInvoke(void); + std::string getSystemMac(); + int getSystemMac(unsigned char *addr); +private: + static FpNim *instance; + DBConnector *applDb; + DBConnector *cfgDb; + + /* tables this component listens to */ + Table m_portTable; + Table m_devMetaTbl; + + /* Private constructor */ + FpNim(DBConnector *applDb, DBConnector *cfgDb); + + /* DB Event handler functions */ + bool processPortTblEvent(Selectable *tbl); +}; + +#endif /* FPNIM_H */ diff --git a/src/sonic-pac/fpinfra/nimsync.cpp b/src/sonic-pac/fpinfra/nimsync.cpp new file mode 100644 index 000000000000..2479db755e04 --- /dev/null +++ b/src/sonic-pac/fpinfra/nimsync.cpp @@ -0,0 +1,315 @@ +/* + * Copyright 2024 Broadcom Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include "nimsync.h" + +#include +#include +#include +#include +#include +#include +#include + +extern "C" { +#include "pacinfra_common.h" +#include "resources.h" +#include "nim_events.h" +#include "nimapi.h" +} + +using namespace std; +using namespace swss; + +#define TEAM_DRV_NAME "team" + +static int hex2num(char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + return -1; +} + +/* + * Converts mac address in string format to array of 6 bytes + * macstr - mac address in string format (example: "11:22:33:44:55:66") + * macarry - mac address in an char array +*/ +int macstr_to_mac(const char *macstr, unsigned char *addr) +{ + for (int i = 0; i < 6; i++) + { + int a, b; + + a = hex2num(*macstr++); + if (a < 0) + return -1; + b = hex2num(*macstr++); + if (b < 0) + return -1; + *addr++ = (a << 4) | b; + if (i < 5 && *macstr++ != ':') + return -1; + } + return 0; +} + +NimPort::NimPort(){ + m_adminState = 0; + m_operState = 0; +} + +NimPort::NimPort(const int &admin, const int &oper) : +m_adminState(admin), +m_operState(oper){ } + + + + +NimSync::NimSync() {} + +NimPort& NimSync::getPort(const string & alias) +{ + return m_portList[alias]; +} + +void NimSync::setPort(const string & alias, const NimPort& port) +{ + m_portList[alias] = port; +} + +void NimSync::delPort(const string & alias) +{ + m_portList.erase(alias); +} + +void NimSync::onMsg(int nlmsg_type, struct nl_object *obj) +{ + SWSS_LOG_ENTER(); + + if ((nlmsg_type != RTM_NEWLINK) && (nlmsg_type != RTM_DELLINK)) + { + return; + } + + struct rtnl_link *link = (struct rtnl_link *)obj; + string key = rtnl_link_get_name(link); + + if (key.compare(0, INTFS_PREFIX.length(), INTFS_PREFIX) && + key.compare(0, LAG_PREFIX.length(), LAG_PREFIX) && + key.compare(0, MGMT_PREFIX.length(), MGMT_PREFIX)) + { + return; + } + + unsigned int flags = rtnl_link_get_flags(link); + bool admin = flags & IFF_UP; + bool oper = flags & IFF_LOWER_UP; + + char addrStr[MAX_ADDR_SIZE+1] = {0}; + nl_addr2str(rtnl_link_get_addr(link), addrStr, MAX_ADDR_SIZE); + + unsigned int ifindex = rtnl_link_get_ifindex(link); + int master = rtnl_link_get_master(link); + char *type = rtnl_link_get_type(link); + + if (type) + { + SWSS_LOG_NOTICE("nlmsg type:%d key:%s admin:%d oper:%d addr:%s ifindex:%d master:%d type:%s", + nlmsg_type, getStdIfFormat(key).c_str(), admin, oper, addrStr, ifindex, master, type); + } + else + { + SWSS_LOG_NOTICE("nlmsg type:%d key:%s admin:%d oper:%d addr:%s ifindex:%d master:%d", + nlmsg_type, getStdIfFormat(key).c_str(), admin, oper, addrStr, ifindex, master); + } + + if (!key.compare(0, MGMT_PREFIX.length(), MGMT_PREFIX)) + { + return; + } + + /* teamd instances are dealt in teamsyncd */ + if (type && !strcmp(type, TEAM_DRV_NAME)) + { + return; + } + + if(key.find(INTFS_PREFIX) == string::npos) + { + SWSS_LOG_NOTICE("Skipping non Ethernet interface %s", key.c_str()); + return; + } + + uint32 intIfNum; + NIM_HANDLE_t handle; + + nimUSP_t usp; + usp.unit = 1; + usp.slot = 0; + + try + { + if(key.length() > 8) + { + usp.port = std::stoi(key.substr(8)) + 1; // FP ports start from 1 corresponds to Ethernet0 on SONiC + } + else + { + usp.port = std::stoi(key.substr(3)); // FP ports start from 1 corresponds to E1_1 on SONiC + // SONiC DB and netlink has different formats for the interface. Convert it into Eth1/1 format + string tmp = "Eth" + key.substr(1,1) + '/' + key.substr(3); + key = tmp; + } + } + catch (...) + { + SWSS_LOG_NOTICE("Skipping invalid interface %s", key.c_str()); + return; + } + + NIM_EVENT_NOTIFY_INFO_t eventInfo; + eventInfo.component = CARDMGR_COMPONENT_ID; + eventInfo.pCbFunc = NULL; + enetMacAddr_t macAddr; + if (macstr_to_mac(addrStr, macAddr.addr) != 0) + { + SWSS_LOG_NOTICE("Invalid MAC address format %s", addrStr); + } + + /* New interface handling */ + if (m_portList.find(key) == m_portList.end()) + { + int port = 0; + SYSAPI_HPC_PORT_DESCRIPTOR_t portData = + { + IANA_GIGABIT_ETHERNET, + PORTCTRL_PORTSPEED_FULL_10GSX, + PHY_CAP_PORTSPEED_ALL, + /* MTRJ,*/ + PORT_FEC_DISABLE, + CAP_FEC_NONE + }; + + NimPort p(0, 0); + + SWSS_LOG_NOTICE("New interface %s", key.c_str()); + setPort(key, p); + + if(key.length() > 8) + { + port = std::stoi(key.substr(8)) + 1; //FP ports starts from 1 whereas SONiC has Ethernet0 + } + else + { + port = std::stoi(key.substr(5)); // Eth1/1 format after conversion + } + + /* Generate Create followed by Attach event*/ + if(nimCmgrNewIntfChangeCallback(1, 0, port, 0, CREATE, &portData, &macAddr) != SUCCESS) + { + SWSS_LOG_NOTICE("Failed to add interface %s", key.c_str()); + return; + } + + /* Get internal interface number from Nim */ + if(nimGetIntIfNumFromUSP(&usp, &intIfNum) != SUCCESS) + { + SWSS_LOG_NOTICE("Failed to get intIfNum for %s", key.c_str()); + } + + if(nimSetIntfifAlias(intIfNum, ( uchar8 *) key.c_str()) != SUCCESS) + { + SWSS_LOG_NOTICE("Failed to set alias %s for intIfNum(%d)", key.c_str(), intIfNum); + } + + /* Generate Attach event*/ + eventInfo.event = ATTACH; + eventInfo.intIfNum = intIfNum; + if (nimEventIntfNotify(eventInfo,&handle) != SUCCESS) + { + SWSS_LOG_NOTICE("Failed to generate Attach %s event ", key.c_str()); + } + } + + if(nimGetIntIfNumFromUSP(&usp, &intIfNum) != SUCCESS) + { + SWSS_LOG_NOTICE("Failed to get intIfNum for %s", key.c_str()); + return; + } + + /* Interface delete handling */ + if (nlmsg_type == RTM_DELLINK) + { + if (m_portList.find(key) == m_portList.end()) + { + SWSS_LOG_NOTICE("Unknown interface %s for Delete event ", key.c_str()); + return; + } + + /* Generate Detach followed by Delete */ + eventInfo.event = DETACH; + eventInfo.intIfNum = intIfNum; + if (nimEventIntfNotify(eventInfo,&handle) != SUCCESS) + { + SWSS_LOG_NOTICE("Failed to generate Detach %s event ", key.c_str()); + } + else if (eventInfo.event = DELETE, nimEventIntfNotify(eventInfo,&handle) != SUCCESS) + { + SWSS_LOG_NOTICE("Failed to generate Delete %s event ", key.c_str()); + } + else + { + SWSS_LOG_NOTICE("Delete %s event", key.c_str()); + delPort(key); + } + return; + } + + /* Set the admin state first*/ + if (admin != m_portList[key].m_adminState) + { + m_portList[key].m_adminState = admin; + nimSetIntfAdminState(intIfNum, admin? ENABLE: DISABLE); + } + + /* followed by the oper state */ + if ( oper != m_portList[key].m_operState) + { + m_portList[key].m_operState = oper; + nimDtlIntfChangeCallback(&usp, oper? UP: DOWN, NULL); + } +} + +string NimSync::getStdIfFormat(string key) +{ + if((key.find("E") == string::npos) || (key.length() > 8)) + { + return key; + } + string key1(""); + key1 = "Eth" + key.substr(1,1) + '/' + key.substr(3); + return key1; +} + diff --git a/src/sonic-pac/fpinfra/nimsync.h b/src/sonic-pac/fpinfra/nimsync.h new file mode 100644 index 000000000000..ff9d9ff0060e --- /dev/null +++ b/src/sonic-pac/fpinfra/nimsync.h @@ -0,0 +1,56 @@ +/* + * Copyright 2024 Broadcom Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __NIMSYNC__ +#define __NIMSYNC__ + +#include +#include +#include "dbconnector.h" +#include "netmsg.h" +#include "table.h" + +using namespace swss; + +const std::string MGMT_PREFIX = "eth"; +const std::string INTFS_PREFIX = "E"; +const std::string LAG_PREFIX = "PortChannel"; + + +int macstr_to_mac(const char *macstr, unsigned char *addr); + +class NimPort { +public: + NimPort(); + NimPort(const int &admin, const int &oper); + int m_adminState; + int m_operState; +}; + + +class NimSync : public NetMsg { +public: + enum { MAX_ADDR_SIZE = 64 }; + NimSync(); + virtual void onMsg(int nlmsg_type, struct nl_object *obj); + NimPort & getPort(const std::string & alias); + void setPort(const std::string & alias, const NimPort & port); + void delPort(const std::string & alias); + std::string getStdIfFormat(std::string key); +private: + std::map m_portList; +}; + +#endif From c75dc62b333d456bc2ecb3182db71b7040e8fe1a Mon Sep 17 00:00:00 2001 From: Vijaya Kumar Abbaraju Date: Sat, 26 Oct 2024 00:37:37 +0530 Subject: [PATCH 13/23] Auth mgr generic header files (#18632) --- .../authmgr/mapping/include/auth_mgr.h | 98 ++ .../mapping/include/auth_mgr_auth_method.h | 55 ++ .../authmgr/mapping/include/auth_mgr_cfg.h | 130 +++ .../authmgr/mapping/include/auth_mgr_client.h | 225 +++++ .../mapping/include/auth_mgr_control.h | 858 ++++++++++++++++++ .../authmgr/mapping/include/auth_mgr_debug.h | 146 +++ .../authmgr/mapping/include/auth_mgr_ih.h | 45 + .../mapping/include/auth_mgr_include.h | 69 ++ .../authmgr/mapping/include/auth_mgr_struct.h | 89 ++ 9 files changed, 1715 insertions(+) create mode 100755 src/sonic-pac/authmgr/mapping/include/auth_mgr.h create mode 100755 src/sonic-pac/authmgr/mapping/include/auth_mgr_auth_method.h create mode 100755 src/sonic-pac/authmgr/mapping/include/auth_mgr_cfg.h create mode 100755 src/sonic-pac/authmgr/mapping/include/auth_mgr_client.h create mode 100755 src/sonic-pac/authmgr/mapping/include/auth_mgr_control.h create mode 100755 src/sonic-pac/authmgr/mapping/include/auth_mgr_debug.h create mode 100755 src/sonic-pac/authmgr/mapping/include/auth_mgr_ih.h create mode 100755 src/sonic-pac/authmgr/mapping/include/auth_mgr_include.h create mode 100755 src/sonic-pac/authmgr/mapping/include/auth_mgr_struct.h diff --git a/src/sonic-pac/authmgr/mapping/include/auth_mgr.h b/src/sonic-pac/authmgr/mapping/include/auth_mgr.h new file mode 100755 index 000000000000..2c20957c1b5b --- /dev/null +++ b/src/sonic-pac/authmgr/mapping/include/auth_mgr.h @@ -0,0 +1,98 @@ +/* + * Copyright 2024 Broadcom Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AUTHMGR_H +#define AUTHMGR_H + +/* USE C Declarations */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Authentication Manager Timers */ +typedef enum +{ + AUTH_MGR_RESTART = 0, +} auth_mgr_timer_t; + +/* Authentication Manager Event Message IDs */ +typedef enum +{ + authMgrMethodSet = 1, + authMgrPrioritySet, + authMgrOpenAccess, + authMgrRestartTimerSet, + authMgrRestartTimerExpiry, + authMgrNimStartup, + authMgrCnfgr, + authMgrActivateStartupDone, + authMgrHandleNewBackupManager +}authMgrMessages_t; + +typedef enum +{ + AUTH_MGR_UNAUTHENTICATED = 0, + AUTH_MGR_AUTHENTICATED +} authMgrAuthStatus_t; + + +typedef struct authMgrIntfChangeParms_s +{ + uint32 event; + NIM_CORRELATOR_t correlator; +} authMgrIntfChangeParms_t; + +typedef struct authMgrNimStartup_s +{ + NIM_STARTUP_PHASE_t startupPhase; +} authMgrNimStartup_t; + +typedef struct authMgrTimerParams_s +{ + uint32 timerCBHandle; +} authMgrTimerParams_t; +#define AUTHMGR_TIMER_MSG_SIZE sizeof(authMgrTimerParams_t) + +/* authentication manager Event Message format */ +typedef struct authMgrMgmtMsg_s +{ + uint32 msgId; /* Of type snoopMgmtMessages_t */ + uint32 intIfNum; + union + { + CNFGR_CMD_DATA_t CmdData; + authMgrIntfChangeParms_t authMgrIntfChangeParms; + authMgrNimStartup_t authMgrNimStartup; + uint32 mode; + authMgrTimerParams_t authMgrParams; + uint32 timerValue; + } u; +} authMgrMgmtMsg_t; +#define AUTHMGR_MSG_SIZE sizeof(authMgrMgmtMsg_t) + + +/* Start of Function Prototype */ +void authMgrNotifyRegisteredUsers(uint32 intIfNum, + uint32 event); +/* End of function prototypes */ + +/* USE C Declarations */ +#ifdef __cplusplus +} +#endif + +#endif /* AUTHMGR_H */ + diff --git a/src/sonic-pac/authmgr/mapping/include/auth_mgr_auth_method.h b/src/sonic-pac/authmgr/mapping/include/auth_mgr_auth_method.h new file mode 100755 index 000000000000..84dcdddaa8de --- /dev/null +++ b/src/sonic-pac/authmgr/mapping/include/auth_mgr_auth_method.h @@ -0,0 +1,55 @@ +/* + * Copyright 2024 Broadcom Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AUTHMGR_AUTHMETHOD_H +#define AUTHMGR_AUTHMETHOD_H + +#include +#include "mab_socket.h" + +/* USE C Declarations */ +#ifdef __cplusplus +extern "C" { +#endif + +#define ETHERNET_PREFIX "Ethernet" + +typedef struct authmgrMethodEvent_s +{ + authmgrNotifyEvent_t event; + char8 eventStr[16]; +}authmgrMethodEvent_t; + +RC_t authmgrDot1xEventSend (uint32 intIfNum, uint32 event, enetMacAddr_t *macAddr); +RC_t authmgrDot1xIntfAdminModeGet (uint32 intIfNum, BOOL *enabled); +RC_t authmgrDot1xIntfPortControlModeSet (uint32 intIfNum, AUTHMGR_PORT_CONTROL_t portControl); +RC_t authmgrDot1xPortPaeCapabilitiesGet (uint32 intIfNum, uchar8 * capabilities); +int wpa_sync_send(char * ctrl_ifname, char * cmd, char *buf, size_t *len); +int authmgrMabDataSend(mab_pac_cmd_t *req, char *resp, unsigned int *len); +RC_t authmgrMabEventSend (uint32 intIfNum, uint32 event, enetMacAddr_t *macAddr); +RC_t authmgrMabIntfAdminModeGet (uint32 intIfNum, BOOL *enabled); + +int handle_async_resp_data(int *listen_sock); + +/* End of function prototypes */ + +/* USE C Declarations */ +#ifdef __cplusplus +} +#endif + +#endif /* AUTHMGR_AUTHMETHOD_H */ + diff --git a/src/sonic-pac/authmgr/mapping/include/auth_mgr_cfg.h b/src/sonic-pac/authmgr/mapping/include/auth_mgr_cfg.h new file mode 100755 index 000000000000..1026c6e98529 --- /dev/null +++ b/src/sonic-pac/authmgr/mapping/include/auth_mgr_cfg.h @@ -0,0 +1,130 @@ +/* + * Copyright 2024 Broadcom Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INCLUDE_AUTHMGR_CFG_H +#define INCLUDE_AUTHMGR_CFG_H + +/* USE C Declarations */ +#ifdef __cplusplus +extern "C" { +#endif + +#include "nim_data.h" + +#define AUTHMGR_IS_READY (((authmgrCnfgrState == AUTHMGR_PHASE_INIT_3) || \ + (authmgrCnfgrState == AUTHMGR_PHASE_EXECUTE) || \ + (authmgrCnfgrState == AUTHMGR_PHASE_UNCONFIG_1)) ? ( TRUE) : ( FALSE)) + +typedef enum { + AUTHMGR_PHASE_INIT_0 = 0, + AUTHMGR_PHASE_INIT_1, + AUTHMGR_PHASE_INIT_2, + AUTHMGR_PHASE_WMU, + AUTHMGR_PHASE_INIT_3, + AUTHMGR_PHASE_EXECUTE, + AUTHMGR_PHASE_UNCONFIG_1, + AUTHMGR_PHASE_UNCONFIG_2, +} authmgrCnfgrState_t; + +#define AUTHMGR_LLDP_PROFILES_MAX 128 + +typedef struct authmgrPortCfg_s +{ + nimConfigID_t configId; /* NIM config ID for this interface*/ + /* if port is operating as supplicnat, + the functionality is redundant */ + /* Authentication methods */ + AUTHMGR_METHOD_t methodList[ AUTHMGR_METHOD_LAST]; + AUTHMGR_METHOD_t priorityList[ AUTHMGR_METHOD_LAST]; + AUTHMGR_PORT_CONTROL_t portControlMode; /* Current control mode setting by mgmt */ + AUTHMGR_HOST_CONTROL_t hostMode; /* Current host mode setting by mgmt */ + uint32 quietPeriod; /* Initialization value for txWhen timer */ + uint32 reAuthPeriod; /* Number of seconds between periodic reauthentication */ + BOOL reAuthEnabled; /* TRUE if reauthentication is enabled */ + uint32 maxUsers; /*Maximum no. users in Mac-Based Authentication */ + uint32 maxAuthAttempts; /* Maximum number of times authentication may be reattempted by the user radius */ + /* variable to hold config related to session time out is to be used + from radius server */ + BOOL reAuthPeriodServer; + uint32 inActivityPeriod; /* Number of seconds to wait after which clients can be cleaned up due to inactivity */ + uint32 intfConfigMask; + uchar8 paeCapabilities; +} authmgrPortCfg_t; + +typedef struct authmgrCfg_s +{ + fileHdr_t cfgHdr; + uint32 adminMode; + uint32 authmgrLogTraceMode; /* Enable/disable log file tracing */ + uint32 vlanAssignmentMode;/* Global mode to enable vlan assignment */ + authmgrPortCfg_t authmgrPortCfg[ AUTHMGR_INTF_MAX_COUNT]; /* Per-port config info */ + AUTHMGR_PORT_CONTROL_t portControlMode; /* Current control mode setting by mgmt */ + AUTHMGR_HOST_CONTROL_t hostMode; /* Current host mode setting by mgmt */ +} authmgrCfg_t; + +extern authmgrCfg_t *authmgrCfg; + +typedef struct authmgrDebugCfgData_s +{ + BOOL authmgrDebugPacketTraceTxFlag; + BOOL authmgrDebugPacketTraceRxFlag; +} authmgrDebugCfgData_t; + +typedef struct authmgrDebugCfg_s +{ + fileHdr_t hdr; + authmgrDebugCfgData_t cfg; + uint32 checkSum; +} authmgrDebugCfg_t; + +extern RC_t authmgrSave(void); +extern BOOL authmgrHasDataChanged(void); +extern void authmgrResetDataChanged(void); + +extern RC_t authmgrCfgDump(void); +extern void authmgrBuildDefaultConfigData(void); +extern void authmgrBuildDefaultIntfConfigData(nimConfigID_t *configId, authmgrPortCfg_t *pCfg); + +extern RC_t authmgrApplyConfigData(void); +extern RC_t authmgrApplyPortConfigData(uint32 intIfNum); +extern RC_t authmgrPortReset(uint32 intIfNum); + +extern void authmgrApiCnfgrCommand( CNFGR_CMD_DATA_t *pCmdData); +extern RC_t authmgrInit(void); +extern void authmgrInitUndo(); +extern RC_t authmgrCnfgrInitPhase1Process(void); +extern RC_t authmgrCnfgrInitPhase2Process(void); +extern RC_t authmgrCnfgrInitPhase3Process( BOOL warmRestart); +extern void authmgrCnfgrFiniPhase1Process(); +extern void authmgrCnfgrFiniPhase2Process(); +extern void authmgrCnfgrFiniPhase3Process(); +extern RC_t authmgrCnfgrNoopProccess( CNFGR_RESPONSE_t *pResponse, + CNFGR_ERR_RC_t *pReason ); +extern RC_t authmgrCnfgrUconfigPhase2( CNFGR_RESPONSE_t *pResponse, + CNFGR_ERR_RC_t *pReason ); +extern void authmgrCnfgrParse( CNFGR_CMD_DATA_t *pCmdData); + +extern RC_t authmgrLogicalPortInfoSetPortInfo(authmgrLogicalPortInfo_t *logicalPortInfo); +extern RC_t authmgrLogicalPortInfoInitialize(authmgrLogicalPortInfo_t *logicalPortInfo); +extern RC_t authmgrLogicalPortReset(authmgrLogicalPortInfo_t *logicalPortInfo); +extern void authmgrCnfgrTerminateProcess( CNFGR_CMD_DATA_t *pCmdData); + +/* USE C Declarations */ +#ifdef __cplusplus +} +#endif + +#endif /* INCLUDE_AUTHMGR_CFG_H */ diff --git a/src/sonic-pac/authmgr/mapping/include/auth_mgr_client.h b/src/sonic-pac/authmgr/mapping/include/auth_mgr_client.h new file mode 100755 index 000000000000..07ebde81ef15 --- /dev/null +++ b/src/sonic-pac/authmgr/mapping/include/auth_mgr_client.h @@ -0,0 +1,225 @@ +/* + * Copyright 2024 Broadcom Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INCLUDE_AUTHMGR_CLIENT_H +#define INCLUDE_AUTHMGR_CLIENT_H + +/* USE C Declarations */ +#ifdef __cplusplus +extern "C" { +#endif + +#include "comm_mask.h" + +/********************************************************************* + * @purpose Set the authmgr physical port authorization status + * + * @param intIfNum @b{(input)) internal interface number + * @param portStatus @b{(input)) port authorization status setting + * + * @returns SUCCESS + * @returns FAILURE + * @returns ERROR + * + * @comments none + * + * @end + *********************************************************************/ +RC_t authmgrIhPhysicalPortStatusSet(uint32 intIfNum, + AUTHMGR_PORT_STATUS_t portStatus); + +/********************************************************************* + * @purpose Set the authmgr physical port authorization status + * +* @param intIfNum @b{(input)} internal interface number +* @param macAddr @b{(input)} MAC address of authorized client +* @param vlanId @b{(input)} set to non-zero value to assign this client to a VLAN + * + * @returns SUCCESS + * @returns FAILURE + * @returns ERROR + * + * @comments none + * + * @end + *********************************************************************/ +RC_t authmgrAuthenticatedClientAdd(uint32 physPort, + enetMacAddr_t macAddr, + ushort16 vlanId, + ushort16 blockVlanId); + +/********************************************************************* + * @purpose Set the authmgr physical port authorization status + * +* @param intIfNum @b{(input)} internal interface number +* @param macAddr @b{(input)} MAC address of authorized client +* @param vlanId @b{(input)} set to non-zero value to assign this client to a VLAN + * + * @returns SUCCESS + * @returns FAILURE + * @returns ERROR + * + * @comments none + * + * @end + *********************************************************************/ +RC_t authmgrAuthenticatedClientDelete(uint32 physPort, + enetMacAddr_t macAddr, + ushort16 vlanId); + +/********************************************************************* +* @purpose Cleanup the client Secure Downloadable ACL info from DB +* +* @param logicalPortInfo @b{(input)) client logical port info structure +* +* @returns SUCCESS +* @returns FAILURE +* +* @comments +* +* @end +*********************************************************************/ +RC_t authmgrRadiusSecDAclCleanupFromDb (authmgrLogicalPortInfo_t * logicalPortInfo); + +/********************************************************************* + * @purpose function to cleanup the vlan and other settings + * + * @param intIfNum @b{(input)) internal interface number + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t authmgrClientHwInfoCleanup(authmgrLogicalPortInfo_t *logicalPortInfo); + +/********************************************************************* + * @purpose function to cleanup the vlan and other settings + * + * @param intIfNum @b{(input)) internal interface number + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t authmgrClientHwInfoAdd(authmgrLogicalPortInfo_t *logicalPortInfo, + enetMacAddr_t macAddr, + ushort16 vlanId, + ushort16 blockVlanId); + +/********************************************************************* + * @purpose Set the authmgr client authorization status + * + * @param lIntIfNum @b{(input)) internal interface number + * @param portStatus @b{(input)) port authorization status setting + * + * @returns SUCCESS + * @returns FAILURE + * @returns ERROR + * + * @comments none + * + * @end + *********************************************************************/ +RC_t authmgrClientStatusSet(authmgrLogicalPortInfo_t *logicalPortInfo, AUTHMGR_PORT_STATUS_t portStatus); + +/********************************************************************* + * @purpose function to cleanup the client + * + * @param intIfNum @b{(input)) internal interface number + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t authmgrClientInfoCleanup(authmgrLogicalPortInfo_t *logicalPortInfo); + +/********************************************************************* + * @purpose function to cleanup the client sw info + * + * @param intIfNum @b{(input)) internal interface number + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t authmgrClientSwInfoCleanup(authmgrLogicalPortInfo_t *logicalPortInfo); + +/********************************************************************* + * @purpose function to check and deAllocate the client + * + * @param intIfNum @b{(input)) internal interface number + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t authmgrClientDisconnectAction(authmgrLogicalPortInfo_t *logicalPortInfo); + + +RC_t authmgrClientInfoCleanupCheck (authmgrClientInfo_t *src, + authmgrClientInfo_t *dst); +RC_t authmgrClientFailTimeoutAction(authmgrLogicalPortInfo_t *logicalPortInfo); + +/********************************************************************* +* @purpose utility function to check if the client ckpt params modified +* @param src +* @param dst +* @return SUCCESS/ FAILURE +* +* @comments +* +* @end +*********************************************************************/ +RC_t authmgrClientHwAddFailPostHwCleanup (authmgrLogicalPortInfo_t *logicalPortInfo, + uint32 mask); + + +/********************************************************************* +* @purpose function to check and cleanup authenticated client's params +* +* @param logicalPortInfo @b{(input)) logical interface structure +* +* @returns SUCCESS +* @returns FAILURE +* +* @comments +* +* @end +*********************************************************************/ +RC_t authmgrAuthenticatedClientCleanupAction (authmgrLogicalPortInfo_t * + logicalPortInfo); + +/* USE C Declarations */ +#ifdef __cplusplus +} +#endif + +#endif /* INCLUDE_AUTHMGR_CLIENT_H */ diff --git a/src/sonic-pac/authmgr/mapping/include/auth_mgr_control.h b/src/sonic-pac/authmgr/mapping/include/auth_mgr_control.h new file mode 100755 index 000000000000..56a53f886b98 --- /dev/null +++ b/src/sonic-pac/authmgr/mapping/include/auth_mgr_control.h @@ -0,0 +1,858 @@ +/* + * Copyright 2024 Broadcom Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef INCLUDE_AUTHMGR_CONTROL_H +#define INCLUDE_AUTHMGR_CONTROL_H + +/* USE C Declarations */ +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef AUTHMGR_MAC_MOVE_ON +#define AUTHMGR_MAC_MOVE_ON +#endif + +typedef enum authmgrControlEvents_s +{ + /***************************************************************/ + /* Events shared with all */ + /***************************************************************/ + /*100*/authmgrControlBegin = 100, + + /***************************************************************/ + /* Events from Management commands */ + /***************************************************************/ + + /*101*/authmgrMgmtPortInitializeSet, + /*102*/authmgrMgmtLogicalPortInitializeSet, + /*103*/authmgrMgmtPortReauthenticateSet, + /*105*/authmgrMgmtPortControlModeSet, + /*106*/authmgrMgmtHostControlModeSet, + /*110*/authmgrMgmtPortQuietPeriodSet, + /*111*/authmgrMgmtPortReAuthPeriodSet, + /*112*/authmgrMgmtPortReAuthEnabledSet, + /*113*/authmgrMgmtPortStatsClear, + /*114*/authmgrMgmtApplyConfigData, + /*115*/authmgrMgmtApplyPortConfigData, + /*116*/authmgrMgmtPortMaxUsersSet, + /*118*/authmgrMgmtLogicalPortReauthenticateSet, + /*119*/authmgrMethodOrderModify, + /*120*/authmgrMethodPriorityModify, + /*123*/authmgrPaeCapabilitiesEvent, + /*124*/authmgrViolationModeSet, + /*125*/authmgrMaxAuthAttemptsSet, + + /*129*/authmgrMgmtEvents, /*keep this last in sub group*/ + + /***************************************************************/ + /* Events from network pdu received */ + /***************************************************************/ + /*130*/authmgrNetworkEvents, + + /***************************************************************/ + /* Events from AAA client */ + /***************************************************************/ + /*131*/authmgrAaaInfoReceived, + + /*132*/authmgrAaaEvents, + + /***************************************************************/ + /* Events from interface state changes */ + /***************************************************************/ + /*133*/authmgrIntfChange, + /*134*/authmgrIntfStartup, + + /*135*/authmgrIntfChangeEvents, + + /***************************************************************/ + /* Events from Vlan state changes */ + /***************************************************************/ + + /*136*/authmgrVlanDeleteEvent, + /*137*/authmgrVlanAddEvent, + /*138*/authmgrVlanAddPortEvent, + /*139*/authmgrVlanDeletePortEvent, + /*140*/authmgrVlanPvidChangeEvent, + /*140*/authmgrVlanConfDeleteEvent, + /*140*/authmgrVlanConfPortDeleteEvent, + /***************************************************************/ + /* Events from configurator */ + /***************************************************************/ + /*141*/authmgrCnfgr, + + /*142*/authmgrCnfgrEvents, + + /*143*/authmgrUnauthAddrCallBackEvent, + /*145*/authmgrClientTimeout, + /***************************************************************/ + /*147*/authmgrDelDuplicateEntry, + /*148*/authmgrAddMacInMacDB, + /*149*/authmgrClientCleanup, + /***************************************************************/ + /* Events from Radius. */ + /***************************************************************/ + /* authmgr app timer events */ + /* 154*/ authmgrTimeTick, + /* 155*/ authmgrAuthenticationStart, + /* 156*/ authMgr8021xEnableDisable, + /* 157*/ authmgrMabEnableDisable, + /* 159*/ authmgrAuthMethodCallbackEvent, + /* 164*/ authmgrMgmtAdminModeEnable, + /* 165*/ authmgrMgmtAdminModeDisable, + /* 167*/ authmgrDynamicVlanModeEnable, + /* 168*/ authmgrDynamicVlanModeDisable, + /* 169*/ authmgrMgmtPortInactivePeriodSet, + + /* 179*/ authmgrCtlPortInfoReset, +}authmgrControlEvents_t; + +/* Message structure to hold responses from AAA client (i.e. RADIUS) */ +typedef struct authmgrAaaMsg_s +{ + uint32 status; /* status of response (i.e. RADIUS_STATUS_SUCCESS, etc.) */ + uint32 respLen; /* length of data (response) being passed */ + uchar8 *pResponse; /* pointer to response from AAA server */ +} authmgrAaaMsg_t; + +typedef struct authmgrIntfChangeParms_s +{ + uint32 intfEvent; + NIM_CORRELATOR_t nimCorrelator; +} authmgrIntfChangeParms_t; + +typedef struct authmgrUnauthCallbackParms_s +{ + enetMacAddr_t macAddr; + ushort16 vlanId; +} authmgrUnauthCallbackParms_t; + +typedef struct authmgrMgmtTimePeriod_s +{ + BOOL reAuthPeriodServer; + uint32 val; +} authmgrMgmtTimePeriod_t; + +typedef struct authmgrMsg_s +{ + uint32 event; + uint32 intf; + union + { + uint32 msgParm; + netBufHandle bufHandle; + authmgrAaaMsg_t authmgrAaaMsg; + authmgrIntfChangeParms_t authmgrIntfChangeParms; + NIM_STARTUP_PHASE_t startupPhase; + authmgrAuthRespParams_t authParams; + authmgrMgmtTimePeriod_t timePeriod; + }data; +} authmgrMsg_t; + +typedef struct authmgrBulkMsg_s +{ + uint32 event; + uint32 intf; + union + { + authmgrUnauthCallbackParms_t unauthParms; + }data; +} authmgrBulkMsg_t; + +typedef struct authmgrVlanMsg_s +{ + uint32 event; + uint32 intf; + union + { + dot1qNotifyData_t vlanData; + }data; +} authmgrVlanMsg_t; + +#define AUTHMGR_MSG_COUNT FD_AUTHMGR_MSG_COUNT +#define AUTHMGR_VLAN_MSG_COUNT (16 * 1024) +#define AUTHMGR_TIMER_TICK 1000 /*in milliseconds*/ + +typedef RC_t(*authmgrStatusMapFn_t) (uint32 lIntIfNum, authmgrAuthRespParams_t *params); + +typedef struct authmgrStatusMap_s +{ + AUTHMGR_STATUS_t type; + authmgrStatusMapFn_t statusFn; +}authmgrStatusMap_t; + +typedef RC_t(*authmgrPortControlChangeNotifyFn_t) (uint32 intIfNum, AUTHMGR_PORT_CONTROL_t portControl); +typedef RC_t(*authmgrHostControlChangeNotifyFn_t) (uint32 intIfNum, AUTHMGR_HOST_CONTROL_t hostMode); +typedef RC_t(*authmgrClientEventNotifyFn_t) (uint32 intIfNum, uint32 event, enetMacAddr_t *macAddr); +typedef RC_t(*authmgrMethodOperEnableGetFn_t) (uint32 intIfNum, uint32 *enable); + +typedef struct authmgrMethodCallbackNotifyMap_s +{ + AUTHMGR_METHOD_t method; + authmgrPortControlChangeNotifyFn_t portCtrlFn; + authmgrHostControlChangeNotifyFn_t hostCtrlFn; + authmgrClientEventNotifyFn_t eventNotifyFn; + authmgrMethodOperEnableGetFn_t enableGetFn; + authmgrMethodOperEnableGetFn_t radiusEnabledGetFn; +}authmgrMethodCallbackNotifyMap_t; + +extern RC_t authmgrStartTasks(); +extern RC_t authmgrFillMsg(void *data, authmgrMsg_t *msg); +extern RC_t authmgrBulkFillMsg(void *data, authmgrBulkMsg_t *msg); +extern RC_t authmgrVlanFillMsg (void *data, authmgrVlanMsg_t * msg); +extern RC_t authmgrIssueCmd(uint32 event, uint32 intIfNum, void *data); +extern RC_t authmgrDispatchCmd(authmgrMsg_t *msg); +extern RC_t authmgrBulkDispatchCmd(authmgrBulkMsg_t *msg); +extern RC_t authmgrVlanDispatchCmd (authmgrVlanMsg_t * msg); +extern RC_t authmgrTimerAction(); + +extern RC_t authmgrCtlPortInitializeSet(uint32 intIfNum, BOOL initialize); +extern RC_t authmgrCtlLogicalPortInitializeSet(uint32 lIntIfNum); +extern RC_t authmgrCtlPortReauthenticateSet(uint32 intIfNum, BOOL reauthenticate); +extern RC_t authmgrCtlLogicalPortReauthenticateSet(uint32 lIntIfNum, BOOL reauthenticate); +extern RC_t authmgrCtlPortControlModeSet(uint32 intIfNum, AUTHMGR_PORT_CONTROL_t portControl); +extern RC_t authmgrCtlPortPaeCapabilitiesSet(uint32 intIfNum, uint32 capabilities); +extern RC_t authmgrCtlPortPaeCapabilitiesInGlobalDisableSet(uint32 intIfNum, uint32 paeCapabilities); +extern RC_t authmgrCtlPortQuietPeriodSet(uint32 intIfNum, uint32 quietPeriod); +extern RC_t authmgrCtlPortTxPeriodSet(uint32 intIfNum, uint32 txPeriod); +extern RC_t authmgrCtlPortReAuthPeriodSet(uint32 intIfNum, authmgrMgmtTimePeriod_t *params); +extern RC_t authmgrCtlPortReAuthEnabledSet(uint32 intIfNum, BOOL reAuthEnabled); +extern RC_t authmgrCtlPortStatsClear(uint32 intIfNum); +extern RC_t authmgrCtlApplyConfigData(void); +extern RC_t authmgrCtlApplyPortConfigData(uint32 intIfNum); +extern RC_t authmgrRadiusServerVlanAssignmentHandle(uint32 intIfNum,uint32 vlanId); +extern RC_t authmgrRadiusServerVlanConversionHandle(const char8 *vlanName, uint32 *vlanId); +extern RC_t authmgrVlanAssignmentEnable(authmgrLogicalPortInfo_t *logicalPortInfo,uint32 vlanId); +extern RC_t authmgrVlanAssignmentDisable(uint32 intIfNum,uint32 vlanId); +extern RC_t authmgrPortVlanAssignmentDisable(uint32 intIfNum); +extern RC_t authmgrApplyConfigCompleteCb(uint32 event); +extern void authmgrVlanChangeProcess(uint32 event, uint32 intIfNum, dot1qNotifyData_t *vlanData); +extern RC_t authmgrCheckMapPdu(uint32 intIfNum, char8 *srcMac, uint32 *logicalPort, BOOL *existing_node); +extern RC_t authmgrCtlPortMaxUsersSet(uint32 intIfNum, uint32 maxUsers); +extern RC_t authmgrCtlApplyLogicalPortConfigData(uint32 lIntIfNum); +extern RC_t authmgrCtlResetLogicalPortSessionData(authmgrLogicalPortInfo_t *logicalPortInfo); +extern RC_t authmgrCtlStopLogicalPortSessionData(authmgrLogicalPortInfo_t *logicalPortInfo); +extern RC_t authmgrPortVlanMembershipSet(uint32 intIfNum, uint32 vlanId, BOOL flag); +extern RC_t authmgrVlanAddPortEventProcess(uint32 intIfNum,uint32 VlanId); +extern RC_t authmgrVlanAddEventProcess(uint32 intIfNum,uint32 VlanId); +extern RC_t authmgrVlanDeletePortEventProcess(uint32 intIfNum,uint32 VlanId); +extern RC_t authmgrVlanPVIDChangeEventProcess(uint32 intIfNum,uint32 vlanId); + +extern RC_t authmgrCtlLogicalPortVlanAssignedReset(uint32 lIntIfNum); +extern RC_t authmgrCtlLogicalPortVlanAssignmentDisable(authmgrLogicalPortInfo_t *logicalPortInfo); +extern RC_t authmgrCtlPortUnauthAddrCallbackProcess(uint32 intIfNum, enetMacAddr_t macAddr, ushort16 vlanId); + +/*MAB*/ +extern RC_t authmgrCtlLogicalPortMABTimerStart(uint32 lIntIfNum); +extern RC_t authmgrCtlPortMABEnableSet(uint32 intIfNum); +extern RC_t authmgrCtlPortMABDisableSet(uint32 intIfNum); +extern RC_t authmgrCtlLogicalPortMABRemove(uint32 llIntIfNum); +extern RC_t authmgrCtlLogicalPortMABOperational(uint32 llIntIfNum); +extern RC_t authmgrCtlLogicalPortMABAuthFailGuestVlanSet(authmgrLogicalPortInfo_t *logicalPortInfo); +extern RC_t authmgrCtlLogicalPortMABGuestVlanReset(uint32 lIntIfNum); +extern RC_t authmgrCtlLogicalPortMABGenResp(uint32 lIntIfNum, BOOL generateNak); + +extern RC_t authmgrCtlPortReset(uint32 intIfNum, BOOL initialize); + +/* Authmgr Client Timeout API */ +RC_t authmgrCtlLogicalPortClientTimeout(uint32 lIntIfNum); + +/********************************************************************* +* @purpose Disconnect the client +* +* @param intIfNum @b{(input)) internal interface number +* +* @returns SUCCESS +* @returns FAILURE +* +* @comments +* +* @end +*********************************************************************/ +RC_t authmgrCtlClientCleanup (uint32 lIntIfNum); + +/********************************************************************* + * @purpose Used to change port admin mode. + * + * @param intIfNum @b{(input)) internal interface number + * @param adminMode @b{(input)) administrative mode + * + * @returns SUCCESS + * + * @comments + * + * @end + *********************************************************************/ +RC_t authmgrCtlPortAdminMode(uint32 intIfNum, uint32 adminMode); + +/********************************************************************* + * @purpose control mode function to set the port control mode to auto + * + * @param intIfNum @b{(input)) internal interface number + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t authmgrPortControlAutoActionSet(uint32 intIfNum); + +/********************************************************************* + * @purpose control function to set the host mode to multi host + * + * @param intIfNum @b{(input)) internal interface number + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t authmgrControlMultiHostActionSet(uint32 intIfNum); + +/********************************************************************* + * @purpose control function to set the host mode to single host mode + * + * @param intIfNum @b{(input)) internal interface number + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t authmgrControlSingleAuthActionSet(uint32 intIfNum); + +/********************************************************************* + * @purpose control function to set the host mode to multi auth + * + * @param intIfNum @b{(input)) internal interface number + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t authmgrControlMultAuthActionSet(uint32 intIfNum); + +/********************************************************************* + * @purpose control function to set the to force authorized + * + * @param intIfNum @b{(input)) internal interface number + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t authmgrPortControlForceAuthActionSet(uint32 intIfNum); + +/********************************************************************* + * @purpose control function to set the to force un-authorized + * + * @param intIfNum @b{(input)) internal interface number + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t authmgrPortControlForceUnAuthActionSet(uint32 intIfNum); + +/********************************************************************* + * @purpose function to clean up authmgr port oper info + * + * @param intIfNum @b{(input)) internal interface number + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t authmgrPortInfoCleanup(uint32 intIfNum); + +/********************************************************************* + * @purpose function to check policy validation based on host mode + * + * @param hostMode @b{(input)) hostmode + * @param *appyPolicy @b{(input)) bool value + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t authmgrHostModeHwPolicyApply( AUTHMGR_HOST_CONTROL_t hostMode, uint32 intIfNum, BOOL install); + + +/********************************************************************* + * @purpose Set authmgr authenticated client in specified VLAN + * + * @param logicalPortInfo @b{(input)) Logical Port Info node + * @param reason @b{(input)) Reason for the assignment + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t authmgrClientVlanInfoSet(authmgrLogicalPortInfo_t *logicalPortInfo, + uint32 vlanId); + +/********************************************************************* + * @purpose Set authmgr authenticated client in specified VLAN + * + * @param logicalPortInfo @b{(input)) Logical Port Info node + * @param reason @b{(input)) Reason for the assignment + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t authmgrClientVlanInfoReset(uint32 physPort, + uint32 vlanId); + + +void authmgrTimerExpiryHdlr( APP_TMR_CTRL_BLK_t timerCtrlBlk, void* ptrData); + +/************************************************************************* + * @purpose Starts the specified timer + * + * @param intIfNum @b{(input)} Interface for starting the timer + * @param timerType @b{(input)} Interface/Timer type + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments none + * + * @end + *************************************************************************/ +RC_t authmgrTimerStart(authmgrLogicalPortInfo_t *logicalPortInfo, authmgrTimerType_t type); + +RC_t authmgrTxPeriodGet(uint32 intIfNum, uint32 *val); + +RC_t authmgrQuietPeriodGet(uint32 intIfNum, uint32 *val); + +RC_t authmgrReAuthPeriodGet(uint32 intIfNum, uint32 *val); + +RC_t authmgrServerTimeoutPeriodGet(uint32 intIfNum, uint32 *val); + +RC_t authmgrHostModeMapInfoGet( AUTHMGR_HOST_CONTROL_t type, authmgrHostModeMap_t *elem); +/********************************************************************* + * @purpose control mode function to set the port host mode + * + * @param intIfNum @b{(input)) internal interface number + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t authmgrPortCtrlHostModeSet(uint32 intIfNum, AUTHMGR_HOST_CONTROL_t hostMode); + +/********************************************************************* + * @purpose Control function to handle the authentication method order changes + * + * @param intIfNum @b{(input)) internal interface number + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t authmgrMethodOrderChangeProcess(uint32 intIfNum); +/********************************************************************* + * @purpose authmgr task which serves the request queue + * + * @param none + * + * @returns void + * + * @comments User-interface writes and all are serviced off + * of the authmgrQueue + * + * @end + *********************************************************************/ +void authmgrTask(); +/********************************************************************* +* @purpose authmgr srvr task which serves the request queue +* +* @param none +* +* @returns void +* +* @comments external applications are serviced off +* of the authmgrQueue +* +* @end +*********************************************************************/ +void authmgrSrvrTask (); + +/********************************************************************* + * @purpose Control function to handle the events received from methods + * + * @param intIfNum @b{(input)) internal interface number + * @param status @b{(input)) status from the calling applications like + 802.1X/MAB/CP + * @param macAddr @b{(input)) mac addr of the client + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t authmgrClientCallbackEventProcess(uint32 intIfNum, + authmgrAuthRespParams_t *callbackParams); + +/********************************************************************* + * @purpose Function to Update the statistics + * + * @param intIfNum @b{(input)) internal interface number + * @param method @b{(input)) 802.1x/mab/cp + * @param mode @b{(input)) TRUE/ FALSE + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments TRUE will update the attempts, and FALSE will update the + failed attempts + * + * @end + *********************************************************************/ +RC_t authmgrStatsUpdate(uint32 intIfNum, + AUTHMGR_METHOD_t method, + authmgrStatsUpdate_t status); + +/********************************************************************* + * @purpose Get the next operationally enabled method on a interface + * + * @param intIfNum @b{(input)) internal interface number + * @param method @b{(input)) input method for which next method is needed. + * @param nextMethod @b{(output)) pointer to the next method + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ + +RC_t authmgrNextMethodGet(uint32 intIfNum, + AUTHMGR_METHOD_t *nextMethod); + +RC_t authmgrRegisteredEntryFnMapGet( AUTHMGR_METHOD_t method, authmgrMethodCallbackNotifyMap_t *entry); + +RC_t authmgrAuthenticationTrigger(authmgrLogicalPortInfo_t *logicalPortInfo); +RC_t authmgrPortEnabledMethodCountGet(uint32 physPort, uint32 *count); +/********************************************************************* + * @purpose Get the next operationally enabled method on a interface + * + * @param intIfNum @b{(input)) internal interface number + * @param method @b{(input)) input method for which next method is needed. + * @param nextMethod @b{(output)) pointer to the next method + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ + +RC_t authmgrEnabledMethodNextGet(uint32 intIfNum, + AUTHMGR_METHOD_t *nextMethod); + +/********************************************************************* + * @purpose updates the port pae capabilities + * + * @param intIfNum + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t authmgrPaeCapabilitiesEventProcess(uint32 intIfNum, uint32 mode); + +/********************************************************************* + * @purpose updates the port violation mode + * + * @param intIfNum + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t authmgrViolationModeSetAction(uint32 intIfNum, AUTHMGR_PORT_AUTH_VIOLATION_MODE_t mode); + +/********************************************************************* + * @purpose updates the port max auth retry attempts + * + * @param intIfNum + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t authmgrAuthFailMaxRetryCountSetAction(uint32 intIfNum, uint32 count); + +RC_t authmgrTimerReset(authmgrTimerType_t type); + +RC_t authmgrMethodModifyAction(uint32 intIfNum); +RC_t authmgrLogicalPortReAuthPeriodGet(uint32 lIntfNum, uint32 *val); + + void authmgrAllTimersStart(authmgrTimerType_t type, BOOL flag); + void authmgrAuthClientsTimersRestart(); + +/********************************************************************* + * @purpose updates the port max auth retry attempts + * + * @param intIfNum + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t authmgrAuthFailMaxRetryCountSetAction(uint32 intIfNum, uint32 count); + +/********************************************************************* + * @purpose Set port control mode + * + * @param intIfNum @b{(input)) internal interface number + * @param portControl @b{(input)) port control mode + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t authmgrPortCtrlModeSet(uint32 intIfNum, AUTHMGR_PORT_CONTROL_t portControl); + +/********************************************************************* + * @purpose Enable administrative mode setting for authmgr + * + * @param none + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t authmgrCtlAdminModeEnable(); + +/********************************************************************* + * @purpose Disable administrative mode setting for authmgr + * + * @param none + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t authmgrCtlAdminModeDisable(); + +/********************************************************************* +* @purpose Initialize the Authmgr Port Structure with Default Values +* +* @param intIfNum @b{(input)) internal interface number +* +* @returns SUCCESS +* @returns FAILURE +* +* @comments +* +* @end +*********************************************************************/ +RC_t authmgrPortInfoInitialize(uint32 intIfNum, BOOL flag); + +/********************************************************************* +* @purpose Set values of the Logical Authmgr Port Structure +* with Default Values of port it belongs to +* +* @param logicalPortInfo @b{(input)) Logical port Info +* +* @returns SUCCESS +* @returns FAILURE +* +* @comments +* +* @end +*********************************************************************/ +RC_t authmgrLogicalPortInfoInit(uint32 lIntIfNum); + +/********************************************************************* +* @purpose Populate Auth Manager Global Info structure +* +* @param none +* +* @returns none +* +* @comments +* +* @end +*********************************************************************/ +void authmgrGlobalInfoPopulate(); + +/********************************************************************* + * @purpose Handle dynamic vlan enable event + * + * @param none + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t authmgrCtlDynamicVlanEnableProcess(); + +/********************************************************************* + * @purpose Disable administrative mode setting for authmgr + * + * @param none + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t authmgrCtlDynamicVlanDisableProcess(); + +/********************************************************************* +* @purpose function to start timers on an interface +* +* @param phyIntf interface number +* @param type timer type +* @param flag start or stop +* +* @comments +* +* @end +*********************************************************************/ +void authmgrIntfClientsTimerStart (uint32 phyIntf, authmgrTimerType_t type, + BOOL flag); + +/********************************************************************* +* @purpose Used to get client inactivity timeout +* +* @param val @b{(input)) periodic timeout in seconds +* +* @returns SUCCESS +* +* @comments +* +* @end +*********************************************************************/ +RC_t authmgrCtlPortInactivityPeriodGet (uint32 intIfNum, + uint32 * val); + +/********************************************************************* +* @purpose function to start timers on an interface +* +* @param phyIntf interface number +* @param type timer type +* @param flag start or stop +* +* @comments +* +* @end +*********************************************************************/ +void authmgrIntfClientsTimerStart (uint32 phyIntf, authmgrTimerType_t type, + BOOL flag); + +/********************************************************************* +* @purpose Used to get client inactivity timeout +* +* @param val @b{(input)) periodic timeout in seconds +* +* @returns SUCCESS +* +* @comments +* +* @end +*********************************************************************/ +RC_t authmgrCtlPortInactivityPeriodGet (uint32 intIfNum, + uint32 * val); + +RC_t authmgrCtlPortMethodNoRespPeriodGet (uint32 intIfNum, + uint32 * val); + +/********************************************************************* +* @purpose To close the authenticated sessions gracefully. +* +* @returns SUCCESS +* @returns FAILURE +* +* @comments +* +* @end +*********************************************************************/ +RC_t authmgrTerminateAuthSessions(); + +/* USE C Declarations */ +#ifdef __cplusplus +} +#endif +#endif /* INCLUDE_AUTHMGR_CONTROL_H */ diff --git a/src/sonic-pac/authmgr/mapping/include/auth_mgr_debug.h b/src/sonic-pac/authmgr/mapping/include/auth_mgr_debug.h new file mode 100755 index 000000000000..80ea003926f1 --- /dev/null +++ b/src/sonic-pac/authmgr/mapping/include/auth_mgr_debug.h @@ -0,0 +1,146 @@ +/* + * Copyright 2024 Broadcom Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INCLUDE_AUTHMGR_DEBUG_H +#define INCLUDE_AUTHMGR_DEBUG_H + +/* USE C Declarations */ +#ifdef __cplusplus +extern "C" { +#endif + +#define AUTHMGR_TRACE(format,args...) \ +{ \ + if ( authmgrDebugLogTraceModeGet() == ENABLE) \ + { \ + LOGF( LOG_SEVERITY_INFO,format,##args); \ + } \ +} + +#define AUTHMGR_ERROR_SEVERE(format,args...) \ +{ \ + LOGF( LOG_SEVERITY_ERROR,format,##args); \ +} + +/* logical port debug info */ +typedef struct authmgrLogicalPortDebugInfo_s +{ + /* unique node identifier*/ + authmgrLogicalNodeKey_t key; + char8 timers[200]; + + /* protocol related info */ + authmgrProtocolInfo_t protocol; + + /* client specific non protocol data */ + authmgrClientInfo_t client; + +} authmgrLogicalPortDebugInfo_t; + +extern void authmgrDebugMsgQueue(); +extern void authmgrDebugTraceIdGet(); +extern void authmgrDebugSizesShow(); +extern void authmgrDebugPortCfgShow(uint32 intIfNum); +extern void authmgrDebugPortInfoShow(uint32 intIfNum); +extern void authmgrDebugPortStatsShow(uint32 intIfNum); +extern RC_t authmgrDebugLogTraceModeSet(uint32 mode); +extern uint32 authmgrDebugLogTraceModeGet(); +extern BOOL authmgrDebugPacketTraceTxFlag; +extern BOOL authmgrDebugPacketTraceRxFlag; + +extern void authmgrBuildTestConfigData(void); +extern RC_t authmgrDebugSave(void); +extern void authmgrDebugBuildDefaultConfigData(uint32 ver); +extern BOOL authmgrDebugHasDataChanged(void); +extern void authmgrDebugPacketTraceFlagGet( BOOL *transmitFlag, BOOL *receiveFlag); +extern RC_t authmgrDebugPacketTraceFlagSet( BOOL transmitFlag, BOOL receiveFlag); +extern void authmgrDebugPacketRxTrace(uint32 intIfNum, netBufHandle bufHandle); +extern void authmgrDebugPacketTxTrace(uint32 intIfNum, netBufHandle bufHandle); +extern void authmgrDebugPacketTrace(uint32 intIfNum, netBufHandle bufHandle, BOOL rxFlag, BOOL txFlag); +extern void authmgrDebugPacketDump(uint32 flag,uint32 physPort,uint32 intIfNum, netBufHandle bufHandle); +extern void authmgrDebugDataDump(uint32 flag, uint32 physPort, uchar8 *data,uint32 len); + +extern void authmgrDebugLogicalPortInfoShow(uint32 intIfNum, uint32 lIntIfNum); + +#define AUTHMGR_USER_TRACE_TX(__fmt__, __args__... ) \ + if (authmgrDebugPacketTraceTxFlag == TRUE) \ + { \ + LOG_USER_TRACE( AUTHMGR_COMPONENT_ID, __fmt__,##__args__); \ + } + +#define AUTHMGR_USER_TRACE_RX(__fmt__, __args__... ) \ + if (authmgrDebugPacketTraceRxFlag == TRUE) \ + { \ + LOG_USER_TRACE( AUTHMGR_COMPONENT_ID, __fmt__,##__args__); \ + } + + + +#define AUTHMGR_TRACE_PORT_STATUS 0x0001 +#define AUTHMGR_TRACE_EVENTS 0x0002 +#define AUTHMGR_TRACE_API_CALLS 0x0004 +#define AUTHMGR_TRACE_FSM_EVENTS 0x0008 +#define AUTHMGR_TRACE_FAILURE 0x0010 +#define AUTHMGR_TRACE_RADIUS 0x0020 +#define AUTHMGR_TRACE_TIMER 0x0040 +#define AUTHMGR_TRACE_MAC_ADDR_DB 0x0080 +#define AUTHMGR_TRACE_CLIENT 0x0800 + +extern uint32 authmgrDebugTraceFlag; +extern uint32 authmgrDebugTraceIntf; + +#define AUTHMGR_EVENT_TRACE(flag,intf,__fmt__, __args__...) \ + /*if ((authmgrDebugTraceFlag&flag) != 0 && (intf==0 || authmgrDebugTraceIntf ==0 || intf == authmgrDebugTraceIntf))*/ \ + { \ + char8 __buf1__[256]; \ + (void)osapiSnprintf (__buf1__, 256, __fmt__, ## __args__); \ + LOGF( LOG_SEVERITY_DEBUG, \ + "[%s:%d]%s",__FUNCTION__, __LINE__, __buf1__); \ + } + +void authmgrDevshellHelpPrint(); + +char *authmgrHostModeStringGet( AUTHMGR_HOST_CONTROL_t hostMode); +char *authmgrNodeTypeStringGet(authmgrNodeType_t type); +char *authmgrTimerTypeStringGet(authmgrTimerType_t type); +char *authmgrVlanTypeStringGet(authmgrVlanType_t type); +char *authmgrAuthStateStringGet(AUTHMGR_STATES_t state); +char *authmgrMethodStringGet( AUTHMGR_METHOD_t method); +char *authmgrMethodStatusStringGet( AUTHMGR_STATUS_t status); +char *authmgrSmEventStringGet(authmgrSmEvents_t event); +char *authmgrListTypeStringGet( AUTHMGR_METHOD_TYPE_t status); +char *authmgrClientTypeStringGet(authmgrClientType_t type); +char *authmgrAuthStatusStringGet( AUTHMGR_PORT_STATUS_t status); +void authmgrSuppMacStringGet( enetMacAddr_t *suppMacAddr); +char *authmgrAuthMethodStringGet(uint32 authMethod); +void authmgrDebugTraceEvent(uint32 debug,uint32 intfNum); +RC_t authmgrDebugTraceEventGet(uint32 *pDebug, uint32 *pIntfNum); + +void authmgrBuildTestConfigData(void); +void authmgrDebugBuildDefaultConfigData(uint32 ver); +BOOL authmgrDebugHasDataChanged(void); + +void authmgrDebugLogicalPortInfoShow(uint32 intIfNum, uint32 lIntIfNum); + +RC_t authmgrLportPortGet(uint32 *intIfNum, uint32 *lIntIfNum); +void authmgrUserCountDump(uint32 intIfNum); +RC_t authmgrDebugLogicalPortInfoNextGet (uint32 intIfNum, uint32 *lIntIfNum, + authmgrLogicalPortDebugInfo_t *debugInfo); + /* USE C Declarations */ +#ifdef __cplusplus +} +#endif +#endif /* INCLUDE_AUTHMGR_DEBUG_H*/ diff --git a/src/sonic-pac/authmgr/mapping/include/auth_mgr_ih.h b/src/sonic-pac/authmgr/mapping/include/auth_mgr_ih.h new file mode 100755 index 000000000000..ac623f7dea20 --- /dev/null +++ b/src/sonic-pac/authmgr/mapping/include/auth_mgr_ih.h @@ -0,0 +1,45 @@ +/* + * Copyright 2024 Broadcom Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INCLUDE_AUTHMGR_IH_H +#define INCLUDE_AUTHMGR_IH_H + +/* USE C Declarations */ +#ifdef __cplusplus +extern "C" { +#endif + +extern RC_t authmgrIntfChangeCallback(uint32 intIfNum, uint32 intfEvent,NIM_CORRELATOR_t correlator, + NIM_EVENT_SPECIFIC_DATA_t eventData); + +extern RC_t authmgrIhProcessIntfChange(uint32 intIfNum, uint32 intfEvent, NIM_CORRELATOR_t correlator); +extern RC_t authmgrIhProcessIntfStartup(NIM_STARTUP_PHASE_t startupPhase); +extern RC_t authmgrIntfActivateStartup(); +extern void authmgrIntfStartupCallback(NIM_STARTUP_PHASE_t startupPhase); +extern RC_t authmgrIhIntfValidate(uint32 intIfNum); +extern BOOL authmgrIntfIsConfigurable(uint32 intIfNum, authmgrPortCfg_t **pCfg); +extern BOOL authmgrIntfConfigEntryGet(uint32 intIfNum, authmgrPortCfg_t **pCfg); +extern RC_t authmgrIntfCreate(uint32 intIfNum); +extern RC_t authmgrIntfDetach(uint32 intIfNum); +extern RC_t authmgrIntfDelete(uint32 intIfNum); +extern RC_t authmgrIhPhyPortViolationCallbackSet(uint32 intIfNum, AUTHMGR_PORT_VIOLATION_CALLBACK_t flag); +extern RC_t authmgrAuthViolationDiagDisablePort(uint32 IntIfNum); +/* USE C Declarations */ +#ifdef __cplusplus +} +#endif + +#endif /*INCLUDE_AUTHMGR_IH_H*/ diff --git a/src/sonic-pac/authmgr/mapping/include/auth_mgr_include.h b/src/sonic-pac/authmgr/mapping/include/auth_mgr_include.h new file mode 100755 index 000000000000..2008eeb4fce4 --- /dev/null +++ b/src/sonic-pac/authmgr/mapping/include/auth_mgr_include.h @@ -0,0 +1,69 @@ +/* + * Copyright 2024 Broadcom Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INCLUDE_AUTHMGR_INCLUDE_H +#define INCLUDE_AUTHMGR_INCLUDE_H + +/* USE C Declarations */ +#ifdef __cplusplus +extern "C" { +#endif +/* +*********************************************************************** +* COMMON INCLUDES +*********************************************************************** +*/ +#include "pacinfra_common.h" +#include "osapi.h" +#include "nimapi.h" +#include "log.h" +#include +#include "datatypes.h" +#include "auth_mgr_api.h" + +/* +********************************************************************** +* STANDARD LIBRARIES +********************************************************************** +*/ +#include +#include +#include + +/* +********************************************************************** +* AUTHMGR HEADER FILES +********************************************************************** +*/ +#include "auth_mgr_exports.h" +#include "auth_mgr_sid.h" +#include "auth_mgr_sm.h" +#include "auth_mgr_db.h" +#include "auth_mgr_cfg.h" +#include "auth_mgr_control.h" +#include "auth_mgr_ih.h" +#include "auth_mgr_txrx.h" +#include "auth_mgr_debug.h" +#include "auth_mgr_mac_db.h" +#include "auth_mgr_client.h" +#include "auth_mgr_radius.h" +#include "auth_mgr_vlan.h" +#include "auth_mgr_util.h" + +#ifdef __cplusplus +} +#endif +#endif /* INCLUDE_AUTHMGR_INCLUDE_H */ diff --git a/src/sonic-pac/authmgr/mapping/include/auth_mgr_struct.h b/src/sonic-pac/authmgr/mapping/include/auth_mgr_struct.h new file mode 100755 index 000000000000..4d2770fa4f30 --- /dev/null +++ b/src/sonic-pac/authmgr/mapping/include/auth_mgr_struct.h @@ -0,0 +1,89 @@ +/* + * Copyright 2024 Broadcom Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INCLUDE_AUTHMGR_STRUCT_H +#define INCLUDE_AUTHMGR_STRUCT_H + +/* USE C Declarations */ +#ifdef __cplusplus +extern "C" { +#endif + +#include "pacinfra_common.h" +#include "osapi.h" +#include "portevent_mask.h" +#include "avl_api.h" +#include "tree_api.h" +#include "apptimer_api.h" +#include "auth_mgr_db.h" +#include "auth_mgr_cfg.h" +#include "auth_mgr_api.h" +#include "auth_mgr_debug.h" +#include "auth_mgr_include.h" + +typedef struct authmgrGlobalInfo_s +{ + authmgrCfg_t *authmgrCfg; + authmgrInfo_t authmgrInfo; + authmgrPortInfo_t *authmgrPortInfo; + authmgrPortStats_t *authmgrPortStats; + uint32 *authmgrMapTbl; + authmgrPortSessionStats_t *authmgrPortSessionStats; + authmgrDebugCfg_t authmgrDebugCfg; + + authmgrMethodCallbackNotifyMap_t authmgrCallbacks[ AUTHMGR_METHOD_LAST]; + /* App timer related data */ + APP_TMR_CTRL_BLK_t authmgrTimerCB; + uint32 authmgrAppTimerBufferPoolId; + + /* avl tree parameters */ + avlTree_t authmgrLogicalPortTreeDb; + avlTreeTables_t *authmgrLogicalPortTreeHeap; + authmgrLogicalPortInfo_t *authmgrLogicalPortDataHeap; + + uint32 authmgrMacAddrBufferPoolId; + sll_t authmgrMacAddrSLL; + osapiRWLock_t authmgrMacAddrDBRWLock; + + VLAN_MASK_t authmgrVlanMask; + int32 eap_socket; + uint32 reservedVlan; +}authmgrGlobalInfo_t; + +typedef struct authmgrCB_s +{ + void *authmgrTaskSyncSema; + void * authmgrTaskId; + void *authmgrSrvrTaskSyncSema; + void * authmgrSrvrTaskId; + int listen_sock; + osapiRWLock_t authmgrRWLock; + osapiRWLock_t authmgrCfgRWLock; + void *authmgrQueue; /* reference to the authmgr message queue */ + void *authmgrBulkQueue; /* reference to the authmgr bulk message queue */ + void *authmgrVlanEventQueue; /* reference to the authmgr vlan message queue */ + authmgrGlobalInfo_t *globalInfo; + authmgrClientInfo_t processInfo; + authmgrClientInfo_t oldInfo; + authmgrAuthAttributeInfo_t attrInfo; +}authmgrCB_t; + +/* USE C Declarations */ +#ifdef __cplusplus +} +#endif + +#endif /* INCLUDE_AUTHMGR_STRUCT_H */ From 2e55c75e38aff762b123322efb277f12e71f2561 Mon Sep 17 00:00:00 2001 From: Vijaya Kumar Abbaraju Date: Sat, 26 Oct 2024 00:37:46 +0530 Subject: [PATCH 14/23] MAB protocol related header files (#18629) --- src/sonic-pac/mab/protocol/include/mab_auth.h | 59 ++++ src/sonic-pac/mab/protocol/include/mab_db.h | 272 ++++++++++++++++++ .../mab/protocol/include/mab_local.h | 35 +++ .../mab/protocol/include/mab_mac_db.h | 43 +++ .../mab/protocol/include/mab_radius.h | 48 ++++ .../mab/protocol/include/mab_timer.h | 118 ++++++++ src/sonic-pac/mab/protocol/include/mab_util.h | 83 ++++++ src/sonic-pac/mab/protocol/include/mab_vlan.h | 81 ++++++ 8 files changed, 739 insertions(+) create mode 100755 src/sonic-pac/mab/protocol/include/mab_auth.h create mode 100644 src/sonic-pac/mab/protocol/include/mab_db.h create mode 100755 src/sonic-pac/mab/protocol/include/mab_local.h create mode 100755 src/sonic-pac/mab/protocol/include/mab_mac_db.h create mode 100644 src/sonic-pac/mab/protocol/include/mab_radius.h create mode 100755 src/sonic-pac/mab/protocol/include/mab_timer.h create mode 100755 src/sonic-pac/mab/protocol/include/mab_util.h create mode 100755 src/sonic-pac/mab/protocol/include/mab_vlan.h diff --git a/src/sonic-pac/mab/protocol/include/mab_auth.h b/src/sonic-pac/mab/protocol/include/mab_auth.h new file mode 100755 index 000000000000..66fabcac546f --- /dev/null +++ b/src/sonic-pac/mab/protocol/include/mab_auth.h @@ -0,0 +1,59 @@ +/* + * Copyright 2024 Broadcom Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INCLUDE_MAB_AUTH_H +#define INCLUDE_MAB_AUTH_H + +/* USE C Declarations */ +#ifdef __cplusplus + extern "C" { +#endif +#include "comm_mask.h" + +/********************************************************************* + * @purpose Actions to be performed when sending request to a client + * + * @param logicalPortInfo @b{(input)) Logical Port Info node + * @param bufHandle @b{(input)) buff handle + * + * @returns SUCCESS + * + * @comments + * + * @end + *********************************************************************/ +RC_t mabClientRequestAction(mabLogicalPortInfo_t *logicalPortInfo, netBufHandle bufHandle); + +/********************************************************************* + * @purpose Actions to be performed when sending response to AAA + * + * @param logicalPortInfo @b{(input)) Logical Port Info node + * @param bufHandle @b{(input)) buff handle + * + * @returns SUCCESS + * + * @comments + * + * @end + *********************************************************************/ +RC_t mabClientResponseAction(mabLogicalPortInfo_t *logicalPortInfo, netBufHandle bufHandle); + +/* USE C Declarations */ +#ifdef __cplusplus +} +#endif + +#endif /* INCLUDE_MAB_AUTH_H */ diff --git a/src/sonic-pac/mab/protocol/include/mab_db.h b/src/sonic-pac/mab/protocol/include/mab_db.h new file mode 100644 index 000000000000..005692f8c29b --- /dev/null +++ b/src/sonic-pac/mab/protocol/include/mab_db.h @@ -0,0 +1,272 @@ +/* + * Copyright 2024 Broadcom Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef INCLUDE_MAB_DB_H +#define INCLUDE_MAB_DB_H + +/* USE C Declarations */ +#ifdef __cplusplus + extern "C" { +#endif + +#include "comm_mask.h" +#include "apptimer_api.h" +#include "mab_vlan.h" +#include "auth_mgr_exports.h" +#include "mab_radius.h" +#include "mab_exports.h" +#include "mab_util.h" +#include "avl_api.h" +#include "radius_attr_parse.h" + +#define MAB_USER_INDEX_INVALID -1 + +#define MAB_MD5_LEN 16 + +#define MAB_SERVER_STATE_LEN 253 +#define MAB_SERVER_CLASS_LEN 253 + +#define MAB_FILTER_NAME_LEN 256 + +#define MAB_LOGICAL_PORT_START 0 +#define MAB_LOGICAL_PORT_END MAB_MAX_USERS_PER_PORT + +#define MAB_LOGICAL_PORT_ITERATE 0xFFFFFFFF +#define MAB_RADIUS_VLAN_ASSIGNED_LEN 32 /* Radius Assigned vlan length */ + +/* switch info */ +typedef struct mabInfo_s +{ + uint32 traceId; +} mabInfo_t; + +typedef enum mabTimerType_s +{ + MAB_TIMER_UNASSIGNED = 0, + MAB_SERVER_AWHILE, +}mabTimerType_t; + +typedef enum +{ + MAB_UNAUTHENTICATED = 0, + MAB_AUTHENTICATING, + MAB_AUTHENTICATED +} MAB_AUTH_STATES_t; + +typedef struct mabProtocolInfo_s +{ + MAB_AUTH_STATES_t mabAuthState; + BOOL authSuccess; + BOOL authFail; +}mabProtocolInfo_t; + +typedef struct mabClientInfo_s +{ + /* mab Client category */ + authmgrClientType_t clientType; + + /* Re-auth and session related info */ + uchar8 currentIdL; /* ID of current auth session (0-255) */ + BOOL reAuthenticate; /* Set to TRUE when reAuthWhen timer expires */ + + /* client authentication status */ + AUTHMGR_PORT_STATUS_t logicalPortStatus; /* Current authorization state of the port */ + + /* user Details */ + uchar8 mabUserName[MAB_USER_NAME_LEN]; + uint32 mabUserNameLength; + int32 mabUserIndex; + + uchar8 mabChallenge[MAB_CHALLENGE_LEN]; + uint32 mabChallengelen; + + netBufHandle suppBufHandle; /* Hold onto buf handle for re-transmit */ + enetMacAddr_t suppMacAddr; /* MAC address of Supplicant */ + + /* vlan related info */ + authmgrVlanType_t vlanType; /* assigned vlan category */ + uint32 vlanId; /* Vlan Id of Supplicant */ + + attrInfo_t attrInfo; + uchar8 filterName[MAB_FILTER_NAME_LEN]; + + USER_MGR_AUTH_METHOD_t authMethod; /* Auth method for the user of this port */ + + AUTHMGR_PORT_MAB_AUTH_TYPE_t mabAuthType; /* Authentication type used by MAB. To be filled in only if isMABClient is TRUE */ + +}mabClientInfo_t; + +typedef struct mabLogicalNodeKey_s +{ + /* first 16 bits represent physical port + next 12 bits represent logical port + and remaining 3 bits represent client type. + last bit is always 0 */ + uint32 keyNum; +}mabLogicalNodeKey_t; + + +typedef struct mabTimerContext_s +{ + mabTimerType_t type; + uint32 keyNum; +}mabTimerContext_t; + + +typedef struct mabTimerHandle_s +{ + APP_TMR_HNDL_t timer; + /* void *timerHandle; */ +}mabTimerHandle_t; + + +typedef struct mabTimer_s +{ + mabTimerContext_t cxt; + mabTimerHandle_t handle; +}mabTimer_t; + + +/* logical port info */ +typedef struct mabLogicalPortInfo_s +{ + /* unique node identifier*/ + mabLogicalNodeKey_t key; + + mabTimer_t mabTimer; + + /* protocol related info */ + mabProtocolInfo_t protocol; + + /* client specific non protocol data */ + mabClientInfo_t client; + + void *next; /* This field must be the last one in this structure */ +} mabLogicalPortInfo_t; + + +/* Per-port info */ +typedef struct mabPortInfo_s +{ + uint32 maxUsers; + uint32 numUsers; + + /* Inter-state machine communication and initialization */ + uchar8 currentId; /* ID of current auth session (0-255) */ + BOOL initialize; /* Set to TRUE by mgmt to cause port initialization */ + AUTHMGR_PORT_CONTROL_t portControlMode; /* Current control mode setting by mgmt */ + AUTHMGR_HOST_CONTROL_t hostMode; /* host mode setting by mgmt */ + BOOL portEnabled; /* TRUE if port is active */ + uint32 authCount; /* number of authorized clients */ + uint32 serverTimeout; /* Initialization value for aWhile timer when timing out Auth. Server */ + USER_MGR_AUTH_METHOD_t authMethod; /* Authentication method for the user of this port */ + AcquiredMask acquiredList; /* Mask of components "acquiring" an interface */ + uint32 mabEnabled; /* ENABLE if MAB has been enabled on the port and port control mode is mac-based*/ + +} mabPortInfo_t; + +typedef RC_t(*mabCtrlTimerExpiryFn_t) (mabLogicalPortInfo_t *logicalPortInfo); +typedef RC_t(*mabCtrlTimerNodeSetFn_t) (uint32 intIfNum, uint32 val); +typedef RC_t(*mabCtrlTimerNodeGetFn_t) (uint32 intIfNum, uint32 *val); + +typedef struct mabTimerMap_s +{ + mabTimerType_t type; + mabCtrlTimerExpiryFn_t expiryFn; +}mabTimerMap_t; + + +typedef RC_t(*mabCtrlHostModeSetFn_t) (uint32 intIfNum); + +typedef struct mabHostModeMap_s +{ + AUTHMGR_HOST_CONTROL_t hostMode; + mabCtrlHostModeSetFn_t hostModeFn; +}mabHostModeMap_t; + + +typedef RC_t(*mabPortCtrlLearnFn_t) (uint32 intIfNum); + +typedef struct mabPortCtrlLearnMap_s +{ + AUTHMGR_PORT_CONTROL_t portControlMode; + mabPortCtrlLearnFn_t learnFn; +}mabPortCtrlLearnMap_t; + + +typedef RC_t(*mabHostCtrlLearnFn_t) (uint32 intIfNum); + +typedef struct mabHostCtrlLearnMap_s +{ + AUTHMGR_HOST_CONTROL_t hostMode; + mabHostCtrlLearnFn_t learnFn; +}mabHostCtrlLearnMap_t; + +typedef RC_t(*mabAuthmgrEventMapFn_t) (uint32 intIfNum, enetMacAddr_t suppMacAddr); + +typedef struct mabAuthmgrEventFnMap_s +{ + uint32 event; + mabAuthmgrEventMapFn_t eventMapFn; +}mabAuthmgrEventFnMap_t; + +/* This structure is used to keep track of vlan addport/delport evetnts */ +typedef struct mabMacBasedVlanParticipation_s +{ + INTF_MASK_t intfBitMask; + INTF_MASK_t adminBitMask; /* Dot1q admin mode */ +}mabMacBasedVlanParticipation_t; + + +typedef struct mabPortStats_s +{ + /* Authenticator Diagnostics */ + uint32 authEntersAuthenticating; + uint32 authAuthSuccessWhileAuthenticating; +} mabPortStats_t; + +extern mabInfo_t mabInfo; +extern mabPortInfo_t *mabPortInfo; +extern mabPortStats_t *mabPortStats; +extern uint32 *mabMapTbl; + +/*********************************************************************************************/ + + +/* Prototypes for the mab_db.c file */ +RC_t mabLogicalPortInfoDBInit(uint32 nodeCount); +RC_t mabLogicalPortInfoDBDeInit(void); + +RC_t mabLogicalPortInfoTakeLock(void); +RC_t mabLogicalPortInfoGiveLock(void); + +mabLogicalPortInfo_t *mabLogicalPortInfoAlloc(uint32 intIfNum); +RC_t mabLogicalPortInfoDeAlloc(mabLogicalPortInfo_t *node); + +mabLogicalPortInfo_t *mabLogicalPortInfoGet(uint32 lIntIfNum); +mabLogicalPortInfo_t *mabLogicalPortInfoGetNext(uint32 lIntIfNum); + +mabLogicalPortInfo_t *mabLogicalPortInfoFirstGet(uint32 intIfNum, + uint32 *lIntIfNum); +mabLogicalPortInfo_t *mabLogicalPortInfoGetNextNode(uint32 intIfNum, + uint32 *lIntIfNum); +/* USE C Declarations */ +#ifdef __cplusplus +} +#endif + +#endif /* INCLUDE_MAB_DB_H */ diff --git a/src/sonic-pac/mab/protocol/include/mab_local.h b/src/sonic-pac/mab/protocol/include/mab_local.h new file mode 100755 index 000000000000..8d83fb3e5b93 --- /dev/null +++ b/src/sonic-pac/mab/protocol/include/mab_local.h @@ -0,0 +1,35 @@ +/* + * Copyright 2024 Broadcom Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INCLUDE_MAB_LOCAL_H +#define INCLUDE_MAB_LOCAL_H + +/* USE C Declarations */ +#ifdef __cplusplus +extern "C" { +#endif + +extern RC_t mabLocalAuthResponseProcess(mabLogicalPortInfo_t *logicalPortInfo, netBufHandle bufHandle); +extern RC_t mabLocalAuthMd5ResponseValidate(mabLogicalPortInfo_t *logicalPortInfo, uchar8 *response); +extern void mabLocalAuthChallengeGenerate( uchar8 *challenge, uint32 challengeLen); +extern void mabLocalMd5Calc( uchar8 *inBuf, uint32 inLen, uchar8 *outBuf); + +/* USE C Declarations */ +#ifdef __cplusplus +} +#endif + +#endif /* INCLUDE_MAB_LOCAL_H */ diff --git a/src/sonic-pac/mab/protocol/include/mab_mac_db.h b/src/sonic-pac/mab/protocol/include/mab_mac_db.h new file mode 100755 index 000000000000..3655343233d6 --- /dev/null +++ b/src/sonic-pac/mab/protocol/include/mab_mac_db.h @@ -0,0 +1,43 @@ +/* + * Copyright 2024 Broadcom Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INCLUDE_MAB_MAC_DB_H +#define INCLUDE_MAB_MAC_DB_H + +/* USE C Declarations */ +#ifdef __cplusplus +extern "C" { +#endif + + +#include "sll_api.h" +#include "buff_api.h" + +extern RC_t mabMacAddrDataDestroy ( sll_member_t *ll_member); +extern int32 mabMacAddrDataCmp(void *p, void *q, uint32 key); +extern RC_t mabMacAddrInfoDBInit(uint32 nodeCount); +extern RC_t mabMacAddrInfoDBDeInit(void); +extern RC_t mabMacAddrInfoAdd( enetMacAddr_t *mac_addr,uint32 lIntIfNum); +extern RC_t mabMacAddrInfoRemove( enetMacAddr_t *mac_addr); +extern RC_t mabMacAddrInfoFind( enetMacAddr_t *mac_addr,uint32 *lIntIfNum); +extern RC_t mabMacAddrInfoFindNext( enetMacAddr_t *mac_addr,uint32 *lIntIfNum); + + +/* USE C Declarations */ +#ifdef __cplusplus +} +#endif +#endif /* INCLUDE_MAB_MAC_DB_H */ diff --git a/src/sonic-pac/mab/protocol/include/mab_radius.h b/src/sonic-pac/mab/protocol/include/mab_radius.h new file mode 100644 index 000000000000..89e5556d4b34 --- /dev/null +++ b/src/sonic-pac/mab/protocol/include/mab_radius.h @@ -0,0 +1,48 @@ +/* + * Copyright 2024 Broadcom Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __INCLUDE_MAB_RADIUS_H__ +#define __INCLUDE_MAB_RADIUS_H__ + +/* USE C Declarations */ +#ifdef __cplusplus +extern "C" { +#endif + +#include "radius_attr_parse.h" + +extern RC_t mabRadiusResponseCallback(void *msg, uint32 correlator); +extern RC_t mabRadiusResponseProcess(unsigned int lIntIfNum, void *resp); +extern RC_t mabRadiusAcceptProcess(uint32 intIfNum, void *payload); +extern RC_t mabRadiusResponseHandle(void *resp, int len); +extern RC_t mabSendRespToServer(uint32 lIntIfNum, netBufHandle bufHandle); + +extern RC_t mabRadiusChallengeProcess(uint32 intIfNum, void *radiusPayload); +extern RC_t mabRadiusAccessRequestSend(uint32 intIfNum, uchar8 *suppEapData); +extern RC_t mabRadiusSuppResponseProcess(uint32 intIfNum, netBufHandle bufHandle); +extern void mabRadiusClearRadiusMsgsSend( enetMacAddr_t suppMacAddr); + +extern int radius_mab_client_register(void *data); + +extern RC_t mabRadiusServerTaskLockTake(void); +extern RC_t mabRadiusServerTaskLockGive(void); + +/* USE C Declarations */ +#ifdef __cplusplus +} +#endif + +#endif /* __INCLUDE_MAB_RADIUS_H__*/ diff --git a/src/sonic-pac/mab/protocol/include/mab_timer.h b/src/sonic-pac/mab/protocol/include/mab_timer.h new file mode 100755 index 000000000000..14df030abd90 --- /dev/null +++ b/src/sonic-pac/mab/protocol/include/mab_timer.h @@ -0,0 +1,118 @@ +/* + * Copyright 2024 Broadcom Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INCLUDE_MAB_TIMER_H +#define INCLUDE_MAB_TIMER_H + +/* USE C Declarations */ +#ifdef __cplusplus +extern "C" { +#endif + +#include "comm_mask.h" + +/********************************************************************* + * @purpose This function is used to send timer events + * + * @param timerCtrlBlk @b{(input)} Timer Control Block + * @param ptrData @b{(input)} Ptr to passed data + * + * @returns None + * + * @notes None + * @end + *********************************************************************/ +void mabTimerExpiryHdlr( APP_TMR_CTRL_BLK_t timerCtrlBlk, void* ptrData); + +/************************************************************************* + * @purpose Starts the specified timer + * + * @param intIfNum @b{(input)} Interface for starting the timer + * @param timerType @b{(input)} Interface/Timer type + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments none + * + * @end + *************************************************************************/ +RC_t mabTimerStart(mabLogicalPortInfo_t *logicalPortInfo, mabTimerType_t timerType); + +/************************************************************************* + * @purpose Helper API to delete the specifed timer node + * + * @param timer @b{(input)} Pointer to appTimer node + * @param handle @b{(input)} Pointer to appTimer handle handle + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments none + * + * @end + *************************************************************************/ +RC_t mabTimerDestroy( APP_TMR_CTRL_BLK_t timerCB, + mabLogicalPortInfo_t *logicalPortInfo); + +/************************************************************************* + * @purpose Process the mab timer expiry event + * + * @param param @b{(input)} Pointer to added mab node identifier + * + * @returns void + * + * @comments none + * + * @end + *************************************************************************/ +void mabTimerExpiryAction(void *param); + + +/************************************************************************* + * @purpose get the map table entry for the timer type + * + * @param param @b{(input)} Pointer to added mab node identifier + * + * @returns void + * + * @comments none + * + * @end + *************************************************************************/ +RC_t mabTimerHandlerInfoGet(mabTimerType_t type, mabTimerMap_t *handler); + +/************************************************************************* + * @purpose function to process on expiry of server awhile timer + * + * @param timer @b{(input)} Pointer to appTimer node + * @param logicalPortInfo @b{(input)} Pointer to logicalPort Info + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments none + * + * @end + *************************************************************************/ +RC_t mabServerAwhileExpiryAction(mabLogicalPortInfo_t *logicalPortInfo); + +/* USE C Declarations */ +#ifdef __cplusplus +} +#endif + +#endif /* INCLUDE_MAB_TIMER_H */ diff --git a/src/sonic-pac/mab/protocol/include/mab_util.h b/src/sonic-pac/mab/protocol/include/mab_util.h new file mode 100755 index 000000000000..d5dc3470d9ae --- /dev/null +++ b/src/sonic-pac/mab/protocol/include/mab_util.h @@ -0,0 +1,83 @@ +/* + * Copyright 2024 Broadcom Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INCLUDE_MAB_UTIL_H +#define INCLUDE_MAB_UTIL_H + +/* USE C Declarations */ +#ifdef __cplusplus +extern "C" { +#endif + +#include "comm_mask.h" +#include "apptimer_api.h" +#include "mab_radius.h" +#include "mab_exports.h" + + +#define MAB_LPORT_KEY_PACK(_x, _y, _z, _val) \ + do { \ + _val |= ((_x<<16) | (_y<<4) | (_z)); \ + } while (0); + +#define MAB_LPORT_KEY_UNPACK(_x, _y, _z, _val) \ + do { \ + _x = (_val & 0XFFFF0000)>>16; \ + _y = (_val & 0X0000FFF0)>>4; \ + _z = (_val & 0X0000000F); \ + } while (0); + + +#define MAB_PORT_GET(_x, _val) \ + _x = (_val & 0XFFFF0000)>>16; + + +#define MAB_LPORT_GET(_y, _val) \ + _y = (_val & 0X0000FFF0)>>4; + + +#define MAB_TYPE_GET(_z, _val) \ + _z = (_val & 0X0000000F); + + +#define MAB_IF_NULLPTR_RETURN_LOG(_p) \ + if ( NULLPTR == _p) \ + { \ + MAB_EVENT_TRACE("%s is NULLPTR.", #_p); \ + return FAILURE; \ + } + +/********************************************************************* + * @purpose function to check policy validation based on host mode + * + * @param hostMode @b{(input)) hostmode + * @param *appyPolicy @b{(input)) bool value + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t mabHostIsDynamicNodeAllocCheck( AUTHMGR_HOST_CONTROL_t hostMode, BOOL *valid); + +/* USE C Declarations */ +#ifdef __cplusplus +} +#endif + +#endif /* INCLUDE_MAB_UTIL_H */ diff --git a/src/sonic-pac/mab/protocol/include/mab_vlan.h b/src/sonic-pac/mab/protocol/include/mab_vlan.h new file mode 100755 index 000000000000..e27aca8f5080 --- /dev/null +++ b/src/sonic-pac/mab/protocol/include/mab_vlan.h @@ -0,0 +1,81 @@ +/* + * Copyright 2024 Broadcom Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INCLUDE_MAB_VLAN_H +#define INCLUDE_MAB_VLAN_H + +/* USE C Declarations */ +#ifdef __cplusplus +extern "C" { +#endif + +#include "comm_mask.h" +#include "mab_exports.h" + +/********************************************************************* + * @purpose check if the port participation can be removed for a vlan + * + * @param physPort @b{(input)) Port + * @param vlanId @b{(input)) vlan Id + * + * @returns SUCCESS/ FAILRE + * + * @comments + * + * @end + *********************************************************************/ +RC_t mabVlanPortDeletionValidate(uint32 physPort, uint32 vlanId); + + +/********************************************************************* + * @purpose check if the port can be aquired by mab + * + * @param physPort @b{(input)) Port + * @param vlanId @b{(input)) vlan Id + * + * @returns SUCCESS/ FAILRE + * + * @comments + * + * @end + *********************************************************************/ +RC_t mabVlanPortAcquireCheck(uint32 physPort); + +/********************************************* + * @purpose Enable mab vlan to a specified interface + * + * @param intIfNum @b{(input)) internal interface number + * @param guestVlanId @b{(input)} guest vlan id + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t mabVlanDeleteProcess(uint32 vlanId); + + +RC_t mabVlanPortDeleteProcess(uint32 intIfNum,uint32 vlanId); +RC_t mabVlanPortAddProcess(uint32 intIfNum,uint32 vlanId); + +/* USE C Declarations */ +#ifdef __cplusplus +} +#endif + +#endif /* INCLUDE_MAB_VLAN_H */ From 3a167ad01ac93876ae31f6c86fa72c6a6b076064 Mon Sep 17 00:00:00 2001 From: Vijaya Kumar Abbaraju Date: Sat, 26 Oct 2024 00:37:55 +0530 Subject: [PATCH 15/23] PAC changs to receive config updates (#18620) --- src/sonic-pac/paccfg/Makefile.am | 15 ++ src/sonic-pac/paccfg/pac_authmgrcfg.cpp | 199 +++++++++++++++++++ src/sonic-pac/paccfg/pac_authmgrcfg.h | 89 +++++++++ src/sonic-pac/paccfg/pac_cfg_authmgr.cpp | 235 +++++++++++++++++++++++ src/sonic-pac/paccfg/pac_cfg_authmgr.h | 57 ++++++ src/sonic-pac/paccfg/pac_cfg_vlan.cpp | 158 +++++++++++++++ src/sonic-pac/paccfg/pac_cfg_vlan.h | 82 ++++++++ src/sonic-pac/paccfg/pac_vlancfg.cpp | 163 ++++++++++++++++ src/sonic-pac/paccfg/pac_vlancfg.h | 88 +++++++++ 9 files changed, 1086 insertions(+) create mode 100644 src/sonic-pac/paccfg/Makefile.am create mode 100644 src/sonic-pac/paccfg/pac_authmgrcfg.cpp create mode 100644 src/sonic-pac/paccfg/pac_authmgrcfg.h create mode 100644 src/sonic-pac/paccfg/pac_cfg_authmgr.cpp create mode 100644 src/sonic-pac/paccfg/pac_cfg_authmgr.h create mode 100644 src/sonic-pac/paccfg/pac_cfg_vlan.cpp create mode 100644 src/sonic-pac/paccfg/pac_cfg_vlan.h create mode 100644 src/sonic-pac/paccfg/pac_vlancfg.cpp create mode 100644 src/sonic-pac/paccfg/pac_vlancfg.h diff --git a/src/sonic-pac/paccfg/Makefile.am b/src/sonic-pac/paccfg/Makefile.am new file mode 100644 index 000000000000..c95d641067f0 --- /dev/null +++ b/src/sonic-pac/paccfg/Makefile.am @@ -0,0 +1,15 @@ +INCLUDES = -I $(top_srcdir)/fpinfra/inc -I $(top_srcdir)/authmgr/common -I $(top_srcdir)/authmgr/mapping/include -I $(top_srcdir)/authmgr/protocol/include + +lib_LTLIBRARIES = libpaccfg.la + +if DEBUG +DBGFLAGS = -ggdb -DDEBUG +else +DBGFLAGS = -g -DNDEBUG +endif + +AM_CPPFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(SONIC_COMMON_CFLAGS) + +libpaccfg_la_SOURCES = $(top_srcdir)/paccfg/pac_cfg_authmgr.cpp $(top_srcdir)/paccfg/pac_authmgrcfg.cpp $(top_srcdir)/paccfg/pac_cfg_vlan.cpp $(top_srcdir)/paccfg/pac_vlancfg.cpp + +libpaccfg_la_LIBADD = -lswsscommon -lnl-3 -lnl-route-3 -lhiredis $(SONIC_COMMON_LDFLAGS) diff --git a/src/sonic-pac/paccfg/pac_authmgrcfg.cpp b/src/sonic-pac/paccfg/pac_authmgrcfg.cpp new file mode 100644 index 000000000000..d5f0322cebbd --- /dev/null +++ b/src/sonic-pac/paccfg/pac_authmgrcfg.cpp @@ -0,0 +1,199 @@ +/* + * Copyright 2019 Broadcom Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include +#include +#include "pac_authmgrcfg.h" + +using namespace std; +using namespace swss; + +// PAC SONIC config engine +PacCfg::PacCfg(DBConnector *db, DBConnector *cfgDb, DBConnector *stateDb) : + m_cfgFdbTable(cfgDb, CFG_FDB_TABLE_NAME), + m_stateOperFdbTable(stateDb, STATE_OPER_FDB_TABLE_NAME), + m_stateOperPortTable(stateDb, STATE_OPER_PORT_TABLE_NAME) +{ + Logger::linkToDbNative("paccfg"); + SWSS_LOG_NOTICE("PAC: config object"); + + /* FDB flush notification producer */ + m_flushFdb = std::make_shared(db, "FLUSHFDBREQUEST"); +} + +PacCfg::~PacCfg() +{ + +} + +// Set learning mode for a port +bool PacCfg::intfLearningSet(string port, string learning) +{ + string key(port); + vector fvVector; + + // Configure port learning mode for FDB manager + fvVector.emplace_back("learn_mode", learning); + m_stateOperPortTable.set(key, fvVector); + + return true; +} + +// Get learning mode of a port +bool PacCfg::intfLearningGet(string port, string *learning) +{ + return true; +} + +// Add a static MAC address to FDB +bool PacCfg::intfStaticMacAdd(string port, MacAddress mac, int vlan) +{ + string key = VLAN_PREFIX + to_string(vlan); + key += STATE_DB_SEPARATOR; + key += mac.to_string(); + + vector fvVector; + + fvVector.push_back(FieldValueTuple("port", port)); + fvVector.push_back(FieldValueTuple("type", "static")); + m_stateOperFdbTable.set(key, fvVector); + + return true; +} + +// Remove an added static MAC address. +bool PacCfg::intfStaticMacRemove(string port, MacAddress mac, int vlan) +{ + string key = VLAN_PREFIX + to_string(vlan); + key += STATE_DB_SEPARATOR; + key += mac.to_string(); + + m_stateOperFdbTable.del(key); + + return true; +} + +// for now, blindly delete all entries. +// Ideally we need to delete only the entries owned by PAC. +void PacCfg::intfStaticMacCleanup(void) +{ + vector keys; + m_stateOperFdbTable.getKeys(keys); + for (const auto key : keys) + { + m_stateOperFdbTable.del(key); + } +} + +// Acquire/Release port. +bool PacCfg::intfAcquireSet(string port, bool acquire) +{ + vector fvVector; + + // Configure port acquire config for port. + if (acquire == true) + { + fvVector.emplace_back("acquired", "true"); + } + else + { + fvVector.emplace_back("acquired", "false"); + } + m_stateOperPortTable.set(port, fvVector); + + return true; +} + +// Block a client +bool PacCfg::intfClientBlock(string port, MacAddress mac, int vlan) +{ + // Add a static MAC entry with discard bits set. + string key = VLAN_PREFIX + to_string(vlan); + key += STATE_DB_SEPARATOR; + key += mac.to_string(); + + vector fvVector; + fvVector.push_back(FieldValueTuple("discard", "true")); + fvVector.push_back(FieldValueTuple("port", port)); + fvVector.push_back(FieldValueTuple("type", "static")); + + m_stateOperFdbTable.set(key, fvVector); + + return true; +} + +bool PacCfg::intfFdbFlush(string port) +{ + vector values; + + SWSS_LOG_DEBUG("send fdb flush by port %s notification ", port.c_str()); + + // Send FDB flush notification. + m_flushFdb->send("PORT", port, values); + + return true; +} + +bool PacCfg::intfMacVlanTranslationAdd(string port, MacAddress mac, int vlan) +{ + // Add MAC-VLAN translation for given MAC-VLAN pair. + return true; +} + +bool PacCfg::intfMacVlanTranslationRemove(string port, MacAddress mac, int vlan) +{ + // Remove MAC-VLAN translation for given MAC-VLAN pair. + return true; +} + +bool PacCfg::sendFdbNotification(string op, string port) +{ + vector keys; + vector entry; + const char delimiter = '|'; + + /* Retrieve static MAC entries configure on port and + * send a notification to add/remove those entries on port. + */ + m_cfgFdbTable.getKeys(keys); + + for (auto id : keys) + { + m_cfgFdbTable.get(id, entry); + for (auto i : entry) + { + if (fvField(i) == "port") + { + if (fvValue(i) == port) + { + vector values; + + /* Get MAC and VLAN from key */ + vector tokens = tokenize(id, delimiter, 1); + + /* tokens[0] is VLAN (Vlan20) and tokens[1] is mac (00:01:02:03:04:05). */ + values.push_back(FieldValueTuple("mac", tokens[1])); + values.push_back(FieldValueTuple("Vlan", tokens[0])); + m_fdbCfgNotificationProducer->send(op, port, values); + } + } + } + } + + return true; +} diff --git a/src/sonic-pac/paccfg/pac_authmgrcfg.h b/src/sonic-pac/paccfg/pac_authmgrcfg.h new file mode 100644 index 000000000000..0d58a4a5e78a --- /dev/null +++ b/src/sonic-pac/paccfg/pac_authmgrcfg.h @@ -0,0 +1,89 @@ +/* + * Copyright 2019 Broadcom Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _PAC_AUTHMGR_CFG_H +#define _PAC_AUTHMGR_CFG_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +#define STATE_DB_SEPARATOR "|" +#define CONFIG_DB_SEPARATOR "|" + +namespace swss { + + class PacCfg { + public: + PacCfg(DBConnector *appDb, DBConnector *cfgDb, DBConnector *stateDb); + ~PacCfg(); + + /* Update learning mode of a port. */ + bool intfLearningSet(std::string port, std::string learning); + + /* Get learning mode of a port. */ + bool intfLearningGet(std::string port, std::string *learning); + + /* Acquire/Release port. */ + bool intfAcquireSet(std::string port, bool acquire); + + /* Block a client's traffic. */ + bool intfClientBlock(std::string port, MacAddress mac, int vlan); + + /* Add a static MAC entry. */ + bool intfStaticMacAdd(std::string port, MacAddress mac, int vlan); + + /* Add a static MAC entry. */ + bool intfStaticMacRemove(std::string port, MacAddress mac, int vlan); + + /* Clean up all static MAC entries. */ + void intfStaticMacCleanup(void); + + /* Flush FDB entries on a port. */ + bool intfFdbFlush(std::string port); + + /* Add MAC-VLAN translation config. */ + bool intfMacVlanTranslationAdd(std::string port, MacAddress mac, int vlan); + + /* Remove MAC-VLAN translation config. */ + bool intfMacVlanTranslationRemove(std::string port, MacAddress mac, int vlan); + + /* Send notification to FDB mgr. */ + bool sendFdbNotification(std::string op, std::string port); + + private: + /* Tables for writing config */ + Table m_cfgFdbTable; + Table m_stateOperFdbTable; + Table m_stateOperPortTable; + + std::shared_ptr m_flushFdb; + std::shared_ptr m_fdbCfgNotificationProducer; + + }; +} + +#endif /* _PAC_AUTHMGR_CFG_H */ diff --git a/src/sonic-pac/paccfg/pac_cfg_authmgr.cpp b/src/sonic-pac/paccfg/pac_cfg_authmgr.cpp new file mode 100644 index 000000000000..9e3a17993672 --- /dev/null +++ b/src/sonic-pac/paccfg/pac_cfg_authmgr.cpp @@ -0,0 +1,235 @@ +/* + * Copyright 2019 Broadcom. The term "Broadcom" refers to Broadcom Inc. and/or + * its subsidiaries. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "pac_cfg_authmgr.h" +#include "pac_authmgrcfg.h" +#include "datatypes.h" +#include "auth_mgr_exports.h" +#include "auth_mgr_mac_db.h" + +using namespace std; +using namespace swss; + +DBConnector db("APPL_DB", 0); +DBConnector cfgDb("CONFIG_DB", 0); +DBConnector stateDb("STATE_DB", 0); + +PacCfg cfg(&db, &cfgDb, &stateDb); + +extern "C" { + + RC_t pacCfgIntfLearningModeSet(char *interface, AUTHMGR_PORT_LEARNING_t learning) + { + string port(interface); + string learning_mode; + bool status = false; + RC_t rc = FAILURE; + + if ( AUTHMGR_PORT_LEARNING_DISABLE == learning) + { + /* Drop all unknown source MAC packets. */ + learning_mode = "drop"; + + } + else if ( AUTHMGR_PORT_LEARNING_CPU == learning) + { + /* Trap all unknown source MAC packets to CPU. */ + learning_mode = "cpu_trap"; + } + else if ( AUTHMGR_PORT_LEARNING_ENABLE == learning) + { + /* Enable learning on port. */ + learning_mode = "hardware"; + } + + /* Configure port learning mode */ + status = cfg.intfLearningSet(port, learning_mode); + if (status != false) + { + /* Flush FDB entries on port. */ + status = cfg.intfFdbFlush(port); + } + + if (status == true) + { + rc = SUCCESS; + } + + return rc; + } + + RC_t pacCfgIntfLearningModeGet(char *interface, AUTHMGR_PORT_LEARNING_t *learning) + { + string port(interface); + string learning_mode; + bool status = false; + RC_t rc = FAILURE; + + status = cfg.intfLearningGet(port, &learning_mode); + + if (status != false) + { + if (learning_mode == "enable") + { + *learning = AUTHMGR_PORT_LEARNING_DISABLE; + } + else + { + *learning = AUTHMGR_PORT_LEARNING_ENABLE; + } + } + return rc; + } + + RC_t pacCfgIntfAcquireSet(char *interface, bool acquire) + { + string port(interface); + RC_t rc = SUCCESS; + + /* Configure port learning mode to CPU trap */ + if (cfg.intfAcquireSet(port, acquire) != true) + { + rc = FAILURE; + } + + return rc; + } + + bool pacCfgIntfViolationPolicySet(char *interface, bool enable) + { + string port(interface); + string learning_mode("cpu_trap"); + + /* Violation policy consists of : + * 1) Policy to trap unknown source MAC packets to CPU. + * 2) Policy to trap static MAC move packets to CPU. + * SONiC implements this via: + * 1) Set learning mode of port to CPU trap. + * 2) Use a CoPP system trap for trapping static MAC move packets. + */ + + /* Configure port learning mode to CPU trap */ + return cfg.intfLearningSet(port, learning_mode); + } + + bool pacCfgIntfClientAdd(char *interface, unsigned char *macaddr, int vlan) + { + string port(interface); + bool status = false; + MacAddress mac(macaddr); + + if (vlan != 0) + { + /* Client authorized on only 1 VLAN. + * Delete static MAC entries added on any other VLAN for this MAC. + */ + + /* Add specified MAC-VLAN pair as static MAC entry. */ + status = cfg.intfStaticMacAdd(port, mac, vlan); + + /* Client timeout logic. */ + + /* Configure MAC-VLAN translation for client on port. */ + status = cfg.intfMacVlanTranslationAdd(port, mac, vlan); + } + else + { + /* Client authorized on all vlans. */ + + /* Indicate to FDB mgr that this MAC needs to be added + * on all VLANs that this port is a member of. + */ + + /* Client timeout logic. */ + } + + return status; + } + + bool pacCfgIntfClientRemove(char *interface, unsigned char *macaddr, int vlan) + { + bool status = false; + string port(interface); + MacAddress mac(macaddr); + + if (vlan != 0) + { + /* MAC authorized on 1 VLAN, remove static FDB entry. */ + status = cfg.intfStaticMacRemove(port, mac, vlan); + + /* Remove MAC-VLAN translation configuration for the client. */ + if (status != true) + { + status = cfg.intfMacVlanTranslationRemove(port, mac, vlan); + } + } + else + { + /* MAC authorized on all VLANs. Remove all configured static MAC-VLAN entries. */ + } + + return status; + } + + void pacCfgIntfClientCleanup(void) + { + return cfg.intfStaticMacCleanup(); + } + + bool pacCfgIntfClientBlock(char *interface, unsigned char *macaddr, int vlan) + { + string port(interface); + MacAddress mac(macaddr); + + /* Add the static MAC-VLAN pair with source and destination discard bits set. */ + return cfg.intfClientBlock(port, mac, vlan); + } + + bool pacCfgIntfClientUnblock(char *interface, unsigned char *macaddr, int vlan) + { + string port(interface); + MacAddress mac(macaddr); + + /* Delete the added static MAC-VLAN pair. */ + return cfg.intfStaticMacRemove(port, mac, vlan); + } + + RC_t pacCfgFdbSendCfgNotification(authMgrFdbCfgType_t type, char *interface) + { + RC_t status = SUCCESS; + string op = "SET"; + vector keys; + string port(interface); + string key; + + if (type == AUTHMGR_FDB_CFG_REMOVE) + { + op = "DEL"; + } + + /* Send a notification to get all MAC entries from + * CONFIG_DB and configure on port (set/del). + */ + if (cfg.sendFdbNotification(op, port) != true) + { + status = FAILURE; + } + + return status; + } +} + diff --git a/src/sonic-pac/paccfg/pac_cfg_authmgr.h b/src/sonic-pac/paccfg/pac_cfg_authmgr.h new file mode 100644 index 000000000000..82c7eb9a19ed --- /dev/null +++ b/src/sonic-pac/paccfg/pac_cfg_authmgr.h @@ -0,0 +1,57 @@ +/* + * Copyright 2019 Broadcom. The term "Broadcom" refers to Broadcom Inc. and/or + * its subsidiaries. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef _PAC_CFG_AUTHMGR_H +#define _PAC_CFG_AUTHMGR_H + +#include "pac_cfg.h" +#include "pacinfra_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Set port learning config */ +RC_t pacCfgIntfLearningModeSet(char *interface, AUTHMGR_PORT_LEARNING_t learning); + +/* Get port learning config */ +RC_t pacCfgIntfLearningModeGet(char *interface, AUTHMGR_PORT_LEARNING_t *learning); + +/* Setup port learning config */ +bool pacCfgIntfViolationPolicySet(char *interface, bool enable); + +/* Add dot1x client */ +bool pacCfgIntfClientAdd(char *interface, unisgned char *m_mac, int vlan); + +/* Delete dot1x client */ +bool pacCfgIntfClientRemove(char *interface, unsigned char *m_mac, int vlan); + +/* Block a client's traffic while client is getting authorized */ +bool pacCfgIntfClientBlock(char *interface, unsigned char *m_mac, int vlan); + +/* Unblock a client's traffic */ +bool pacCfgIntfClientUnBlock(char *interface, unsigned char *m_mac, int vlan); + +/* Send a notification to remove/add static MAC entries on a port. */ +RC_t pacCfgFdbSendCfgNotification(authMgrFdbCfgType_t type, char *interface); + +/* USE C Declarations */ +#ifdef __cplusplus +} +#endif + +#endif /* _PAC_CFG_AUTHMGR_H */ diff --git a/src/sonic-pac/paccfg/pac_cfg_vlan.cpp b/src/sonic-pac/paccfg/pac_cfg_vlan.cpp new file mode 100644 index 000000000000..fc0f9c4f95b9 --- /dev/null +++ b/src/sonic-pac/paccfg/pac_cfg_vlan.cpp @@ -0,0 +1,158 @@ +/* + * Copyright 2019 Broadcom. The term "Broadcom" refers to Broadcom Inc. and/or + * its subsidiaries. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "pac_cfg_vlan.h" +#include "pac_vlancfg.h" +#include "datatypes.h" +#include "auth_mgr_exports.h" +#include "auth_mgr_vlan_db.h" +#include "exec.h" + +using namespace std; +using namespace swss; + +extern DBConnector db; +extern DBConnector cfgDb; +extern DBConnector stateDb; +DBConnector asicDb("ASIC_DB", 0); +DBConnector countersDb("COUNTERS_DB", 0); + +PacCfgVlan vcfg(&db, &cfgDb, &stateDb, &asicDb, &countersDb); + +extern "C" { + + RC_t pacCfgPortPVIDSet(char *interface, int pvid) + { + string port(interface); + RC_t rc = SUCCESS; + + /* Set port PVID */ + if (vcfg.portPVIDset(port, pvid) != true) + { + rc = FAILURE; + } + + return rc; + } + + RC_t pacCfgPortPVIDGet(char *interface, int *pvid) + { + string port(interface); + RC_t rc = FAILURE; + + if (pvid == NULL) + { + return FAILURE; + } + + if (vcfg.portPVIDGet(port, pvid) != true) + { + rc = FAILURE; + } + + return rc; + } + + RC_t pacCfgVlanMemberAdd(int vlan, char *interface, dot1qTaggingMode_t mode) + { + string port(interface); + RC_t rc = SUCCESS; + string tagging_mode = "untagged"; + + if (mode == DOT1Q_MEMBER_TAGGED) + { + tagging_mode = "tagged"; + } + + /* Set VLAN membership */ + if (vcfg.vlanMemberAdd(vlan, port, tagging_mode) != true) + { + rc = FAILURE; + } + + return rc; + } + + RC_t pacCfgVlanMemberRemove(int vlan, char *interface) + { + string port(interface); + RC_t rc = SUCCESS; + + /* Set VLAN membership */ + if (vcfg.vlanMemberRemove(port, vlan) != true) + { + rc = FAILURE; + } + + return rc; + } + + RC_t pacCfgVlanMemberClean(int vlan) + { + RC_t rc = SUCCESS; + + if (vcfg.vlanMemberClean(vlan) != true) + { + rc = FAILURE; + } + + return rc; + } + + RC_t pacCfgVlanSendCfgNotification(authMgrVlanPortCfgType_t type, + char *interface, authMgrVlanPortData_t *cfg) + { + string op = "SET"; + vector keys; + string key, mode; + int i = 0; + string port(interface); + + if (cfg == NULLPTR) + { + return FAILURE; + } + + if (type == AUTHMGR_INTF_CFG_REMOVE) + { + op = "DEL"; + } + + /* Iterate over config and create keys to be handled */ + for (i = 1; i < DOT1Q_MAX_VLAN_ID; i++) + { + if ( VLAN_ISMASKBITSET(cfg->vlanMask, i)) + { + mode = "untagged"; + if ( VLAN_ISMASKBITSET(cfg->tagging, i)) + { + mode = "tagged"; + } + key = "Vlan" + to_string(i) + STATE_DB_SEPARATOR + mode; + keys.push_back(key); + } + } + + if (vcfg.sendVlanNotification(op, port, keys) != true) + { + return FAILURE; + } + + return SUCCESS; + } +} + diff --git a/src/sonic-pac/paccfg/pac_cfg_vlan.h b/src/sonic-pac/paccfg/pac_cfg_vlan.h new file mode 100644 index 000000000000..49880866727e --- /dev/null +++ b/src/sonic-pac/paccfg/pac_cfg_vlan.h @@ -0,0 +1,82 @@ +/* + * Copyright 2019 Broadcom. The term "Broadcom" refers to Broadcom Inc. and/or + * its subsidiaries. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef _PAC_CFG_VLAN_H +#define _PAC_CFG_VLAN_H + +#include "pac_vlancfg.h" +#include "pacinfra_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Set port PVID */ +RC_t pacCfgPortPVIDSet(char *interface, int pvid); + +/* Set port PVID */ +RC_t pacCfgPortPVIDGet(char *interface, int *pvid); + +/* Get port PVID */ +RC_t pacCfgPortPVIDGet(char *interface, int *pvid); + +/* Set port VLAN membership */ +RC_t pacCfgVlanMemberAdd(int vlan, char *interface, dot1qTaggingMode_t mode); + +/* Remove port VLAN membership */ +RC_t pacCfgVlanMemberRemove(int vlan, char *interface); + +/* Remove all port VLAN membership */ +RC_t pacCfgVlanMemberClean(int vlan); + +/* Add a dynamic VLAN */ +RC_t pacCfgVlanAdd(int vlan); + +/* Remove a dynamic VLAN */ +RC_t pacCfgVlanRemove(int vlan); + +/* Remove all dynamic VLAN */ +void pacCfgVlanCleanup(void); + +/* Add a reserved dynamic VLAN */ +RC_t pacCfgReservedVlanAdd(int vlan); + +/* Remove a reserved dynamic VLAN */ +RC_t pacCfgReservedVlanRemove(int vlan); + +/* Send a VLAN config notification to VLAN mgr */ +RC_t pacCfgVlanSendCfgNotification(authMgrVlanPortCfgType_t type, + char *interface, authMgrVlanPortData_t *cfg); + +/* Request for a Reserved VLAN */ +void pacCfgResvVlanAllocate(void); + +/* Release a Reserved VLAN */ +void pacCfgResvVlanRelease(int resvVlan); + +/* Check if VLAN is in reserved VLAN range. */ +bool pacCfgIsReserveVlan(int resvVlan); + +/* Check if VLAN is an L3 interface. */ +bool pacCfgIsL3VlanInterface(int vlan); + +/* USE C Declarations */ +#ifdef __cplusplus +} +#endif + +#endif /* _PAC_CFG_VLAN_H */ diff --git a/src/sonic-pac/paccfg/pac_vlancfg.cpp b/src/sonic-pac/paccfg/pac_vlancfg.cpp new file mode 100644 index 000000000000..d6385bffedbd --- /dev/null +++ b/src/sonic-pac/paccfg/pac_vlancfg.cpp @@ -0,0 +1,163 @@ +/* + * Copyright 2019 Broadcom Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include +#include "pac_vlancfg.h" + +using namespace std; +using namespace swss; + +// PAC SONIC config engine +PacCfgVlan::PacCfgVlan(DBConnector *db, DBConnector *cfgDb, DBConnector *stateDb, + DBConnector *asicDb, DBConnector *countersDb) : + m_appPortTable(db, APP_PORT_TABLE_NAME), + m_stateOperPortTable(stateDb, STATE_OPER_PORT_TABLE_NAME), + m_cfgVlanTable(cfgDb, CFG_VLAN_TABLE_NAME), + m_cfgVlanMemberTable(cfgDb, CFG_VLAN_MEMBER_TABLE_NAME), + m_stateOperFdbTable(stateDb, STATE_OPER_FDB_TABLE_NAME), + m_stateOperVlanMemberTable(stateDb, STATE_OPER_VLAN_MEMBER_TABLE_NAME), + m_vlanStateTable(stateDb, STATE_VLAN_TABLE_NAME), + m_vlanMemberStateTable(stateDb, STATE_VLAN_MEMBER_TABLE_NAME), + m_countersPortNameMapTable(countersDb, COUNTERS_PORT_NAME_MAP), + m_appPacTable(db, APP_PAC_PORT_TABLE_NAME) +{ +// Logger::linkToDbNative("paccfgvlan"); + SWSS_LOG_NOTICE("PAC: VLAN config object"); + + m_cfgDb = cfgDb; + m_asicDb = asicDb; + + /* Setup notification producer for VLAN notifications. */ + m_vlanCfgNotificationProducer = std::make_shared(stateDb, "VLANCFG"); +} + +PacCfgVlan::~PacCfgVlan() +{ + +} + +bool PacCfgVlan::vlanMemberAdd(int vlan, string port, string tagging_mode) +{ + string key = VLAN_PREFIX + to_string(vlan) + STATE_DB_SEPARATOR + port; + vector fvs; + + fvs.emplace_back("tagging_mode", tagging_mode); + m_stateOperVlanMemberTable.set(key, fvs); + + return true; +} + +bool PacCfgVlan::vlanMemberRemove(string port, int vlan) +{ + string key = VLAN_PREFIX + to_string(vlan) + STATE_DB_SEPARATOR + port; + + // Remove port from VLAN. + m_stateOperVlanMemberTable.del(key); + + return true; +} + +bool PacCfgVlan::vlanMemberClean(int vlan) +{ + vector keys; + vector fvVector; + fvVector.emplace_back("learn_mode", "drop"); + m_stateOperVlanMemberTable.getKeys(keys); + for (const auto key : keys) + { + unsigned pos = key.find(STATE_DB_SEPARATOR); + string vlanStr = key.substr (0, pos); + string intfStr = key.substr (pos+1); + if((VLAN_PREFIX + to_string(vlan)) == vlanStr) + { + // Remove port from VLAN after setting PVID back to zero. + m_stateOperVlanMemberTable.del(key); + m_stateOperPortTable.hdel(intfStr ,"pvid"); + m_stateOperPortTable.hdel(intfStr ,"acquired"); + m_stateOperPortTable.set(intfStr, fvVector); + } + } + + return true; +} + +bool PacCfgVlan::portPVIDset(string port, int pvid) +{ + string key(port); + vector fvVector; + + fvVector.emplace_back("pvid", to_string(pvid)); + + m_stateOperPortTable.set(key, fvVector); + + return true; +} + +bool PacCfgVlan::portPVIDGet(string port, int *pvid) +{ + string portOid; + std::unordered_map::iterator it; + + if (pvid == NULL) + { + return false; + } + + *pvid = 0; + + /* Get the port OID for COUNTERS_DB. */ + if (m_countersPortNameMapTable.hget("", port, portOid) != true) + { + return false; + } + + /* Port PVID from ASIC_DB */ + auto fieldValues = m_asicDb->hgetall("ASIC_STATE:SAI_OBJECT_TYPE_PORT:"+portOid); + for (it = fieldValues.begin(); it != fieldValues.end(); it++) + { + if ((it->first) == "SAI_PORT_ATTR_PORT_VLAN_ID") + { + try + { + *pvid = stoi(it->second); + } + catch (...) + { + SWSS_LOG_WARN("Invalid value:%s for SAI_PORT_ATTR_PORT_VLAN_ID", (it->second).c_str()); + } + } + } + + return true; +} + +bool PacCfgVlan::sendVlanNotification(string op, string port, vector keys) +{ + vector values; + + for (vector::iterator it = keys.begin(); + it != keys.end(); ++it) + { + FieldValueTuple tuple("Vlan|tagging_mode", *it); + values.push_back(tuple); + } + + m_vlanCfgNotificationProducer->send(op, port, values); + return true; +} + diff --git a/src/sonic-pac/paccfg/pac_vlancfg.h b/src/sonic-pac/paccfg/pac_vlancfg.h new file mode 100644 index 000000000000..e5fbaec83ee4 --- /dev/null +++ b/src/sonic-pac/paccfg/pac_vlancfg.h @@ -0,0 +1,88 @@ +/* + * Copyright 2019 Broadcom Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _PAC_VLAN_CFG_H +#define _PAC_VLAN_CFG_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +#define STATE_DB_SEPARATOR "|" +#define CONFIG_DB_SEPARATOR "|" +#define PAC_INTERNAL_VLAN 4095 + +namespace swss { + + class PacCfgVlan { + public: + PacCfgVlan(DBConnector *appDb, DBConnector *cfgDb, DBConnector *stateDb, + DBConnector *asicDb, DBConnector *countersDb); + ~PacCfgVlan(); + + /* Add a port to a VLAN. */ + bool vlanMemberAdd(int vlan, std::string port, std::string tagging_mode); + + /* Remove port from VLAN. */ + bool vlanMemberRemove(std::string port, int vlan); + + bool vlanMemberClean(int vlan); + + /* Set port PVID. */ + bool portPVIDset(std::string port, int pvid); + + /* Get port PVID. */ + bool portPVIDGet(std::string port, int *pvid); + + /* Check if port exists */ + bool portCheckValid(std::string port); + + /* Send notification to VLAN mgr for VLAN config. */ + bool sendVlanNotification(std::string op, std::string port, vector keys); + + private: + /* Tables for writing config */ + Table m_appPortTable; + Table m_stateOperPortTable; + Table m_cfgVlanTable; + Table m_cfgVlanMemberTable; + Table m_stateOperFdbTable; + Table m_stateOperVlanMemberTable; + Table m_vlanStateTable; + Table m_vlanMemberStateTable; + Table m_countersPortNameMapTable; + + ProducerStateTable m_appPacTable; + std::shared_ptr m_vlanCfgNotificationProducer; + std::shared_ptr m_resvVlanNotificationProducer; + + DBConnector *m_cfgDb; + DBConnector *m_asicDb; + + }; +} + +#endif /* _PAC_VLAN_CFG_ */ From dfc9b30539e328cccafb942dd32b287303b07658 Mon Sep 17 00:00:00 2001 From: mssonicbld <79238446+mssonicbld@users.noreply.github.com> Date: Sat, 26 Oct 2024 19:01:07 +0800 Subject: [PATCH 16/23] [submodule] Update submodule sonic-platform-common to the latest HEAD automatically (#20624) #### Why I did it src/sonic-platform-common ``` * 7268fad - (HEAD -> master, origin/master, origin/HEAD) [SmartSwitch] Add a new API for the DPU chassis to query dataplane and midplane states (#509) (7 hours ago) [Oleksandr Ivantsiv] ``` #### How I did it #### How to verify it #### Description for the changelog --- 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 912ceb34c8a3..7268fad2c220 160000 --- a/src/sonic-platform-common +++ b/src/sonic-platform-common @@ -1 +1 @@ -Subproject commit 912ceb34c8a352b235ad77ea07778c4779a5bd4a +Subproject commit 7268fad2c220bdcca2f22bfb080f15f078d5fa8f From e958af1a2e28527e4c442cb75bc881f957cea3b8 Mon Sep 17 00:00:00 2001 From: mssonicbld <79238446+mssonicbld@users.noreply.github.com> Date: Sun, 27 Oct 2024 19:27:12 +0800 Subject: [PATCH 17/23] [submodule] Update submodule sonic-platform-daemons to the latest HEAD automatically (#20609) #### Why I did it src/sonic-platform-daemons ``` * f169f86 - (HEAD -> master, origin/master, origin/HEAD) Move DomInfoUpdateTask class to a separate file (#552) (2 days ago) [mihirpat1] ``` #### How I did it #### How to verify it #### Description for the changelog --- 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 5d827af7a92e..f169f86a2cd7 160000 --- a/src/sonic-platform-daemons +++ b/src/sonic-platform-daemons @@ -1 +1 @@ -Subproject commit 5d827af7a92ec4bc0960cc708f7a71582122eeb4 +Subproject commit f169f86a2cd7f4f4ebf69f7b9d972824790d0080 From 40d9f7a94c0db6f9322a63e8bca83f40b22cd9b0 Mon Sep 17 00:00:00 2001 From: Tomer Shalvi <116184476+tshalvi@users.noreply.github.com> Date: Sun, 27 Oct 2024 15:30:37 +0200 Subject: [PATCH 18/23] Module detection flow update to tag copper passive cables as software control (#19476) - Why I did it On Mellanox platforms, currently only CMIS active ports can be controlled by the SW, and all copper modules are controlled by FW. We want to let Sonic control passive copper modules as well, for CMIS and SFF (sff8636 and sff8436). - How I did it I updated the module detection flow to tag CMIS and SFF passive modules as SW control. - How to verify it Manual tests. --- platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py index ddaa60d2860e..e2c6d63dc7a3 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py @@ -1053,7 +1053,10 @@ def is_supported_for_software_control(self, xcvr_api): Returns: bool: True if the api object supports software control """ - return self.is_cmis_api(xcvr_api) and not xcvr_api.is_flat_memory() + if xcvr_api.is_flat_memory(): + return self.is_cmis_api(xcvr_api) or self.is_sff_api(xcvr_api) + else: + return self.is_cmis_api(xcvr_api) def check_power_capability(self): """Check module max power with cage power limit From 47aa38c8ef31b42a7f5b8555c0ad410f52232b29 Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> Date: Sun, 27 Oct 2024 23:46:33 +0800 Subject: [PATCH 19/23] Enable runtime config log level (#19611) HLD link: sonic-net/SONiC#1522 - Why I did it SONiC provides two Python logger implementations: sonic_py_common.logger.Logger and sonic_py_common.syslogger.SysLogger. Both of them do not provide the ability to change log level at real time. Sometimes, in order to get more debug information, developer has to manually change the log level in code on a running switch and restart the Python daemon. This is not convenient. SONiC also provides a C/C++ logger implementation in sonic-platform-common.common.logger.cpp. This C/C++ logger implementation is also a wrapper of Linux standard syslog which is widely used by swss/syncd. It provides the ability to set log level on fly by starting a thread to listen to CONFIG DB LOGGER table change. SONiC infrastructure also provides the Python wrapper for sonic-platform-common.common.logger.cpp which is swsscommon.Logger. However, this logger implementation also has some drawbacks: swsscommon.Logger assumes redis DB is ready to connect. This is a valid assumption for swss/syncd. But it is not good for a Python logger implementation because some Python script may be called before redis server starting. swsscommon.Logger wraps Linux syslog which only support single log identifier for a daemon. So, swsscommon.Logger is not an option too. This PR is a Python logger enhancement which allows user setting log level at run time. - How I did it swsscommon.Logger depends on a thread to listen to CONFIG DB LOGGER table change. It refreshes log level for each logger instances once the thread detects a DB entry change. A thread is considered heavy in a python script, especially that there are many short and simple python scripts which also use logger. To keep python logger light weight, it uses a different design than swsscommon.Logger: A class level logger registry shall be added to SysLoggerclass Each logger instance shall register itself to logger register if enables runtime configuration Logger configuration shall be refreshed by CLI which send a SIGHUP signal to the daemon - How to verify it Manual test New unit test cases --- .../sonic_py_common/daemon_base.py | 4 +- .../sonic_py_common/syslogger.py | 80 ++++++++++++++++++- src/sonic-py-common/tests/test_syslogger.py | 57 +++++++++++++ 3 files changed, 135 insertions(+), 6 deletions(-) diff --git a/src/sonic-py-common/sonic_py_common/daemon_base.py b/src/sonic-py-common/sonic_py_common/daemon_base.py index 8bfd09cd881d..fd98a12b28e2 100644 --- a/src/sonic-py-common/sonic_py_common/daemon_base.py +++ b/src/sonic-py-common/sonic_py_common/daemon_base.py @@ -35,10 +35,10 @@ def db_connect(db_name, namespace=EMPTY_NAMESPACE): class DaemonBase(Logger): - def __init__(self, log_identifier, use_syslogger=True): + def __init__(self, log_identifier, use_syslogger=True, enable_runtime_log_config=False): super().__init__() if use_syslogger: - self.logger_instance = SysLogger(log_identifier) + self.logger_instance = SysLogger(log_identifier, enable_runtime_config=enable_runtime_log_config) else: self.logger_instance = Logger( log_identifier=log_identifier, diff --git a/src/sonic-py-common/sonic_py_common/syslogger.py b/src/sonic-py-common/sonic_py_common/syslogger.py index c45f0cde8425..3d5449642cc4 100644 --- a/src/sonic-py-common/sonic_py_common/syslogger.py +++ b/src/sonic-py-common/sonic_py_common/syslogger.py @@ -4,6 +4,11 @@ import socket import sys +CONFIG_DB = 'CONFIG_DB' +FIELD_LOG_LEVEL = 'LOGLEVEL' +FIELD_REQUIRE_REFRESH = 'require_manual_refresh' + + # customize python logging to support notice logger logging.NOTICE = logging.INFO + 1 logging.addLevelName(logging.NOTICE, "NOTICE") @@ -18,12 +23,11 @@ class SysLogger: DEFAULT_LOG_FACILITY = SysLogHandler.LOG_USER DEFAULT_LOG_LEVEL = logging.NOTICE - def __init__(self, log_identifier=None, log_facility=DEFAULT_LOG_FACILITY, log_level=DEFAULT_LOG_LEVEL): - if log_identifier is None: - log_identifier = os.path.basename(sys.argv[0]) + def __init__(self, log_identifier=None, log_facility=DEFAULT_LOG_FACILITY, log_level=DEFAULT_LOG_LEVEL, enable_runtime_config=False): + self.log_identifier = log_identifier if log_identifier else os.path.basename(sys.argv[0]) # Initialize SysLogger - self.logger = logging.getLogger(log_identifier) + self.logger = logging.getLogger(self.log_identifier) # Reset all existing handlers for handler in self.logger.handlers[:]: @@ -35,6 +39,74 @@ def __init__(self, log_identifier=None, log_facility=DEFAULT_LOG_FACILITY, log_l self.logger.addHandler(handler) self.set_min_log_priority(log_level) + + if enable_runtime_config: + self.update_log_level() + + def update_log_level(self): + """Refresh log level. + + Returns: + tuple: (refresh result, fail reason) + """ + from swsscommon import swsscommon + try: + config_db = swsscommon.SonicV2Connector(use_unix_socket_path=True) + config_db.connect(CONFIG_DB) + log_level_in_db = config_db.get(CONFIG_DB, f'{swsscommon.CFG_LOGGER_TABLE_NAME}|{self.log_identifier}', FIELD_LOG_LEVEL) + if log_level_in_db: + self.set_min_log_priority(self.log_priority_from_str(log_level_in_db)) + else: + data = { + FIELD_LOG_LEVEL: self.log_priority_to_str(self._min_log_level), + FIELD_REQUIRE_REFRESH: 'true' + } + config_db.hmset(CONFIG_DB, f'{swsscommon.CFG_LOGGER_TABLE_NAME}|{self.log_identifier}', data) + return True, '' + except Exception as e: + return False, f'Failed to refresh log configuration - {e}' + + def log_priority_to_str(self, priority): + """Convert log priority to string. + Args: + priority (int): log priority. + Returns: + str: log priority in string. + """ + if priority == logging.INFO: + return 'INFO' + elif priority == logging.NOTICE: + return 'NOTICE' + elif priority == logging.DEBUG: + return 'DEBUG' + elif priority == logging.WARNING: + return 'WARN' + elif priority == logging.ERROR: + return 'ERROR' + else: + self.log_error(f'Invalid log priority: {priority}') + return 'WARN' + + def log_priority_from_str(self, priority_in_str): + """Convert log priority from string. + Args: + priority_in_str (str): log priority in string. + Returns: + _type_: log priority. + """ + if priority_in_str == 'DEBUG': + return logging.DEBUG + elif priority_in_str == 'INFO': + return logging.INFO + elif priority_in_str == 'NOTICE': + return logging.NOTICE + elif priority_in_str == 'WARN': + return logging.WARNING + elif priority_in_str == 'ERROR': + return logging.ERROR + else: + self.log_error(f'Invalid log priority string: {priority_in_str}') + return logging.WARNING def set_min_log_priority(self, priority): """ diff --git a/src/sonic-py-common/tests/test_syslogger.py b/src/sonic-py-common/tests/test_syslogger.py index 359120163b3f..35e0fd058606 100644 --- a/src/sonic-py-common/tests/test_syslogger.py +++ b/src/sonic-py-common/tests/test_syslogger.py @@ -32,3 +32,60 @@ def test_notice_log(self, capsys): log.log_notice('this is a message') captured = capsys.readouterr() assert 'NOTICE' in captured.out + + def test_basic(self): + log = syslogger.SysLogger() + log.logger.log = mock.MagicMock() + log.log_error('error message') + log.log_warning('warning message') + log.log_notice('notice message') + log.log_info('info message') + log.log_debug('debug message') + log.log(logging.ERROR, 'error msg', also_print_to_console=True) + + def test_log_priority(self): + log = syslogger.SysLogger() + log.set_min_log_priority(logging.ERROR) + assert log.logger.level == logging.ERROR + + def test_log_priority_from_str(self): + log = syslogger.SysLogger() + assert log.log_priority_from_str('ERROR') == logging.ERROR + assert log.log_priority_from_str('INFO') == logging.INFO + assert log.log_priority_from_str('NOTICE') == logging.NOTICE + assert log.log_priority_from_str('WARN') == logging.WARN + assert log.log_priority_from_str('DEBUG') == logging.DEBUG + assert log.log_priority_from_str('invalid') == logging.WARN + + def test_log_priority_to_str(self): + log = syslogger.SysLogger() + assert log.log_priority_to_str(logging.NOTICE) == 'NOTICE' + assert log.log_priority_to_str(logging.INFO) == 'INFO' + assert log.log_priority_to_str(logging.DEBUG) == 'DEBUG' + assert log.log_priority_to_str(logging.WARN) == 'WARN' + assert log.log_priority_to_str(logging.ERROR) == 'ERROR' + assert log.log_priority_to_str(-1) == 'WARN' + + @mock.patch('swsscommon.swsscommon.SonicV2Connector') + def test_runtime_config(self, mock_connector): + mock_db = mock.MagicMock() + mock_db.get = mock.MagicMock(return_value='DEBUG') + mock_connector.return_value = mock_db + log = syslogger.SysLogger(log_identifier='log1', enable_runtime_config=True, log_level=logging.INFO) + assert log.logger.level == logging.DEBUG + + mock_db.get.return_value = 'ERROR' + ret, msg = log.update_log_level() + assert ret + assert not msg + + @mock.patch('swsscommon.swsscommon.SonicV2Connector') + def test_runtime_config_negative(self, mock_connector): + mock_db = mock.MagicMock() + mock_db.get = mock.MagicMock(side_effect=Exception('')) + mock_connector.return_value = mock_db + log = syslogger.SysLogger(log_identifier='log', enable_runtime_config=True) + + ret, msg = log.update_log_level() + assert not ret + assert msg From 186e9ac28957b6f6d3770d391a729b1ce48650c8 Mon Sep 17 00:00:00 2001 From: Oleksandr Ivantsiv Date: Sun, 27 Oct 2024 08:47:32 -0700 Subject: [PATCH 20/23] [Nvidia-bluefield] Update SAI to SAIBuild0.0.36.0, SDK/FW to v24.10-RC2/v32.42.1000, BFSoC to 4.9.0 (#20565) - Why I did it To include latest fixes and new functionality - How I did it SDK_VERSION 24.7-RC4 -> 24.10-RC2 FW_VERSION 32.41.1000 -> 32.42.1000 SAI_VERSION SAIBuild0.0.32.0 -> SAIBuild0.0.36.0 BFSOC_VERSION: 4.7.0 -> 4.9.0 - How to verify it Build an image and run tests from "sonic-mgmt". --- platform/nvidia-bluefield/recipes/bluefield-soc.mk | 4 ++-- platform/nvidia-bluefield/recipes/dpu-sai.mk | 2 +- platform/nvidia-bluefield/recipes/fw.mk | 2 +- platform/nvidia-bluefield/recipes/sdk.mk | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/platform/nvidia-bluefield/recipes/bluefield-soc.mk b/platform/nvidia-bluefield/recipes/bluefield-soc.mk index dc256b6b6c11..2b6a5c64fdc9 100644 --- a/platform/nvidia-bluefield/recipes/bluefield-soc.mk +++ b/platform/nvidia-bluefield/recipes/bluefield-soc.mk @@ -16,8 +16,8 @@ # # Bluefied Software Distribution Version -BFSOC_VERSION = 4.7.0 -BFSOC_REVISION = 13127 +BFSOC_VERSION = 4.9.0 +BFSOC_REVISION = 13347 BFB_IMG_TYPE = prod BFSOC_BUILD_DATE = diff --git a/platform/nvidia-bluefield/recipes/dpu-sai.mk b/platform/nvidia-bluefield/recipes/dpu-sai.mk index 706fd6d65c4e..533a22ea8ffe 100644 --- a/platform/nvidia-bluefield/recipes/dpu-sai.mk +++ b/platform/nvidia-bluefield/recipes/dpu-sai.mk @@ -15,7 +15,7 @@ # limitations under the License. # -DPU_SAI_VERSION = SAIBuild0.0.32.0 +DPU_SAI_VERSION = SAIBuild0.0.36.0 # Place here URL where SAI sources exist DPU_SAI_SOURCE_BASE_URL= diff --git a/platform/nvidia-bluefield/recipes/fw.mk b/platform/nvidia-bluefield/recipes/fw.mk index 344ed49b18b3..9d45d327fcfd 100644 --- a/platform/nvidia-bluefield/recipes/fw.mk +++ b/platform/nvidia-bluefield/recipes/fw.mk @@ -17,7 +17,7 @@ BF3_FW_BASE_URL = -BF3_FW_VERSION = 32.41.1000 +BF3_FW_VERSION = 32.42.1000 BF3_FW_FILE = fw-BlueField-3-rel-$(subst .,_,$(BF3_FW_VERSION)).mfa diff --git a/platform/nvidia-bluefield/recipes/sdk.mk b/platform/nvidia-bluefield/recipes/sdk.mk index fbe53fddde64..71e3a024d9f4 100644 --- a/platform/nvidia-bluefield/recipes/sdk.mk +++ b/platform/nvidia-bluefield/recipes/sdk.mk @@ -19,7 +19,7 @@ SDK_BASE_PATH = $(PLATFORM_PATH)/sdk-src/sonic-bluefield-packages/bin # Place here URL where SDK sources exist SDK_SOURCE_BASE_URL = -SDK_VERSION = 24.7-RC4 +SDK_VERSION = 24.10-RC2 SDK_COLLECTX_URL = https://linux.mellanox.com/public/repo/doca/1.5.2/debian12/aarch64/ From a5a9dacad7fadd7fdd064858f2a586424ad4f766 Mon Sep 17 00:00:00 2001 From: Chris <156943338+ccroy-arista@users.noreply.github.com> Date: Sun, 27 Oct 2024 20:57:11 -0700 Subject: [PATCH 21/23] sonic-buildimage: rename qsp 128x400g to o128s2, fix lane map typo (#20580) * sonic-buildimage: rename qsp 128x400g to o128s2 In keeping with normative convention, renaming the hwsku folders for qsp/qspr from 128x400G to O128S2. * sonic-buildimage: fix qsp-o128s2 port_config typo There is a typo in the lanes used for Ethernet356 within port_config.ini, where lanes 381 and 382 appear twice instead of being followed by the intended 383 and 384. This change fixes that typo. This exact typo is not present in the other hwskus under x86_64-arista_7060x6_64pe or x86_64-arista_7060x6_64de. --- .../BALANCED | 0 .../buffer_ports.j2 | 0 .../buffers.json.j2 | 0 .../buffers_defaults_t0.j2 | 0 .../buffers_defaults_t1.j2 | 0 .../hwsku.json | 0 .../pg_profile_lookup.ini | 0 .../port_config.ini | 2 +- .../qos.json.j2 | 0 .../sai.profile | 0 .../th5-a7060x6-64pe.config.bcm | 0 11 files changed, 1 insertion(+), 1 deletion(-) rename device/arista/x86_64-arista_7060x6_64pe/{Arista-7060X6-64PE-128x400G => Arista-7060X6-64PE-O128S2}/BALANCED (100%) rename device/arista/x86_64-arista_7060x6_64pe/{Arista-7060X6-64PE-128x400G => Arista-7060X6-64PE-O128S2}/buffer_ports.j2 (100%) rename device/arista/x86_64-arista_7060x6_64pe/{Arista-7060X6-64PE-128x400G => Arista-7060X6-64PE-O128S2}/buffers.json.j2 (100%) rename device/arista/x86_64-arista_7060x6_64pe/{Arista-7060X6-64PE-128x400G => Arista-7060X6-64PE-O128S2}/buffers_defaults_t0.j2 (100%) rename device/arista/x86_64-arista_7060x6_64pe/{Arista-7060X6-64PE-128x400G => Arista-7060X6-64PE-O128S2}/buffers_defaults_t1.j2 (100%) rename device/arista/x86_64-arista_7060x6_64pe/{Arista-7060X6-64PE-128x400G => Arista-7060X6-64PE-O128S2}/hwsku.json (100%) rename device/arista/x86_64-arista_7060x6_64pe/{Arista-7060X6-64PE-128x400G => Arista-7060X6-64PE-O128S2}/pg_profile_lookup.ini (100%) rename device/arista/x86_64-arista_7060x6_64pe/{Arista-7060X6-64PE-128x400G => Arista-7060X6-64PE-O128S2}/port_config.ini (99%) rename device/arista/x86_64-arista_7060x6_64pe/{Arista-7060X6-64PE-128x400G => Arista-7060X6-64PE-O128S2}/qos.json.j2 (100%) rename device/arista/x86_64-arista_7060x6_64pe/{Arista-7060X6-64PE-128x400G => Arista-7060X6-64PE-O128S2}/sai.profile (100%) rename device/arista/x86_64-arista_7060x6_64pe/{Arista-7060X6-64PE-128x400G => Arista-7060X6-64PE-O128S2}/th5-a7060x6-64pe.config.bcm (100%) diff --git a/device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-128x400G/BALANCED b/device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-O128S2/BALANCED similarity index 100% rename from device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-128x400G/BALANCED rename to device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-O128S2/BALANCED diff --git a/device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-128x400G/buffer_ports.j2 b/device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-O128S2/buffer_ports.j2 similarity index 100% rename from device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-128x400G/buffer_ports.j2 rename to device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-O128S2/buffer_ports.j2 diff --git a/device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-128x400G/buffers.json.j2 b/device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-O128S2/buffers.json.j2 similarity index 100% rename from device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-128x400G/buffers.json.j2 rename to device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-O128S2/buffers.json.j2 diff --git a/device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-128x400G/buffers_defaults_t0.j2 b/device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-O128S2/buffers_defaults_t0.j2 similarity index 100% rename from device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-128x400G/buffers_defaults_t0.j2 rename to device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-O128S2/buffers_defaults_t0.j2 diff --git a/device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-128x400G/buffers_defaults_t1.j2 b/device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-O128S2/buffers_defaults_t1.j2 similarity index 100% rename from device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-128x400G/buffers_defaults_t1.j2 rename to device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-O128S2/buffers_defaults_t1.j2 diff --git a/device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-128x400G/hwsku.json b/device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-O128S2/hwsku.json similarity index 100% rename from device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-128x400G/hwsku.json rename to device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-O128S2/hwsku.json diff --git a/device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-128x400G/pg_profile_lookup.ini b/device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-O128S2/pg_profile_lookup.ini similarity index 100% rename from device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-128x400G/pg_profile_lookup.ini rename to device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-O128S2/pg_profile_lookup.ini diff --git a/device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-128x400G/port_config.ini b/device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-O128S2/port_config.ini similarity index 99% rename from device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-128x400G/port_config.ini rename to device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-O128S2/port_config.ini index 4fee0c95baef..688ae29c1261 100644 --- a/device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-128x400G/port_config.ini +++ b/device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-O128S2/port_config.ini @@ -88,7 +88,7 @@ Ethernet340 325,326,327,328 Ethernet43/5 43 400000 rs Ethernet344 337,338,339,340 Ethernet44/1 44 400000 rs Ethernet348 341,342,343,344 Ethernet44/5 44 400000 rs Ethernet352 377,378,379,380 Ethernet45/1 45 400000 rs -Ethernet356 381,382,381,382 Ethernet45/5 45 400000 rs +Ethernet356 381,382,383,384 Ethernet45/5 45 400000 rs Ethernet360 361,362,363,364 Ethernet46/1 46 400000 rs Ethernet364 365,366,367,368 Ethernet46/5 46 400000 rs Ethernet368 353,354,355,356 Ethernet47/1 47 400000 rs diff --git a/device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-128x400G/qos.json.j2 b/device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-O128S2/qos.json.j2 similarity index 100% rename from device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-128x400G/qos.json.j2 rename to device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-O128S2/qos.json.j2 diff --git a/device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-128x400G/sai.profile b/device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-O128S2/sai.profile similarity index 100% rename from device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-128x400G/sai.profile rename to device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-O128S2/sai.profile diff --git a/device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-128x400G/th5-a7060x6-64pe.config.bcm b/device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-O128S2/th5-a7060x6-64pe.config.bcm similarity index 100% rename from device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-128x400G/th5-a7060x6-64pe.config.bcm rename to device/arista/x86_64-arista_7060x6_64pe/Arista-7060X6-64PE-O128S2/th5-a7060x6-64pe.config.bcm From d6d8c579c813bfeab7f1cdbb2ea7bc0f5a2b4042 Mon Sep 17 00:00:00 2001 From: vdahiya12 <67608553+vdahiya12@users.noreply.github.com> Date: Tue, 29 Oct 2024 11:05:04 -0700 Subject: [PATCH 22/23] [yang] add Yang model for XCVRD_LOG|Y_CABLE (#20496) #### Why I did it Adding yang model for CONFIG_DB table XCVRD_LOG|Y_CABLE. Introduced by https://github.com/sonic-net/sonic-utilities/blob/master/config/muxcable.py#L1230-L1235 #### How I did it Added the changes in sonic-yang-models #### How to verify it UT test ``` ==================================================================================== test session starts ==================================================================================== platform linux -- Python 3.9.2, pytest-6.0.2, py-1.10.0, pluggy-0.13.0 rootdir: /sonic/src/sonic-yang-models plugins: pyfakefs-5.2.3, cov-2.10.1 collected 3 items tests/test_sonic_yang_models.py .. [ 66%] tests/yang_model_tests/test_yang_model.py . [100%] ===================================================================================== 3 passed in 2.06s ===================================================================================== ``` --- src/sonic-yang-models/doc/Configuration.md | 1 + src/sonic-yang-models/setup.py | 1 + .../tests/files/sample_config_db.json | 5 +++ .../yang_model_tests/tests/xcvrd-log.json | 5 +++ .../tests_config/xcvrd-log.json | 12 ++++++ .../yang-models/sonic-xcvrd-log.yang | 41 +++++++++++++++++++ 6 files changed, 65 insertions(+) create mode 100644 src/sonic-yang-models/tests/yang_model_tests/tests/xcvrd-log.json create mode 100644 src/sonic-yang-models/tests/yang_model_tests/tests_config/xcvrd-log.json create mode 100644 src/sonic-yang-models/yang-models/sonic-xcvrd-log.yang diff --git a/src/sonic-yang-models/doc/Configuration.md b/src/sonic-yang-models/doc/Configuration.md index 4d264417d509..4ebae55c3ea2 100644 --- a/src/sonic-yang-models/doc/Configuration.md +++ b/src/sonic-yang-models/doc/Configuration.md @@ -86,6 +86,7 @@ Table of Contents * [Virtual router](#virtual-router) * [LOGGER](#logger) * [WRED_PROFILE](#wred_profile) + * [XCVRD_LOG](#xcvrd_log) * [PASSWORD_HARDENING](#password_hardening) * [SSH_SERVER](#ssh_server) * [SYSTEM_DEFAULTS table](#systemdefaults-table) diff --git a/src/sonic-yang-models/setup.py b/src/sonic-yang-models/setup.py index 420dd36a24ca..5e130854eeba 100644 --- a/src/sonic-yang-models/setup.py +++ b/src/sonic-yang-models/setup.py @@ -203,6 +203,7 @@ def run(self): './yang-models/sonic-macsec.yang', './yang-models/sonic-bgp-sentinel.yang', './yang-models/sonic-bmp.yang', + './yang-models/sonic-xcvrd-log.yang', './yang-models/sonic-serial-console.yang', './yang-models/sonic-smart-switch.yang',]), ('cvlyang-models', ['./cvlyang-models/sonic-acl.yang', diff --git a/src/sonic-yang-models/tests/files/sample_config_db.json b/src/sonic-yang-models/tests/files/sample_config_db.json index d58849dd04eb..a9ab004008b6 100644 --- a/src/sonic-yang-models/tests/files/sample_config_db.json +++ b/src/sonic-yang-models/tests/files/sample_config_db.json @@ -2744,6 +2744,11 @@ "midplane_interface": "dpu1" } }, + "XCVRD_LOG": { + "Y_CABLE": { + "log_verbosity": "notice" + } + }, "BANNER_MESSAGE": { "global": { "state": "enabled", diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests/xcvrd-log.json b/src/sonic-yang-models/tests/yang_model_tests/tests/xcvrd-log.json new file mode 100644 index 000000000000..19b85bad5ee5 --- /dev/null +++ b/src/sonic-yang-models/tests/yang_model_tests/tests/xcvrd-log.json @@ -0,0 +1,5 @@ +{ + "XCVRD_LOG_Y_CABLE_CHANGE_VERBOSITY_LEVEL": { + "desc": "Consume verbosity level config changes. " + } +} diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests_config/xcvrd-log.json b/src/sonic-yang-models/tests/yang_model_tests/tests_config/xcvrd-log.json new file mode 100644 index 000000000000..9135a43198b5 --- /dev/null +++ b/src/sonic-yang-models/tests/yang_model_tests/tests_config/xcvrd-log.json @@ -0,0 +1,12 @@ +{ + "XCVRD_LOG_Y_CABLE_CHANGE_VERBOSITY_LEVEL": { + "sonic-xcvrd-log:sonic-xcvrd-log": { + "sonic-xcvrd-log:XCVRD_LOG": { + "sonic-xcvrd-log:Y_CABLE": + { + "log_verbosity": "debug" + } + } + } + } +} diff --git a/src/sonic-yang-models/yang-models/sonic-xcvrd-log.yang b/src/sonic-yang-models/yang-models/sonic-xcvrd-log.yang new file mode 100644 index 000000000000..5d7c8866c6ed --- /dev/null +++ b/src/sonic-yang-models/yang-models/sonic-xcvrd-log.yang @@ -0,0 +1,41 @@ +module sonic-xcvrd-log { + namespace "http://github.com/sonic-net/sonic-xcvrd-log"; + prefix xcvrd_log; + yang-version 1.1; + + organization + "SONiC"; + + contact + "SONiC"; + + description + "SONiC DualToR xcvrd logging configuration data"; + + revision 2024-10-14 { + description + "Initial revision"; + } + + container sonic-xcvrd-log { + + container XCVRD_LOG { + + container Y_CABLE { + + leaf log_verbosity { + type enumeration { + enum info; + enum notice; + enum debug; + enum warning; + enum critical; + } + + description "xcvrd log verbosity level. "; + + } + } + } + } +} From cc4a40258b6624677c1f27266c8ea241cfd2b8ae Mon Sep 17 00:00:00 2001 From: Vijaya Kumar Abbaraju Date: Wed, 30 Oct 2024 00:03:49 +0530 Subject: [PATCH 23/23] MAB common header files for generic files (#18626) * MAB common header files for genereic files * Addressed review comments --- src/sonic-pac/mab/mapping/include/mab_cfg.h | 64 +++ .../mab/mapping/include/mab_client.h | 92 ++++ .../mab/mapping/include/mab_control.h | 397 ++++++++++++++++++ src/sonic-pac/mab/mapping/include/mab_debug.h | 48 +++ src/sonic-pac/mab/mapping/include/mab_ih.h | 41 ++ .../mab/mapping/include/mab_include.h | 66 +++ .../mab/mapping/include/mab_socket.h | 34 ++ .../mab/mapping/include/mab_struct.h | 95 +++++ 8 files changed, 837 insertions(+) create mode 100755 src/sonic-pac/mab/mapping/include/mab_cfg.h create mode 100755 src/sonic-pac/mab/mapping/include/mab_client.h create mode 100755 src/sonic-pac/mab/mapping/include/mab_control.h create mode 100755 src/sonic-pac/mab/mapping/include/mab_debug.h create mode 100755 src/sonic-pac/mab/mapping/include/mab_ih.h create mode 100755 src/sonic-pac/mab/mapping/include/mab_include.h create mode 100644 src/sonic-pac/mab/mapping/include/mab_socket.h create mode 100755 src/sonic-pac/mab/mapping/include/mab_struct.h diff --git a/src/sonic-pac/mab/mapping/include/mab_cfg.h b/src/sonic-pac/mab/mapping/include/mab_cfg.h new file mode 100755 index 000000000000..104462e6423c --- /dev/null +++ b/src/sonic-pac/mab/mapping/include/mab_cfg.h @@ -0,0 +1,64 @@ +/* + * Copyright 2024 Broadcom Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INCLUDE_MAB_CFG_H +#define INCLUDE_MAB_CFG_H + +#include "nim_data.h" +/* USE C Declarations */ +#ifdef __cplusplus + extern "C" { +#endif +#define PASSWORD_SIZE MAB_USER_NAME_LEN + +extern BOOL mabInitializationState; +#define MAB_IS_READY (mabInitializationState) + +typedef struct mabPortCfg_s +{ + nimConfigID_t configId; /* NIM config ID for this interface*/ + uint32 maxUsers; /*Maximum no. users in Mac-Based Authentication */ + uint32 mabEnabled; /*enabled if MAB is enabled for the port*/ + AUTHMGR_PORT_MAB_AUTH_TYPE_t mabAuthType; /* Authentication type to be used by MAB */ +} mabPortCfg_t; + +typedef struct mabCfg_s +{ + mabPortCfg_t mabPortCfg[ MAB_INTF_MAX_COUNT]; /* Per-port config info */ +} mabCfg_t; + +extern mabCfg_t *mabCfg; + +extern uint32 mabPhysPortGet(uint32 lIntIfNum); +extern void mabBuildDefaultConfigData(); +extern void mabBuildDefaultIntfConfigData(nimConfigID_t *configId, mabPortCfg_t *pCfg); + +extern RC_t mabApplyConfigData(void); +extern RC_t mabPortInfoInitialize(uint32 intIfNum, BOOL flag); +extern RC_t mabPortReset(uint32 intIfNum); + +extern BOOL mabIsRestartTypeWarm(); +extern RC_t mabInit(void); +extern void mabInitUndo(); +extern RC_t mabInitPhase1Process(void); +extern RC_t mabInitPhase2Process(void); +extern RC_t mabInitPhase3Process( BOOL warmRestart); + +/* USE C Declarations */ +#ifdef __cplusplus +} +#endif +#endif /* INCLUDE_MAB_CFG_H */ diff --git a/src/sonic-pac/mab/mapping/include/mab_client.h b/src/sonic-pac/mab/mapping/include/mab_client.h new file mode 100755 index 000000000000..a331c5e62c61 --- /dev/null +++ b/src/sonic-pac/mab/mapping/include/mab_client.h @@ -0,0 +1,92 @@ +/* + * Copyright 2024 Broadcom Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INCLUDE_MAB_CLIENT_H +#define INCLUDE_MAB_CLIENT_H + +/* USE C Declarations */ +#ifdef __cplusplus + extern "C" { +#endif + +#define MAC_STR_LEN 17 + +#include "comm_mask.h" + +/********************************************************************* + * @purpose Set the mab client authorization status + * + * @param lIntIfNum @b{(input)) internal interface number + * @param portStatus @b{(input)) port authorization status setting + * + * @returns SUCCESS + * @returns FAILURE + * @returns ERROR + * + * @comments none + * + * @end + *********************************************************************/ +RC_t mabClientStatusSet(mabLogicalPortInfo_t *logicalPortInfo, AUTHMGR_PORT_STATUS_t portStatus); + +/********************************************************************* + * @purpose function to cleanup the client + * + * @param intIfNum @b{(input)) internal interface number + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t mabClientInfoCleanup(mabLogicalPortInfo_t *logicalPortInfo); + +/********************************************************************* + * @purpose function to cleanup the client sw info + * + * @param intIfNum @b{(input)) internal interface number + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t mabClientSwInfoCleanup(mabLogicalPortInfo_t *logicalPortInfo); + +/********************************************************************* + * @purpose function to check and deAllocate the client + * + * @param intIfNum @b{(input)) internal interface number + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t mabClientDisconnectAction(mabLogicalPortInfo_t *logicalPortInfo); + +/* USE C Declarations */ +#ifdef __cplusplus +} +#endif + +#endif /* INCLUDE_MAB_CLIENT_H */ diff --git a/src/sonic-pac/mab/mapping/include/mab_control.h b/src/sonic-pac/mab/mapping/include/mab_control.h new file mode 100755 index 000000000000..251d44934fe0 --- /dev/null +++ b/src/sonic-pac/mab/mapping/include/mab_control.h @@ -0,0 +1,397 @@ +/* + * Copyright 2024 Broadcom Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INCLUDE_MAB_CONTROL_H +#define INCLUDE_MAB_CONTROL_H + +/* USE C Declarations */ +#ifdef __cplusplus + extern "C" { +#endif + +#include +#include "auth_mgr_common.h" + +typedef enum mabControlEvents_s +{ + /***************************************************************/ + /* Events shared with all */ + /***************************************************************/ + /*100*/mabControlBegin = 100, + + /***************************************************************/ + /* Events from Management commands */ + /***************************************************************/ + /*101*/mabMgmtPortInitializeSet, + /*102*/mabMgmtPortControlModeSet, + /*103*/mabMgmtPortHostModeSet, + /*104*/mabMgmtPortStatsClear, + /*105*/mabMgmtApplyConfigData, // No calls to API + /*106*/mabMgmtPortMABEnableSet, + /*107*/mabMgmtPortMABDisableSet, + + /*120*/mabMgmtEvents = 120, /*keep this last in sub group*/ + + /***************************************************************/ + /* Events from AAA client */ + /***************************************************************/ + /*121*/mabAaaInfoReceived, + /*122*/mabRadiusConfigUpdate, + + /***************************************************************/ + /* Events from interface state changes */ + /***************************************************************/ + /*123*/mabIntfChange, + /*124*/mabIntfStartup, + + /***************************************************************/ + /* Events from Vlan state changes */ + /***************************************************************/ + /*131*/mabVlanDeleteEvent = 131, + /*132*/mabVlanAddEvent, + /*133*/mabVlanAddPortEvent, + /*134*/mabVlanDeletePortEvent, + /*135*/mabVlanPvidChangeEvent, + + /***************************************************************/ + /* Events from authentication manager. */ + /***************************************************************/ + /*136*/mabAuthMgrEvent, + + /*137*/mabAddMacInMacDB, + + /***************************************************************/ + /* App timer events. */ + /***************************************************************/ + /*138*/ mabTimeTick, + + +}mabControlEvents_t; + +/* Message structure to Global RADIUS config updates */ +typedef struct mabRadiusGlobal_s +{ + unsigned char nas_ip[64]; + unsigned char nas_id[64]; +}mabRadiusGlobal_t; + +/* Message structure to RADIUS config updates */ +typedef struct mabRadiusServer_s +{ + unsigned int cmd; + union { + mab_radius_server_t server; + mabRadiusGlobal_t globalCfg; + }cmd_data; +}mabRadiusServer_t; + +typedef struct mabIpAaddr { + unsigned char af; /* AF_INET / AF_INET6 */ + union { + struct in_addr v4; + struct in6_addr v6; + } u; +}mabIpAaddr_t; + +/* Message structure to hold responses from AAA client (i.e. RADIUS) */ +typedef struct mabAaaMsg_s +{ + void *resp; + unsigned int len; +} mabAaaMsg_t; + +typedef struct mabIntfChangeParms_s +{ + uint32 intfEvent; + NIM_CORRELATOR_t nimCorrelator; +} mabIntfChangeParms_t; + +/* Message structure to hold responses from authentication manager */ +typedef struct mabAuthmgrMsg_s +{ + uint32 event; /* event */ + enetMacAddr_t clientMacAddr; /* client mac addr*/ +} mabAuthmgrMsg_t; + +typedef struct mabMsg_s +{ + uint32 event; + uint32 intf; + union + { + uint32 msgParm; + mabAaaMsg_t mabAaaMsg; + mabIntfChangeParms_t mabIntfChangeParms; + dot1qNotifyData_t vlanData; + NIM_STARTUP_PHASE_t startupPhase; + mabAuthmgrMsg_t mabAuthmgrMsg; + mabRadiusServer_t mabRadiusCfgMsg; + }data; +} mabMsg_t; + + +#define MAB_MSG_COUNT FD_MAB_MSG_COUNT +#define MAB_TIMER_TICK 1000 /*in milliseconds*/ + +extern RC_t mabStartTasks(); +extern void mabTask(); +extern void mabSrvrTask (); +extern void mabEloopTask (); +extern RC_t mabFillMsg(void *data, mabMsg_t *msg); +extern RC_t mabIssueCmd(uint32 event, uint32 intIfNum, void *data); +extern RC_t mabDispatchCmd(mabMsg_t *msg); +extern RC_t mabTimerAction(); +extern RC_t mabAuthmgrEventMapFnGet(uint32 event, mabAuthmgrEventFnMap_t *elem); +extern RC_t mabCtlPortInitializeSet(uint32 intIfNum, BOOL initialize); +extern RC_t mabCtlPortControlModeSet(uint32 intIfNum, AUTHMGR_PORT_CONTROL_t portControl); +extern RC_t mabPortCtrlModeSet(uint32 intIfNum, AUTHMGR_PORT_CONTROL_t portControl); +extern RC_t mabCtlPortStatsClear(uint32 intIfNum); +extern RC_t mabCtlApplyConfigData(void); +extern RC_t mabCtlApplyPortConfigData(uint32 intIfNum); +extern RC_t mabRadiusServerVlanConversionHandle(const char8 *vlanName, uint32 *vlanId); +extern RC_t mabVlanChangeCallback(dot1qNotifyData_t *vlanData, uint32 intIfNum, uint32 event); +extern void mabVlanChangeProcess(uint32 event, uint32 intIfNum, dot1qNotifyData_t *vlanData); +extern RC_t mabCheckMapPdu(uint32 intIfNum, char8 *srcMac, uint32 *logicalPort, BOOL *existing_node); +extern RC_t mabVlanPVIDChangeEventProcess(uint32 intIfNum,uint32 vlanId); + +extern RC_t mabCtlPortMABEnableSet(uint32 intIfNum); +extern RC_t mabCtlPortMABDisableSet(uint32 intIfNum); +extern RC_t mabCtlLogicalPortMABGenResp(uint32 lIntIfNum, BOOL generateNak); + +extern RC_t mabPortControlForceUnAuthActionSet(uint32 intIfNum); + +int mab_socket_server_handle(int *listen_sock); +int mabPortClientAuthStatusUpdate(int intIfNum, unsigned char *addr, char *status, void *param); + +/********************************************************************* + * @purpose control mode function to set the port control mode to auto + * + * @param intIfNum @b{(input)) internal interface number + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t mabPortControlAutoActionSet(uint32 intIfNum); + +/********************************************************************* + * @purpose control function to set the host mode to multi-domain-auth + * + * @param intIfNum @b{(input)) internal interface number + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t mabControlMultiDomainHostAuthActionSet(uint32 intIfNum); + +/********************************************************************* + * @purpose control function to set the host mode to multi host + * + * @param intIfNum @b{(input)) internal interface number + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t mabControlMultiHostActionSet(uint32 intIfNum); + +/********************************************************************* + * @purpose control function to set the host mode to single host mode + * + * @param intIfNum @b{(input)) internal interface number + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t mabControlSingleAuthActionSet(uint32 intIfNum); + +/********************************************************************* + * @purpose control function to set the host mode to multi auth + * + * @param intIfNum @b{(input)) internal interface number + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t mabControlMultAuthActionSet(uint32 intIfNum); + +/********************************************************************* + * @purpose control function to set the to force authorized + * + * @param intIfNum @b{(input)) internal interface number + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t mabPortControlForceAuthActionSet(uint32 intIfNum); + +/********************************************************************* + * @purpose control function to set the to force un-authorized + * + * @param intIfNum @b{(input)) internal interface number + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t mabPortControlForceUnAuthActionSet(uint32 intIfNum); + +/********************************************************************* + * @purpose function to clean up mab port oper info + * + * @param intIfNum @b{(input)) internal interface number + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t mabPortInfoCleanup(uint32 intIfNum); + +RC_t mabHostModeMapInfoGet( AUTHMGR_HOST_CONTROL_t type, mabHostModeMap_t *elem); + +/********************************************************************* + * @purpose control mode function to set the port host mode + * + * @param intIfNum @b{(input)) internal interface number + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t mabPortCtrlHostModeSet(uint32 intIfNum, AUTHMGR_HOST_CONTROL_t hostMode); + +/********************************************************************* + * @purpose Actions to be performed in the APM state DISCONNECTED + * + * @param logicalPortInfo @b{(input)) Logical Port Info node + * + * @returns SUCCESS + * + * @comments + * + * @end + *********************************************************************/ +RC_t mabUnAuthenticatedAction(mabLogicalPortInfo_t *logicalPortInfo); + +/********************************************************************* + * @purpose Actions to be performed in the APM state AUTHENTICATED + * + * @param logicalPortInfo @b{(input)) Logical Port Info node + * + * @returns SUCCESS + * + * @comments + * + * @end + *********************************************************************/ +RC_t mabAuthenticatedAction(mabLogicalPortInfo_t *logicalPortInfo); + +/********************************************************************* + * @purpose Actions to be performed in the APM state AUTHENTICATING + * + * @param logicalPortInfo @b{(input)) Logical Port Info node + * + * @returns SUCCESS + * + * @comments + * + * @end + *********************************************************************/ +RC_t mabAuthenticatingAction(mabLogicalPortInfo_t *logicalPortInfo); + +/********************************************************************* + * @purpose Add supplicant MAC in MAC database + * + * @param lIntIfNum @b{(input)} logical interface number that this PDU was received on + * + * @returns SUCCESS or FAILURE + * + * @end + *********************************************************************/ +RC_t mabAddMac(uint32 lIntIfNum); + +RC_t mabAuthenticationInitiate(uint32 intIfNum, enetMacAddr_t suppMacAddr); + +RC_t mabAuthmgrEventProcess(uint32 intIfNum, mabAuthmgrMsg_t *authmgrParams); + +/********************************************************************* +* @purpose Set values of the Logical Dot1x Port Structure +* with Default Values of port it belongs to +* +* @param logicalPortInfo @b{(input)) Logical port Info +* +* @returns SUCCESS +* @returns FAILURE +* +* @comments +* +* @end +*********************************************************************/ +RC_t mabLogicalPortInfoInit(uint32 lIntIfNum); + +/********************************************************************* + * @purpose API to check and clear appTimer Deinit + * + * @param none + * + * @returns SUCCESS + * @returns FAILURE + * + * @comments + * + * @end + *********************************************************************/ +RC_t mabAppTimerDeInitCheck(void); + +RC_t mabRadiusChangeHandle(mabRadiusServer_t *info); + +/* USE C Declarations */ +#ifdef __cplusplus +} +#endif + +#endif /* INCLUDE_MAB_CONTROL_H */ diff --git a/src/sonic-pac/mab/mapping/include/mab_debug.h b/src/sonic-pac/mab/mapping/include/mab_debug.h new file mode 100755 index 000000000000..cf8a098619a7 --- /dev/null +++ b/src/sonic-pac/mab/mapping/include/mab_debug.h @@ -0,0 +1,48 @@ +/* + * Copyright 2024 Broadcom Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INCLUDE_MAB_DEBUG_H +#define INCLUDE_MAB_DEBUG_H + + /* USE C Declarations */ +#ifdef __cplusplus + extern "C" { +#endif + +#define MAB_ERROR_SEVERE(format,args...) \ +{ \ + LOGF(LOG_SEVERITY_ERROR,format,##args); \ +} + +#define MAB_EVENT_TRACE(__fmt__, __args__...) \ + { \ + char8 __buf1__[256] = {0}; \ + (void)osapiSnprintf(__buf1__, 256, __fmt__, ## __args__); \ + LOGF(LOG_SEVERITY_DEBUG, \ + "[%s:%d]%s",__FUNCTION__, __LINE__, (char *)__buf1__); \ + } + +char *mabHostModeStringGet( AUTHMGR_HOST_CONTROL_t hostMode); +char *mabNodeTypeStringGet(authmgrNodeType_t type); +char *mabTimerTypeStringGet(mabTimerType_t type); +char *mabVlanTypeStringGet(authmgrVlanType_t type); + +/* USE C Declarations */ +#ifdef __cplusplus +} +#endif + +#endif /* INCLUDE_MAB_DEBUG_H*/ diff --git a/src/sonic-pac/mab/mapping/include/mab_ih.h b/src/sonic-pac/mab/mapping/include/mab_ih.h new file mode 100755 index 000000000000..66f6816a8765 --- /dev/null +++ b/src/sonic-pac/mab/mapping/include/mab_ih.h @@ -0,0 +1,41 @@ +/* + * Copyright 2024 Broadcom Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INCLUDE_MAB_IH_H +#define INCLUDE_MAB_IH_H + + /* USE C Declarations */ +#ifdef __cplusplus + extern "C" { +#endif + +extern RC_t mabIntfChangeCallback(uint32 intIfNum, uint32 intfEvent,NIM_CORRELATOR_t correlator, + NIM_EVENT_SPECIFIC_DATA_t eventData); +extern RC_t mabIhProcessIntfChange(uint32 intIfNum, uint32 intfEvent, NIM_CORRELATOR_t correlator); +extern RC_t mabIhProcessIntfStartup(NIM_STARTUP_PHASE_t startupPhase); +extern RC_t mabIntfActivateStartup(); +extern void mabIntfStartupCallback(NIM_STARTUP_PHASE_t startupPhase); +extern BOOL mabIntfIsConfigurable(uint32 intIfNum, mabPortCfg_t **pCfg); +extern RC_t mabIntfCreate(uint32 intIfNum); +extern RC_t mabIntfDetach(uint32 intIfNum); +extern RC_t mabIntfDelete(uint32 intIfNum); + +/* USE C Declarations */ +#ifdef __cplusplus +} +#endif + +#endif /*INCLUDE_MAB_IH_H*/ diff --git a/src/sonic-pac/mab/mapping/include/mab_include.h b/src/sonic-pac/mab/mapping/include/mab_include.h new file mode 100755 index 000000000000..6b3808bd98f2 --- /dev/null +++ b/src/sonic-pac/mab/mapping/include/mab_include.h @@ -0,0 +1,66 @@ +/* + * Copyright 2024 Broadcom Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + + +#ifndef INCLUDE_MAB_INCLUDE_H +#define INCLUDE_MAB_INCLUDE_H + +/* +*********************************************************************** +* COMMON INCLUDES +*********************************************************************** +*/ + /* USE C Declarations */ +#ifdef __cplusplus + extern "C" { +#endif + +/* +********************************************************************** +* STANDARD LIBRARIES +********************************************************************** +*/ + +#include +#include +#include + +/* +********************************************************************** +* MAB HEADER FILES +********************************************************************** +*/ +#include "pacinfra_common.h" +#include "osapi.h" +#include "nimapi.h" + +#include "mab_api.h" +#include "mab_common.h" +#include "mab_db.h" +#include "mab_cfg.h" +#include "mab_control.h" +#include "mab_ih.h" +#include "mab_local.h" +#include "mab_debug.h" +#include "mab_sid.h" +#include "mab_mac_db.h" + +/* USE C Declarations */ +#ifdef __cplusplus +} +#endif +#endif /* INCLUDE_MAB_INCLUDE_H */ diff --git a/src/sonic-pac/mab/mapping/include/mab_socket.h b/src/sonic-pac/mab/mapping/include/mab_socket.h new file mode 100644 index 000000000000..8518632a5627 --- /dev/null +++ b/src/sonic-pac/mab/mapping/include/mab_socket.h @@ -0,0 +1,34 @@ +/* + * Copyright 2024 Broadcom Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef MAB_SOCKET_H +#define MAB_SOCKET_H + +#define MAB_INTF_STR_LEN 128 +#define MAB_CMD_STR_LEN 128 + +typedef struct mab_pac_cmd_s +{ + char intf[MAB_INTF_STR_LEN]; + char cmd[MAB_CMD_STR_LEN]; + unsigned char mac_addr[6]; + unsigned int notif_event; +}mab_pac_cmd_t; + +int mab_radius_init_send_socket(int *sock); +int mab_radius_init_recv_socket(int *sock); +#endif diff --git a/src/sonic-pac/mab/mapping/include/mab_struct.h b/src/sonic-pac/mab/mapping/include/mab_struct.h new file mode 100755 index 000000000000..d111cfbbf18b --- /dev/null +++ b/src/sonic-pac/mab/mapping/include/mab_struct.h @@ -0,0 +1,95 @@ +/* + * Copyright 2024 Broadcom Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INCLUDE_MAB_STRUCT_H +#define INCLUDE_MAB_STRUCT_H + +/* USE C Declarations */ +#ifdef __cplusplus +extern "C" { +#endif + +#include "pacinfra_common.h" +#include "osapi.h" +#include "avl_api.h" +#include "apptimer_api.h" +#include "mab_db.h" +#include "mab_cfg.h" +#include "mab_api.h" +#include "mab_debug.h" +#include "mab_include.h" +#include "portevent_mask.h" +#include "tree_api.h" + +typedef struct connection_list_e +{ + int socket; + pthread_t tid; +}connection_list_t; + + +typedef struct mabBlock_s +{ + void * mabTaskId; + void * mabSrvrTaskId; + void * mabEloopTaskId; + int mabServerSock; + int send_fd; + int recv_fd; + connection_list_t *conn_list; + void *rad_cxt; + + mabCfg_t *mabCfg; + mabInfo_t mabInfo; + mabPortInfo_t *mabPortInfo; + mabPortStats_t *mabPortStats; + uint32 *mabMapTbl; + + /* App timer related data */ + APP_TMR_CTRL_BLK_t mabTimerCB; + uint32 mabAppTimerBufferPoolId; + + BOOL warmRestart; + BOOL mabSwitchoverInProgress; + + void *mabQueue; /* reference to the mab message queue */ + void *mabTaskSyncSema; + + void *mabRadiusSrvrTaskSyncSema; + + /* Global parameters */ + avlTree_t mabLogicalPortTreeDb; + avlTreeTables_t *mabLogicalPortTreeHeap; + mabLogicalPortInfo_t *mabLogicalPortDataHeap; + + uint32 mabMacAddrBufferPoolId; + sll_t mabMacAddrSLL; + osapiRWLock_t mabMacAddrDBRWLock; + + osapiRWLock_t mabRWLock; + + mabIpAaddr_t nas_ip; + unsigned char nas_id[64]; + +}mabBlock_t; + +/* USE C Declarations */ +#ifdef __cplusplus +} +#endif + + +#endif /* INCLUDE_MAB_STRUCT_H */