From a29a2a49770df90ef18132a37b2ff1dea82dae4f Mon Sep 17 00:00:00 2001 From: Abhishek Date: Thu, 16 Jan 2020 22:23:24 -0800 Subject: [PATCH 001/178] [submodule update of sonic-mgmr-framework] Pointing to latest master. Needed as Compilation was failing. --- src/sonic-mgmt-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-mgmt-framework b/src/sonic-mgmt-framework index 8b199a9f822c..00410e5516ec 160000 --- a/src/sonic-mgmt-framework +++ b/src/sonic-mgmt-framework @@ -1 +1 @@ -Subproject commit 8b199a9f822ca42564a7a89da0cab3133684bd12 +Subproject commit 00410e5516ec4dce957c6bb1fdd0258ef47bfafa From bb34edf1afd713a143169ffb96ba4d19b7b9d83b Mon Sep 17 00:00:00 2001 From: rajendra-dendukuri <47423477+rajendra-dendukuri@users.noreply.github.com> Date: Wed, 4 Dec 2019 10:15:58 -0500 Subject: [PATCH 002/178] [config-setup]: create a SONiC configuration management service (#3227) * Create a SONiC configuration management service * Perform config db migration after loading config_db.json to redis DB * Migrate config-setup post migration hooks on image upgrade config-setup post migration hooks help user to migrate configurations from old image to new image. If the installed hooks are user defined they will not be part of the newly installed image. So these hooks have to be migrated to new image and only then they can be executing when the new image is booting. The changes in this fix migrate config-setup post-migration hooks and ensure that any hooks with the same filename in newly installed image are not overwritten. It is expected that users install new hooks as per their requirement and not edit existing hooks. Any changes to existing hooks need to be done as part of new image and not post bootup. --- files/build_templates/config-setup.service.j2 | 18 + .../build_templates/sonic_debian_extension.j2 | 5 + files/build_templates/updategraph.service.j2 | 9 +- files/image_config/config-setup/config-setup | 399 ++++++++++++++++++ files/image_config/updategraph/updategraph | 72 +--- 5 files changed, 430 insertions(+), 73 deletions(-) create mode 100644 files/build_templates/config-setup.service.j2 create mode 100755 files/image_config/config-setup/config-setup diff --git a/files/build_templates/config-setup.service.j2 b/files/build_templates/config-setup.service.j2 new file mode 100644 index 000000000000..a4b614a5f7fb --- /dev/null +++ b/files/build_templates/config-setup.service.j2 @@ -0,0 +1,18 @@ +[Unit] +Description=Config initialization and migration service +After=rc-local.service +After=database.service +Requires=database.service +{% if sonic_asic_platform == 'mellanox' -%} +Requires=hw-management.service +{% endif -%} + + +[Service] +Type=oneshot +ExecStart=/usr/bin/config-setup boot +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target + diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 0e6d07fb001a..81bec67796d2 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -258,6 +258,11 @@ sudo bash -c "echo '{ \"DEVICE_METADATA\": { \"localhost\": { \"default_bgp_stat \"{{crm_res}}_threshold_type\": \"percentage\", \"{{crm_res}}_low_threshold\": \"70\", \"{{crm_res}}_high_threshold\": \"85\"{% if not loop.last %}, {% endif %} {%- endfor %} } } }' >> $FILESYSTEM_ROOT/etc/sonic/init_cfg.json" +# Copy config-setup script and service file +j2 files/build_templates/config-setup.service.j2 | sudo tee $FILESYSTEM_ROOT/etc/systemd/system/config-setup.service +sudo cp $IMAGE_CONFIGS/config-setup/config-setup $FILESYSTEM_ROOT/usr/bin/config-setup +sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable config-setup.service + # Copy SNMP configuration files sudo cp $IMAGE_CONFIGS/snmp/snmp.yml $FILESYSTEM_ROOT/etc/sonic/ diff --git a/files/build_templates/updategraph.service.j2 b/files/build_templates/updategraph.service.j2 index 8039f42531cd..0e05cbf147d6 100644 --- a/files/build_templates/updategraph.service.j2 +++ b/files/build_templates/updategraph.service.j2 @@ -1,12 +1,7 @@ [Unit] Description=Update minigraph and set configuration based on minigraph -After=rc-local.service -After=database.service -Requires=database.service -{% if sonic_asic_platform == 'mellanox' -%} -Requires=hw-management.service -{% endif -%} - +After=config-setup.service +Requires=config-setup.service [Service] Type=oneshot diff --git a/files/image_config/config-setup/config-setup b/files/image_config/config-setup/config-setup new file mode 100755 index 000000000000..bd497d06b257 --- /dev/null +++ b/files/image_config/config-setup/config-setup @@ -0,0 +1,399 @@ +#!/bin/bash +########################################################################### +# 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. # +# # +########################################################################### +# SONiC Configuration Setup # +# # +# This script is used to initialize configuration used # +# by SONiC SWSS. It also performs configuration # +# migration. # +# # +########################################################################### + +# Initialize constants +CONFIG_DB_INDEX=4 +UPDATEGRAPH_CONF=/etc/sonic/updategraph.conf +CONFIG_DB_JSON=/etc/sonic/config_db.json +MINGRAPH_FILE=/etc/sonic/minigraph.xml +TMP_ZTP_CONFIG_DB_JSON=/tmp/ztp_config_db.json +FACTORY_DEFAULT_HOOKS=/etc/config-setup/factory-default-hooks.d +CONFIG_PRE_MIGRATION_HOOKS=/etc/config-setup/config-migration-pre-hooks.d +CONFIG_POST_MIGRATION_HOOKS=/etc/config-setup/config-migration-post-hooks.d +CONFIG_SETUP_VAR_DIR=/var/lib/config-setup +CONFIG_SETUP_PRE_MIGRATION_FLAG=${CONFIG_SETUP_VAR_DIR}/pending_pre_migration +CONFIG_SETUP_POST_MIGRATION_FLAG=${CONFIG_SETUP_VAR_DIR}/pending_post_migration +CONFIG_SETUP_INITIALIZATION_FLAG=${CONFIG_SETUP_VAR_DIR}/pending_initialization + +# Command usage and help +usage() +{ + cat << EOF + Usage: config-setup < backup | boot | factory > + + backup - Take a backup copy of SONiC configuration. + boot - Initialize/migrate SONiC configuration during system boot. + factory - Create factory default SONiC configuration and save it to + to ${CONFIG_DB_JSON}. +EOF +} + +# run given script +run_hook() { + local script="$1" + local exit_status=0 + + if [ -f $script ]; then + # Check hook for syntactical correctness before executing it + /bin/bash -n $script + exit_status=$? + if [ "$exit_status" -eq 0 ]; then + . $script + fi + exit_status=$? + fi + + if [ -n "$exit_status" ] && [ "$exit_status" -ne 0 ]; then + echo "$script returned non-zero exit status $exit_status" + fi + + return $exit_status +} + +# run scripts in given directory +run_hookdir() { + local dir="$1" + local progress_file="$2" + local exit_status=0 + + if [ -d "$dir" ]; then + if [ -n $progress_file ]; then + [ ! -d $(dirname $progress_file) ] && mkdir -p $(dirname $progress_file) + [ ! -e $progress_file ] && run-parts --list $dir > $progress_file + SCRIPT_LIST=$(cat $progress_file) + else + SCRIPT_LIST=$(run-parts --list $dir) + fi + + for script in $SCRIPT_LIST; do + run_hook $script + exit_status=$((exit_status|$?)) + script_name=$(basename $script) + sed -i "/$script_name/d" $progress_file + done + [ -n $progress_file ] && [ "$(cat ${progress_file})" = "" ] && rm -f ${progress_file} + fi + + return $exit_status +} + +# Reload minigraph.xml file on disk +reload_minigraph() +{ + echo "Reloading minigraph..." + if [ ! -f /etc/sonic/init_cfg.json ]; then + echo "{}" > /etc/sonic/init_cfg.json + fi + redis-cli -n $CONFIG_DB_INDEX FLUSHDB + sonic-cfggen -H -m -j /etc/sonic/init_cfg.json --write-to-db + redis-cli -n $CONFIG_DB_INDEX SET "CONFIG_DB_INITIALIZED" "1" + if [ -f /etc/sonic/acl.json ]; then + acl-loader update full /etc/sonic/acl.json + fi + config qos reload + pfcwd start_default + + if [[ -x /usr/bin/db_migrator.py ]]; then + # Set latest version number + /usr/bin/db_migrator.py -o set_version + fi +} + +# Restore SONiC configuration from a backup copy +function copy_config_files_and_directories() +{ + for file_dir in $@; do + if [ -f /etc/sonic/old_config/${file_dir} ] || [ -d /etc/sonic/old_config/${file_dir} ]; then + echo "Copying SONiC configuration ${file_dir} ..." + cp -ar /etc/sonic/old_config/${file_dir} /etc/sonic/ + else + echo "Missing SONiC configuration ${file_dir} ..." + fi + done +} + +# Check if SONiC swich has booted after a warm reboot request +check_system_warm_boot() +{ + SYSTEM_WARM_START=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|system" enable` + # SYSTEM_WARM_START could be empty, always make WARM_BOOT meaningful. + if [[ x"$SYSTEM_WARM_START" == x"true" ]]; then + WARM_BOOT="true" + else + WARM_BOOT="false" + fi +} + +# Check if updategraph service is administratively enabled +updategraph_is_enabled() +{ + rv=1 + if [ -e ${UPDATEGRAPH_CONF} ]; then + updategraph_mode=$(grep enabled ${UPDATEGRAPH_CONF} | head -n 1 | cut -f2 -d=) + [ "${updategraph_mode}" = "true" ] && rv = 0 + fi + return $rv +} + +# Disable updategraph admininistratively +disable_updategraph() +{ + sed -i "/enabled=/d" ${UPDATEGRAPH_CONF} + echo "enabled=false" >> ${UPDATEGRAPH_CONF} +} + +# Check if Zero Touch Provisioning is available and is administratively enabled +ztp_is_enabled() +{ + rv=1 + if [ -e /usr/bin/ztp ]; then + status=$(ztp status -c) + [ "$status" != "0:DISABLED" ] && [ "$status" != "" ] && rv=0 + fi + return $rv +} + +# Load requested SONiC configuration into config DB and initialize it +# Usage: load_config +# +# +load_config() +{ + CONFIG_FILE=${1} + if [ "${CONFIG_FILE}" = "" ]; then + return 1 + fi + + redis-cli -n $CONFIG_DB_INDEX FLUSHDB + sonic-cfggen -j ${CONFIG_FILE} --write-to-db + if [ $? -ne 0 ]; then + return $? + fi + + if [[ -x /usr/bin/db_migrator.py ]]; then + # Migrate the DB to the latest schema version if needed + /usr/bin/db_migrator.py -o migrate + fi + + redis-cli -n $CONFIG_DB_INDEX SET "CONFIG_DB_INITIALIZED" "1" + return 0 +} + + +# Generate requested SONiC configuration and save it as destination file +# Usage: generate_config < factory | ztp > +# +# factory - Create factory default configuration +# ztp - Create Zero Touch Provisioning Configuration +# used for provisioning data discovery. +# +generate_config() +{ + # Collect all information needed to generate configuration + PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` + PRESET=(`head -n 1 /usr/share/sonic/device/$PLATFORM/default_sku`) + HW_KEY=${PRESET[0]} + DEFAULT_PRESET=${PRESET[1]} + + # Parse arguments passed + CONFIG_TYPE=$1 + DEST_FILE=$2 + + if [ "$1" = "ztp" ]; then + /usr/lib/ztp/ztp-profile.sh create ${DEST_FILE} + elif [ "$1" = "factory" ]; then + rv=1 + + # Execute config initialization hooks + run_hookdir ${FACTORY_DEFAULT_HOOKS} ${CONFIG_SETUP_INITIALIZATION_FLAG} + + # Use preset defined in default_sku + if [ ! -e ${DEST_FILE} ]; then + sonic-cfggen -H -k ${HW_KEY} --preset ${DEFAULT_PRESET} > ${DEST_FILE} + rv=$? + if [ $rv -ne 0 ]; then + return $rv + fi + fi + fi + return 0 +} + +# Create SONiC configuration for first time bootup +# - If ZTP is enabled, ZTP configuraion is created +# - If ZTP is disabled and updategraph is disabled, factory default configuration +# is created +# - If updategraph is enabled and ZTP is disabled, updategraph initializes +# configuration +do_config_intialization() +{ + if ! updategraph_is_enabled ; then + if ! ztp_is_enabled ; then + echo "No configuration detected, generating factory default configuration..." + generate_config factory ${CONFIG_DB_JSON} + load_config ${CONFIG_DB_JSON} + fi + fi + + if ztp_is_enabled ; then + echo "No configuration detected, initiating zero touch provisioning..." + generate_config ztp ${TMP_ZTP_CONFIG_DB_JSON} + load_config ${TMP_ZTP_CONFIG_DB_JSON} + rm -f ${TMP_ZTP_CONFIG_DB_JSON} + fi + + rm -f /tmp/pending_config_initialization +} + +# Restore config-setup post migration hooks from a backup copy +copy_post_migration_hooks() +{ + BACKUP_DIR=/etc/sonic/old_config/config-migration-post-hooks.d + if [ -d ${BACKUP_DIR} ]; then + [ -d ${CONFIG_POST_MIGRATION_HOOKS} ] || mkdir -p ${CONFIG_POST_MIGRATION_HOOKS} + for hook in $(ls -1 ${BACKUP_DIR}) ; do + if [ ! -e ${CONFIG_POST_MIGRATION_HOOKS}/$hook ]; then + cp -ar ${BACKUP_DIR}/$hook ${CONFIG_POST_MIGRATION_HOOKS} + fi + done + fi +} + +# Perform configuration migration from backup copy. +# - This step is performed when a new image is installed and SONiC switch boots into it +do_config_migration() +{ + # Identify list of files to migrate + copy_list="minigraph.xml snmp.yml acl.json config_db.json frr" + + # Migrate all configuration files from old to new + copy_config_files_and_directories $copy_list + + # Migrate post-migration hooks + copy_post_migration_hooks + + # Execute custom hooks if present + run_hookdir ${CONFIG_POST_MIGRATION_HOOKS} ${CONFIG_SETUP_POST_MIGRATION_FLAG} + + if [ x"${WARM_BOOT}" == x"true" ]; then + echo "Warm reboot detected..." + disable_updategraph + rm -f /tmp/pending_config_migration + exit 0 + elif [ -r ${CONFIG_DB_JSON} ]; then + echo "Use config_db.json from old system..." + sonic-cfggen -j ${CONFIG_DB_JSON} --write-to-db + + if [[ -x /usr/bin/db_migrator.py ]]; then + # Migrate the DB to the latest schema version if needed + /usr/bin/db_migrator.py -o migrate + fi + elif [ -r ${MINGRAPH_FILE} ]; then + echo "Use minigraph.xml from old system..." + reload_minigraph + sonic-cfggen -d --print-data > ${CONFIG_DB_JSON} + + # Disable updategraph + disable_updategraph + else + echo "Didn't found neither config_db.json nor minigraph.xml ..." + fi + + rm -f /tmp/pending_config_migration +} + +# Take a backup of current SONiC configuration +do_config_backup() +{ + echo "Taking backup of curent configuration" + rm -rf /host/old_config + cp -ar /etc/sonic /host/old_config + [ -d ${CONFIG_POST_MIGRATION_HOOKS} ] && cp -arL ${CONFIG_POST_MIGRATION_HOOKS} /host/old_config + + # Execute custom hooks if present + run_hookdir ${CONFIG_PRE_MIGRATION_HOOKS} ${CONFIG_SETUP_PRE_MIGRATION_FLAG} +} + +# Process switch bootup event +# - Check if it is warm boot and take no further action +# - Perform configuration migration if requested +# - Perform configuration initialization if requested +# - If no saved SONiC configuration is found and ZTP is enabled, +# start ZTP +boot_config() +{ + check_system_warm_boot + if [ -e /tmp/pending_config_migration ] || [ -e ${CONFIG_SETUP_POST_MIGRATION_FLAG} ]; then + do_config_migration + fi + + if [ -e /tmp/pending_config_initialization ] || [ -e ${CONFIG_SETUP_INITIALIZATION_FLAG} ]; then + do_config_intialization + fi + + # If no startup configuration is found, create a configuration to be used + if [ ! -e ${CONFIG_DB_JSON} ]; then + do_config_intialization + # force ZTP to restart + if ztp_is_enabled ; then + ztp_status=$(ztp status -c) + if [ "$ztp_status" = "5:SUCCESS" ] || \ + [ "$ztp_status" = "6:FAILED" ]; then + # Clear completed ztp information, before starting a new one + ztp erase -y + else + touch /tmp/pending_ztp_restart + fi + fi + fi +} + +### Execution starts here ### + +CMD=$1 +# Default command is boot +if [ "$CMD" = "" ] || [ "$CMD" = "help" ] || \ + [ "$CMD" = "-h" ] || [ "$CMD" = "--help" ]; then + usage + exit 1 +fi + +# Process switch bootup event +if [ "$CMD" = "boot" ]; then + boot_config +fi + +# Process factory default configuration creation request +if [ "$CMD" = "factory" ]; then + generate_config factory ${CONFIG_DB_JSON} +fi + +# Take a backup of current configuration +if [ "$CMD" = "backup" ]; then + do_config_backup +fi + +exit 0 diff --git a/files/image_config/updategraph/updategraph b/files/image_config/updategraph/updategraph index 2eb510afa4e1..b2bd027e82e7 100755 --- a/files/image_config/updategraph/updategraph +++ b/files/image_config/updategraph/updategraph @@ -26,32 +26,6 @@ reload_minigraph() fi } -function copy_config_files_and_directories() -{ - for file_dir in $@; do - if [ -f /etc/sonic/old_config/${file_dir} ] || [ -d /etc/sonic/old_config/${file_dir} ]; then - logger "Copying SONiC configuration ${file_dir} ..." - cp -ar /etc/sonic/old_config/${file_dir} /etc/sonic/ - else - logger "Missing SONiC configuration ${file_dir} ..." - fi - done - - sync -} - -function check_system_warm_boot() -{ - SYSTEM_WARM_START=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|system" enable` - # SYSTEM_WARM_START could be empty, always make WARM_BOOT meaningful. - if [[ x"$SYSTEM_WARM_START" == x"true" ]]; then - WARM_BOOT="true" - else - WARM_BOOT="false" - fi -} - - if [ ! -f /etc/sonic/updategraph.conf ]; then echo "No updategraph.conf found, generating a default one." echo "enabled=false" >/etc/sonic/updategraph.conf @@ -59,46 +33,6 @@ fi . /etc/sonic/updategraph.conf -check_system_warm_boot -copy_list="minigraph.xml snmp.yml acl.json config_db.json frr" -if [ -f /tmp/pending_config_migration ]; then - copy_config_files_and_directories $copy_list - if [ x"${WARM_BOOT}" == x"true" ]; then - echo "Warm reboot detected..." - elif [ -r /etc/sonic/config_db.json ]; then - echo "Use config_db.json from old system..." - sonic-cfggen -j /etc/sonic/config_db.json --write-to-db - - if [[ -x /usr/bin/db_migrator.py ]]; then - # Migrate the DB to the latest schema version if needed - /usr/bin/db_migrator.py -o migrate - fi - elif [ -r /etc/sonic/minigraph.xml ]; then - echo "Use minigraph.xml from old system..." - reload_minigraph - sonic-cfggen -d --print-data > /etc/sonic/config_db.json - else - echo "Didn't found neither config_db.json nor minigraph.xml ..." - fi - rm -f /tmp/pending_config_migration - sed -i "/enabled=/d" /etc/sonic/updategraph.conf - echo "enabled=false" >> /etc/sonic/updategraph.conf - exit 0 -fi - -if [ -f /tmp/pending_config_initialization ]; then - rm -f /tmp/pending_config_initialization - if [ "$enabled" != "true" ]; then - PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` - PRESET=(`head -n 1 /usr/share/sonic/device/$PLATFORM/default_sku`) - sonic-cfggen -H -k ${PRESET[0]} --preset ${PRESET[1]} > /etc/sonic/config_db.json - redis-cli -n $CONFIG_DB_INDEX FLUSHDB - sonic-cfggen -j /etc/sonic/config_db.json --write-to-db - redis-cli -n $CONFIG_DB_INDEX SET "CONFIG_DB_INITIALIZED" "1" - exit 0 - fi -fi - if [ "$enabled" = "reload_only" ]; then reload_minigraph sed -i "/enabled=/d" /etc/sonic/updategraph.conf @@ -111,6 +45,12 @@ if [ "$enabled" != "true" ]; then exit 0 fi +# If ZTP package is available and enabled, use ZTP to download and load the graph. +if [ -e /usr/bin/ztp ] && [ "$(ztp status -c)" != "0:DISABLED" ]; then + echo "ZTP is available and enabled. Skipping graph update." + exit 0 +fi + ACL_URL=$acl_src if [ "$src" = "dhcp" ]; then From c883583e208fed93350cf30b8baef8d934e4d1ca Mon Sep 17 00:00:00 2001 From: Tamer Ahmed Date: Tue, 7 Jan 2020 17:48:03 -0800 Subject: [PATCH 003/178] [dhcp-relay]: Add DHCP Relay Monitor (#3886) DHCP relay MONitor (dhcpmon) keeps track of DORA messages. If DHCP Relay is detected to be not forwarding DORA message, dhcpmon will log such event to syslog. Under the hood dhcpmon keeps counts of clients DR messages, forwarded DR messages, DHCP server OA messages, and forwarded OA messages. dhcpmon will check every 12 sec (configurable) if counts are monotonically increasing and record snapshot of those counters. dhcpmon will report discrepancies when detected between current counters and snapshot counters. pull-request: https://github.com/Azure/sonic-buildimage/pull/3886 signed-off-by: Tamer Ahmed --- .gitignore | 6 + .../docker-dhcp-relay.supervisord.conf.j2 | 48 ++ dockers/docker-dhcp-relay/start.sh | 6 + rules/dhcpmon.mk | 8 + rules/docker-dhcp-relay.mk | 2 +- sonic-slave-stretch/Dockerfile.j2 | 5 +- src/dhcpmon/Makefile | 44 ++ src/dhcpmon/debian/changelog | 5 + src/dhcpmon/debian/compat | 1 + src/dhcpmon/debian/control | 16 + src/dhcpmon/debian/rules | 3 + src/dhcpmon/objects.mk | 4 + src/dhcpmon/src/dhcp_device.c | 460 ++++++++++++++++++ src/dhcpmon/src/dhcp_device.h | 113 +++++ src/dhcpmon/src/dhcp_devman.c | 149 ++++++ src/dhcpmon/src/dhcp_devman.h | 76 +++ src/dhcpmon/src/dhcp_mon.c | 199 ++++++++ src/dhcpmon/src/dhcp_mon.h | 54 ++ src/dhcpmon/src/main.c | 174 +++++++ src/dhcpmon/src/subdir.mk | 29 ++ .../docker-dhcp-relay.supervisord.conf | 13 + 21 files changed, 1413 insertions(+), 2 deletions(-) create mode 100644 rules/dhcpmon.mk create mode 100644 src/dhcpmon/Makefile create mode 100644 src/dhcpmon/debian/changelog create mode 100644 src/dhcpmon/debian/compat create mode 100644 src/dhcpmon/debian/control create mode 100755 src/dhcpmon/debian/rules create mode 100644 src/dhcpmon/objects.mk create mode 100644 src/dhcpmon/src/dhcp_device.c create mode 100644 src/dhcpmon/src/dhcp_device.h create mode 100644 src/dhcpmon/src/dhcp_devman.c create mode 100644 src/dhcpmon/src/dhcp_devman.h create mode 100644 src/dhcpmon/src/dhcp_mon.c create mode 100644 src/dhcpmon/src/dhcp_mon.h create mode 100644 src/dhcpmon/src/main.c create mode 100644 src/dhcpmon/src/subdir.mk diff --git a/.gitignore b/.gitignore index 1f921971d8bb..73a99e67854e 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,11 @@ target/ # Subdirectories in src src/bash/* !src/bash/Makefile +src/dhcpmon/debian/* +!src/dhcpmon/debian/changelog +!src/dhcpmon/debian/compat +!src/dhcpmon/debian/control +!src/dhcpmon/debian/rules src/ixgbe/* !src/ixgbe/Makefile src/isc-dhcp/* @@ -104,6 +109,7 @@ src/thrift/* # Autogenerated Dockerfiles sonic-slave/Dockerfile sonic-slave-stretch/Dockerfile +sonic-slave-jessie/Dockerfile dockers/docker-base/Dockerfile dockers/docker-base-stretch/Dockerfile dockers/docker-config-engine/Dockerfile diff --git a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 index e738e8699e6c..94fdbfdaff2f 100644 --- a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 +++ b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 @@ -85,5 +85,53 @@ stderr_logfile=syslog {% endif %} {% endif %} {% endfor %} + +[group:dhcpmon] +programs= +{%- set add_preceding_comma = { 'flag': False } %} +{% for vlan_name in VLAN %} +{% if VLAN[vlan_name]['dhcp_servers'] %} +{% if add_preceding_comma.flag %},{% endif %} +{% set _dummy = add_preceding_comma.update({'flag': True}) %} +dhcpmon-{{ vlan_name }} +{%- endif %} +{% endfor %} + + +{# Create a program entry for each DHCP MONitor instance #} +{% set relay_for_ipv4 = { 'flag': False } %} +{% for vlan_name in VLAN %} +{% if VLAN[vlan_name]['dhcp_servers'] %} +{% for dhcp_server in VLAN[vlan_name]['dhcp_servers'] %} +{% if dhcp_server | ipv4 %} +{% set _dummy = relay_for_ipv4.update({'flag': True}) %} +{% endif %} +{% endfor %} +{% if relay_for_ipv4.flag %} +{% set _dummy = relay_for_ipv4.update({'flag': False}) %} +[program:dhcpmon-{{ vlan_name }}] +{# We treat this VLAN as a downstream interface (-id), as we only want to listen for requests #} +command=/usr/sbin/dhcpmon -id {{ vlan_name }} +{#- We treat all other interfaces as upstream interfaces (-iu), as we only want to listen for replies #} +{% for (name, prefix) in VLAN_INTERFACE|pfx_filter %} +{% if prefix | ipv4 and name != vlan_name %} -iu {{ name }}{% endif -%} +{% endfor %} +{% for (name, prefix) in INTERFACE|pfx_filter %} +{% if prefix | ipv4 %} -iu {{ name }}{% endif -%} +{% endfor %} +{% for (name, prefix) in PORTCHANNEL_INTERFACE|pfx_filter %} +{% if prefix | ipv4 %} -iu {{ name }}{% endif -%} +{% endfor %} + +priority=4 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + +{% endif %} +{% endif %} +{% endfor %} + {% endif %} {% endif %} diff --git a/dockers/docker-dhcp-relay/start.sh b/dockers/docker-dhcp-relay/start.sh index 0ac5ea1a10ec..dbbf32251080 100755 --- a/dockers/docker-dhcp-relay/start.sh +++ b/dockers/docker-dhcp-relay/start.sh @@ -19,3 +19,9 @@ if [ $(supervisorctl status | grep -c "^isc-dhcp-relay:") -gt 0 ]; then # Start all DHCP relay agent(s) supervisorctl start isc-dhcp-relay:* fi + +# If our supervisor config has entries in the "dhcpmon" group... +if [ $(supervisorctl status | grep -c "^dhcpmon:") -gt 0 ]; then + # Start all DHCP Monitor daemon(s) + supervisorctl start dhcpmon:* +fi diff --git a/rules/dhcpmon.mk b/rules/dhcpmon.mk new file mode 100644 index 000000000000..3d80d227c156 --- /dev/null +++ b/rules/dhcpmon.mk @@ -0,0 +1,8 @@ +# SONiC DHCP MONitor package + +SONIC_DHCPMON_VERSION = 1.0.0-0 +SONIC_DHCPMON_PKG_NAME = dhcpmon + +SONIC_DHCPMON = sonic-$(SONIC_DHCPMON_PKG_NAME)_$(SONIC_DHCPMON_VERSION)_$(CONFIGURED_ARCH).deb +$(SONIC_DHCPMON)_SRC_PATH = $(SRC_PATH)/$(SONIC_DHCPMON_PKG_NAME) +SONIC_DPKG_DEBS += $(SONIC_DHCPMON) diff --git a/rules/docker-dhcp-relay.mk b/rules/docker-dhcp-relay.mk index 5aae24ee33b5..8deb6ebbfad7 100644 --- a/rules/docker-dhcp-relay.mk +++ b/rules/docker-dhcp-relay.mk @@ -6,7 +6,7 @@ DOCKER_DHCP_RELAY_DBG = $(DOCKER_DHCP_RELAY_STEM)-$(DBG_IMAGE_MARK).gz $(DOCKER_DHCP_RELAY)_PATH = $(DOCKERS_PATH)/$(DOCKER_DHCP_RELAY_STEM) -$(DOCKER_DHCP_RELAY)_DEPENDS += $(ISC_DHCP_RELAY) $(REDIS_TOOLS) +$(DOCKER_DHCP_RELAY)_DEPENDS += $(ISC_DHCP_RELAY) $(REDIS_TOOLS) $(SONIC_DHCPMON) $(DOCKER_DHCP_RELAY)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) $(DOCKER_DHCP_RELAY)_DBG_DEPENDS += $(ISC_DHCP_RELAY_DBG) diff --git a/sonic-slave-stretch/Dockerfile.j2 b/sonic-slave-stretch/Dockerfile.j2 index 17da5ba9cf19..c5139f1dd6f7 100644 --- a/sonic-slave-stretch/Dockerfile.j2 +++ b/sonic-slave-stretch/Dockerfile.j2 @@ -293,7 +293,10 @@ RUN apt-get update && apt-get install -y \ # For kdump-tools liblzo2-dev \ # For SAI3.7 - libprotobuf-dev + libprotobuf-dev \ +# For DHCP Monitor tool + libexplain-dev \ + libevent-dev # For smartmontools 6.6-1 RUN apt-get -t stretch-backports install -y debhelper diff --git a/src/dhcpmon/Makefile b/src/dhcpmon/Makefile new file mode 100644 index 000000000000..61cde376730b --- /dev/null +++ b/src/dhcpmon/Makefile @@ -0,0 +1,44 @@ +RM := rm -rf +DHCPMON_TARGET := dhcpmon +CP := cp +MKDIR := mkdir +CC := gcc +MV := mv + +# All of the sources participating in the build are defined here +-include src/subdir.mk +-include objects.mk + +ifneq ($(MAKECMDGOALS),clean) +ifneq ($(strip $(C_DEPS)),) +-include $(C_DEPS) +endif +endif + +# Add inputs and outputs from these tool invocations to the build variables + +# All Target +all: sonic-dhcpmon + +# Tool invocations +sonic-dhcpmon: $(OBJS) $(USER_OBJS) + @echo 'Building target: $@' + @echo 'Invoking: GCC C Linker' + $(CC) -o "$(DHCPMON_TARGET)" $(OBJS) $(USER_OBJS) $(LIBS) + @echo 'Finished building target: $@' + @echo ' ' + +# Other Targets +install: + $(MKDIR) -p $(DESTDIR)/usr/sbin + $(MV) $(DHCPMON_TARGET) $(DESTDIR)/usr/sbin + +deinstall: + $(RM) $(DESTDIR)/usr/sbin/$(DHCPMON_TARGET) + $(RM) -rf $(DESTDIR)/usr/sbin + +clean: + -$(RM) $(EXECUTABLES)$(OBJS)$(C_DEPS) $(DHCPMON_TARGET) + -@echo ' ' + +.PHONY: all clean dependents diff --git a/src/dhcpmon/debian/changelog b/src/dhcpmon/debian/changelog new file mode 100644 index 000000000000..83b79d6d93bd --- /dev/null +++ b/src/dhcpmon/debian/changelog @@ -0,0 +1,5 @@ +sonic-dhcpmon (1.0.0-0) UNRELEASED; urgency=medium + + * Initial release. + + -- Tamer Ahmed Mon, 09 Dec 2019 12:00:00 -0700 diff --git a/src/dhcpmon/debian/compat b/src/dhcpmon/debian/compat new file mode 100644 index 000000000000..ec635144f600 --- /dev/null +++ b/src/dhcpmon/debian/compat @@ -0,0 +1 @@ +9 diff --git a/src/dhcpmon/debian/control b/src/dhcpmon/debian/control new file mode 100644 index 000000000000..2f05fda79963 --- /dev/null +++ b/src/dhcpmon/debian/control @@ -0,0 +1,16 @@ +Source: sonic-dhcpmon +Section: devel +Priority: optional +Maintainer: Tamer Ahmed +Build-Depends: debhelper (>= 8.0.0), + dh-systemd +Standards-Version: 3.9.3 +Homepage: https://github.com/Azure/sonic-buildimage +XS-Go-Import-Path: github.com/Azure/sonic-buildimage + +Package: sonic-dhcpmon +Architecture: any +Built-Using: ${misc:Built-Using} +Depends: libexplain51, + libevent-2.0-5 +Description: SONiC DHCP Monitor diff --git a/src/dhcpmon/debian/rules b/src/dhcpmon/debian/rules new file mode 100755 index 000000000000..3995a26d7fcd --- /dev/null +++ b/src/dhcpmon/debian/rules @@ -0,0 +1,3 @@ +#!/usr/bin/make -f +%: + dh $@ --with systemd diff --git a/src/dhcpmon/objects.mk b/src/dhcpmon/objects.mk new file mode 100644 index 000000000000..c9b774a53921 --- /dev/null +++ b/src/dhcpmon/objects.mk @@ -0,0 +1,4 @@ +USER_OBJS := + +LIBS := -levent -lexplain + diff --git a/src/dhcpmon/src/dhcp_device.c b/src/dhcpmon/src/dhcp_device.c new file mode 100644 index 000000000000..aa0c0f835cbd --- /dev/null +++ b/src/dhcpmon/src/dhcp_device.c @@ -0,0 +1,460 @@ +/** + * @file dhcp_device.c + * + * device (interface) module + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dhcp_device.h" + +/** Start of Ether header of a captured frame */ +#define ETHER_START_OFFSET 0 +/** Start of IP header of a captured frame */ +#define IP_START_OFFSET (ETHER_START_OFFSET + ETHER_HDR_LEN) +/** Start of UDP header of a captured frame */ +#define UDP_START_OFFSET (IP_START_OFFSET + sizeof(struct ip)) +/** Start of DHCP header of a captured frame */ +#define DHCP_START_OFFSET (UDP_START_OFFSET + sizeof(struct udphdr)) +/** Start of DHCP Options segment of a captured frame */ +#define DHCP_OPTIONS_HEADER_SIZE 240 + +#define OP_LDHA (BPF_LD | BPF_H | BPF_ABS) /** bpf ldh Abs */ +#define OP_LDHI (BPF_LD | BPF_H | BPF_IND) /** bpf ldh Ind */ +#define OP_LDB (BPF_LD | BPF_B | BPF_ABS) /** bpf ldb Abs*/ +#define OP_JEQ (BPF_JMP | BPF_JEQ | BPF_K) /** bpf jeq */ +#define OP_JGT (BPF_JMP | BPF_JGT | BPF_K) /** bpf jgt */ +#define OP_RET (BPF_RET | BPF_K) /** bpf ret */ +#define OP_JSET (BPF_JMP | BPF_JSET | BPF_K) /** bpf jset */ +#define OP_LDXB (BPF_LDX | BPF_B | BPF_MSH) /** bpf ldxb */ + +/** Berkley Packet Fitler program for "udp and (port 67 or port 68)". This program is obtained suing the following + * tcpdump command: 'tcpdump -dd "udp and (port 67 or port 68)"' + */ +static struct sock_filter dhcp_bpf_code[] = { + {.code = OP_LDHA, .jt = 0, .jf = 0, .k = 0x0000000c}, // (000) ldh [12] + {.code = OP_JEQ, .jt = 0, .jf = 7, .k = 0x000086dd}, // (001) jeq #0x86dd jt 2 jf 9 + {.code = OP_LDB, .jt = 0, .jf = 0, .k = 0x00000014}, // (002) ldb [20] + {.code = OP_JEQ, .jt = 0, .jf = 18, .k = 0x00000011}, // (003) jeq #0x11 jt 4 jf 22 + {.code = OP_LDHA, .jt = 0, .jf = 0, .k = 0x00000036}, // (004) ldh [54] + {.code = OP_JEQ, .jt = 15, .jf = 0, .k = 0x00000043}, // (005) jeq #0x43 jt 21 jf 6 + {.code = OP_JEQ, .jt = 14, .jf = 0, .k = 0x00000044}, // (006) jeq #0x44 jt 21 jf 7 + {.code = OP_LDHA, .jt = 0, .jf = 0, .k = 0x00000038}, // (007) ldh [56] + {.code = OP_JEQ, .jt = 12, .jf = 11, .k = 0x00000043}, // (008) jeq #0x43 jt 21 jf 20 + {.code = OP_JEQ, .jt = 0, .jf = 12, .k = 0x00000800}, // (009) jeq #0x800 jt 10 jf 22 + {.code = OP_LDB, .jt = 0, .jf = 0, .k = 0x00000017}, // (010) ldb [23] + {.code = OP_JEQ, .jt = 0, .jf = 10, .k = 0x00000011}, // (011) jeq #0x11 jt 12 jf 22 + {.code = OP_LDHA, .jt = 0, .jf = 0, .k = 0x00000014}, // (012) ldh [20] + {.code = OP_JSET, .jt = 8, .jf = 0, .k = 0x00001fff}, // (013) jset #0x1fff jt 22 jf 14 + {.code = OP_LDXB, .jt = 0, .jf = 0, .k = 0x0000000e}, // (014) ldxb 4*([14]&0xf) + {.code = OP_LDHI, .jt = 0, .jf = 0, .k = 0x0000000e}, // (015) ldh [x + 14] + {.code = OP_JEQ, .jt = 4, .jf = 0, .k = 0x00000043}, // (016) jeq #0x43 jt 21 jf 17 + {.code = OP_JEQ, .jt = 3, .jf = 0, .k = 0x00000044}, // (017) jeq #0x44 jt 21 jf 18 + {.code = OP_LDHI, .jt = 0, .jf = 0, .k = 0x00000010}, // (018) ldh [x + 16] + {.code = OP_JEQ, .jt = 1, .jf = 0, .k = 0x00000043}, // (019) jeq #0x43 jt 21 jf 20 + {.code = OP_JEQ, .jt = 0, .jf = 1, .k = 0x00000044}, // (020) jeq #0x44 jt 21 jf 22 + {.code = OP_RET, .jt = 0, .jf = 0, .k = 0x00040000}, // (021) ret #262144 + {.code = OP_RET, .jt = 0, .jf = 0, .k = 0x00000000}, // (022) ret #0 +}; + +/** Filter program socket struct */ +static struct sock_fprog dhcp_sock_bfp = { + .len = sizeof(dhcp_bpf_code) / sizeof(*dhcp_bpf_code), .filter = dhcp_bpf_code +}; + +/** global aggregate counter for DHCP interfaces */ +static dhcp_device_counters_t glob_counters[DHCP_DIR_COUNT] = { + [DHCP_RX] = {.discover = 0, .offer = 0, .request = 0, .ack = 0}, + [DHCP_TX] = {.discover = 0, .offer = 0, .request = 0, .ack = 0}, +}; + +/** global aggregate counter snapshot for DHCP interfaces */ +static dhcp_device_counters_t glob_counters_snapshot[DHCP_DIR_COUNT] = { + [DHCP_RX] = {.discover = 0, .offer = 0, .request = 0, .ack = 0}, + [DHCP_TX] = {.discover = 0, .offer = 0, .request = 0, .ack = 0}, +}; + +/** + * @code handle_dhcp_option_53(context, dhcp_option, dir); + * + * @brief handle the logic related to DHCP option 53 + * + * @param context Device (interface) context + * @param dhcp_option pointer to DHCP option buffer space + * @param dir packet direction + * + * @return none + */ +static void handle_dhcp_option_53(dhcp_device_context_t *context, const u_char *dhcp_option, dhcp_packet_direction_t dir) +{ + switch (dhcp_option[2]) + { + case 1: + context->counters[dir].discover++; + if ((context->is_uplink && dir == DHCP_TX) || (!context->is_uplink && dir == DHCP_RX)) { + glob_counters[dir].discover++; + } + break; + case 2: + context->counters[dir].offer++; + if ((!context->is_uplink && dir == DHCP_TX) || (context->is_uplink && dir == DHCP_RX)) { + glob_counters[dir].offer++; + } + break; + case 3: + context->counters[dir].request++; + if ((context->is_uplink && dir == DHCP_TX) || (!context->is_uplink && dir == DHCP_RX)) { + glob_counters[dir].request++; + } + break; + case 5: + context->counters[dir].ack++; + if ((!context->is_uplink && dir == DHCP_TX) || (context->is_uplink && dir == DHCP_RX)) { + glob_counters[dir].ack++; + } + break; + case 4: // type: Decline + case 6 ... 8: + // type: NAK, Release, Inform + break; + default: + syslog(LOG_WARNING, "handle_dhcp_option_53(%s): Unknown DHCP option 53 type %d", context->intf, dhcp_option[2]); + break; + } +} + +/** + * @code read_callback(fd, event, arg); + * + * @brief callback for libevent which is called every time out in order to read queued packet capture + * + * @param fd socket to read from + * @param event libevent triggered event + * @param arg user provided argument for callback (interface context) + * @param packet pointer to packet data + * + * @return none + */ +static void read_callback(int fd, short event, void *arg) +{ + dhcp_device_context_t *context = (dhcp_device_context_t*) arg; + ssize_t buffer_sz; + + while ((event == EV_READ) && + ((buffer_sz = recv(fd, context->buffer, context->snaplen, MSG_DONTWAIT)) > 0)) { + struct ether_header *ethhdr = (struct ether_header*) context->buffer; + struct udphdr *udp = (struct udphdr*) (context->buffer + UDP_START_OFFSET); + int dhcp_option_offset = DHCP_START_OFFSET + DHCP_OPTIONS_HEADER_SIZE; + + if ((buffer_sz > UDP_START_OFFSET + sizeof(struct udphdr) + DHCP_OPTIONS_HEADER_SIZE) && + (ntohs(udp->len) > DHCP_OPTIONS_HEADER_SIZE)) { + int dhcp_sz = ntohs(udp->len) < buffer_sz - UDP_START_OFFSET - sizeof(struct udphdr) ? + ntohs(udp->len) : buffer_sz - UDP_START_OFFSET - sizeof(struct udphdr); + int dhcp_option_sz = dhcp_sz - DHCP_OPTIONS_HEADER_SIZE; + const u_char *dhcp_option = context->buffer + dhcp_option_offset; + dhcp_packet_direction_t dir = (ethhdr->ether_shost[0] == context->mac[0] && + ethhdr->ether_shost[1] == context->mac[1] && + ethhdr->ether_shost[2] == context->mac[2] && + ethhdr->ether_shost[3] == context->mac[3] && + ethhdr->ether_shost[4] == context->mac[4] && + ethhdr->ether_shost[5] == context->mac[5]) ? + DHCP_TX : DHCP_RX; + int offset = 0; + int stop_dhcp_processing = 0; + while ((offset < (dhcp_option_sz + 1)) && dhcp_option[offset] != 255) { + switch (dhcp_option[offset]) + { + case 53: + if (offset < (dhcp_option_sz + 2)) { + handle_dhcp_option_53(context, &dhcp_option[offset], dir); + } + stop_dhcp_processing = 1; // break while loop since we are only interested in Option 53 + break; + default: + break; + } + + if (stop_dhcp_processing == 1) { + break; + } + + if (dhcp_option[offset] == 0) { // DHCP Option Padding + offset++; + } else { + offset += dhcp_option[offset + 1] + 2; + } + } + } else { + syslog(LOG_WARNING, "read_callback(%s): read length (%ld) is too small to capture DHCP options", + context->intf, buffer_sz); + } + } +} + +/** + * @code dhcp_device_validate(counters, counters_snapshot); + * + * @brief validate current interface counters by comparing aggregate counter with snapshot counters. + * + * @param counters recent interface counter + * @param counters_snapshot snapshot counters + * + * @return DHCP_MON_STATUS_HEALTHY, DHCP_MON_STATUS_UNHEALTHY, or DHCP_MON_STATUS_INDETERMINATE + */ +static dhcp_mon_status_t dhcp_device_validate(dhcp_device_counters_t *counters, + dhcp_device_counters_t *counters_snapshot) +{ + dhcp_mon_status_t rv = DHCP_MON_STATUS_HEALTHY; + + if ((counters[DHCP_RX].discover == counters_snapshot[DHCP_RX].discover) && + (counters[DHCP_RX].offer == counters_snapshot[DHCP_RX].offer ) && + (counters[DHCP_RX].request == counters_snapshot[DHCP_RX].request ) && + (counters[DHCP_RX].ack == counters_snapshot[DHCP_RX].ack ) ) { + rv = DHCP_MON_STATUS_INDETERMINATE; + } else { + // if we have rx DORA then we should have corresponding tx DORA (DORA being relayed) + if (((counters[DHCP_RX].discover > counters_snapshot[DHCP_RX].discover) && + (counters[DHCP_TX].discover <= counters_snapshot[DHCP_TX].discover) ) || + ((counters[DHCP_RX].offer > counters_snapshot[DHCP_RX].offer ) && + (counters[DHCP_TX].offer <= counters_snapshot[DHCP_TX].offer ) ) || + ((counters[DHCP_RX].request > counters_snapshot[DHCP_RX].request ) && + (counters[DHCP_TX].request <= counters_snapshot[DHCP_TX].request ) ) || + ((counters[DHCP_RX].ack > counters_snapshot[DHCP_RX].ack ) && + (counters[DHCP_TX].ack <= counters_snapshot[DHCP_TX].ack ) ) ) { + rv = DHCP_MON_STATUS_UNHEALTHY; + } + } + + return rv; +} + +/** + * @code dhcp_print_counters(counters); + * + * @brief prints DHCP counters to sylsog. + * + * @param counters interface counter + */ +static void dhcp_print_counters(dhcp_device_counters_t *counters) +{ + syslog(LOG_NOTICE, "DHCP Discover rx: %lu, tx:%lu, Offer rx: %lu, tx:%lu, Request rx: %lu, tx:%lu, ACK rx: %lu, tx:%lu\n", + counters[DHCP_RX].discover, counters[DHCP_TX].discover, + counters[DHCP_RX].offer, counters[DHCP_TX].offer, + counters[DHCP_RX].request, counters[DHCP_TX].request, + counters[DHCP_RX].ack, counters[DHCP_TX].ack); +} + +/** + * @code init_socket(context, intf, snaplen, base); + * + * @brief initializes socket, bind it to interface and bpf prgram, and + * associate with libevent base + * + * @param context pointer to device (interface) context + * @param intf interface name + * @param snaplen length of packet capture + * @param base libevent base + * + * @return 0 on success, otherwise for failure + */ +static int init_socket(dhcp_device_context_t *context, + const char *intf, + size_t snaplen, + struct event_base *base) +{ + int rv = -1; + + do { + if (snaplen < UDP_START_OFFSET + sizeof(struct udphdr) + DHCP_OPTIONS_HEADER_SIZE) { + syslog(LOG_ALERT, "init_socket(%s): snap length is too low to capture DHCP options", intf); + break; + } + + context->sock = socket(AF_PACKET, SOCK_RAW | SOCK_NONBLOCK, htons(ETH_P_ALL)); + if (context->sock < 0) { + syslog(LOG_ALERT, "socket: failed to open socket with '%s'\n", strerror(errno)); + break; + } + + struct sockaddr_ll addr; + memset(&addr, 0, sizeof(addr)); + addr.sll_ifindex = if_nametoindex(intf); + addr.sll_family = AF_PACKET; + addr.sll_protocol = htons(ETH_P_ALL); + if (bind(context->sock, (struct sockaddr *) &addr, sizeof(addr))) { + syslog(LOG_ALERT, "bind: failed to bind to interface '%s' with '%s'\n", intf, strerror(errno)); + break; + } + + if (setsockopt(context->sock, SOL_SOCKET, SO_ATTACH_FILTER, &dhcp_sock_bfp, sizeof(dhcp_sock_bfp)) != 0) { + syslog(LOG_ALERT, "setsockopt: failed to attach filter with '%s'\n", strerror(errno)); + break; + } + + context->buffer = (uint8_t *) malloc(snaplen); + if (context->buffer == NULL) { + syslog(LOG_ALERT, "malloc: failed to allocate memory for socket buffer '%s'\n", strerror(errno)); + break; + } + context->snaplen = snaplen; + + struct event *ev = event_new(base, context->sock, EV_READ | EV_PERSIST, read_callback, context); + if (ev == NULL) { + syslog(LOG_ALERT, "event_new: failed to allocate memory for libevent event '%s'\n", strerror(errno)); + break; + } + event_add(ev, NULL); + + strncpy(context->intf, intf, sizeof(context->intf) - 1); + context->intf[sizeof(context->intf) - 1] = '\0'; + + rv = 0; + } while (0); + + return rv; +} + +/** + * @code initialize_intf_mac_and_ip_addr(context); + * + * @brief initializes device (interface) mac/ip addresses + * + * @param context pointer to device (interface) context + * + * @return 0 on success, otherwise for failure + */ +static int initialize_intf_mac_and_ip_addr(dhcp_device_context_t *context) +{ + int rv = -1; + + do { + int fd; + struct ifreq ifr; + if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { + syslog(LOG_ALERT, "socket: %s", strerror(errno)); + break; + } + + ifr.ifr_addr.sa_family = AF_INET; + strncpy(ifr.ifr_name, context->intf, sizeof(ifr.ifr_name) - 1); + ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0'; + + // Get network address + if (ioctl(fd, SIOCGIFADDR, &ifr) == -1) { + syslog(LOG_ALERT, "ioctl: %s", explain_ioctl(fd, SIOCGIFADDR, &ifr)); + break; + } + context->ip = ((struct sockaddr_in*) &ifr.ifr_addr)->sin_addr.s_addr; + + // Get mac address + if (ioctl(fd, SIOCGIFHWADDR, &ifr) == -1) { + syslog(LOG_ALERT, "ioctl: %s", explain_ioctl(fd, SIOCGIFHWADDR, &ifr)); + break; + } + memcpy(context->mac, ifr.ifr_hwaddr.sa_data, sizeof(context->mac)); + + close(fd); + + rv = 0; + } while (0); + + return rv; +} + +/** + * @code dhcp_device_init(context, intf, snaplen, is_uplink, base); + * + * @brief initializes device (interface) that handles packet capture per interface. + */ +int dhcp_device_init(dhcp_device_context_t **context, + const char *intf, + int snaplen, + uint8_t is_uplink, + struct event_base *base) +{ + int rv = -1; + dhcp_device_context_t *dev_context = NULL; + + if ((context != NULL) && (strlen(intf) < sizeof(dev_context->intf))) { + + dev_context = (dhcp_device_context_t *) malloc(sizeof(dhcp_device_context_t)); + if (dev_context != NULL) { + if ((init_socket(dev_context, intf, snaplen, base) == 0) && + (initialize_intf_mac_and_ip_addr(dev_context) == 0 ) ) { + + dev_context->is_uplink = is_uplink; + + memset(&dev_context->counters, 0, sizeof(dev_context->counters)); + memset(&dev_context->counters_snapshot, 0, sizeof(dev_context->counters_snapshot)); + + *context = dev_context; + rv = 0; + } + } + else { + syslog(LOG_ALERT, "malloc: failed to allocated device context memory for '%s'", dev_context->intf); + } + } + + return rv; +} + +/** + * @code dhcp_device_shutdown(context); + * + * @brief shuts down device (interface). Also, stops packet capture on interface and cleans up any allocated memory + */ +void dhcp_device_shutdown(dhcp_device_context_t *context) +{ + free(context); +} + +/** + * @code dhcp_device_get_status(context); + * + * @brief collects DHCP relay status info for a given interface. If context is null, it will report aggregate + * status + */ +dhcp_mon_status_t dhcp_device_get_status(dhcp_device_context_t *context) +{ + dhcp_mon_status_t rv = 0; + + if (context != NULL) { + rv = dhcp_device_validate(context->counters, context->counters_snapshot); + memcpy(context->counters_snapshot, context->counters, sizeof(context->counters_snapshot)); + } else { + rv = dhcp_device_validate(glob_counters, glob_counters_snapshot); + memcpy(glob_counters_snapshot, glob_counters, sizeof(glob_counters_snapshot)); + } + + return rv; +} + +/** + * @code dhcp_device_print_status(); + * + * @brief prints status counters to syslog. If context is null, it will print aggregate status + */ +void dhcp_device_print_status(dhcp_device_context_t *context) +{ + if (context != NULL) { + dhcp_print_counters(context->counters); + } else { + dhcp_print_counters(glob_counters); + } +} diff --git a/src/dhcpmon/src/dhcp_device.h b/src/dhcpmon/src/dhcp_device.h new file mode 100644 index 000000000000..04113eeabdc0 --- /dev/null +++ b/src/dhcpmon/src/dhcp_device.h @@ -0,0 +1,113 @@ +/** + * @file dhcp_device.h + * + * device (interface) module + */ + +#ifndef DHCP_DEVICE_H_ +#define DHCP_DEVICE_H_ + +#include +#include +#include +#include + +#include +#include +#include + + +/** packet direction */ +typedef enum +{ + DHCP_RX, /** RX DHCP packet */ + DHCP_TX, /** TX DHCP packet */ + + DHCP_DIR_COUNT +} dhcp_packet_direction_t; + +/** dhcp health status */ +typedef enum +{ + DHCP_MON_STATUS_HEALTHY, /** DHCP relay is healthy */ + DHCP_MON_STATUS_UNHEALTHY, /** DHCP relay is unhealthy and is missing out on some packets */ + DHCP_MON_STATUS_INDETERMINATE, /** DHCP relay health could not be determined */ +} dhcp_mon_status_t; + +/** DHCP device (interface) health counters */ +typedef struct +{ + uint64_t discover; /** DHCP discover packets */ + uint64_t offer; /** DHCP offer packets */ + uint64_t request; /** DHCP request packets */ + uint64_t ack; /** DHCP ack packets */ +} dhcp_device_counters_t; + +/** DHCP device (interface) context */ +typedef struct +{ + int sock; /** Raw socket associated with this device/interface */ + in_addr_t ip; /** network address of this device (interface) */ + uint8_t mac[ETHER_ADDR_LEN]; /** hardware address of this device (interface) */ + uint8_t is_uplink; /** north interface? */ + char intf[IF_NAMESIZE]; /** device (interface) name */ + uint8_t *buffer; /** buffer used to read socket data */ + size_t snaplen; /** snap length or buffer size */ + dhcp_device_counters_t counters[DHCP_DIR_COUNT]; + /** current coutners of DORA packets */ + dhcp_device_counters_t counters_snapshot[DHCP_DIR_COUNT]; + /** counter snapshot */ +} dhcp_device_context_t; + +/** + * @code dhcp_device_init(context, intf, snaplen, timeout_ms, is_uplink, base); + * + * @brief initializes device (interface) that handles packet capture per interface. + * + * @param context(inout) pointer to device (interface) context + * @param intf interface name + * @param snaplen length of packet capture + * @param is_uplink uplink interface + * @param base pointer to libevent base + * + * @return 0 on success, otherwise for failure + */ +int dhcp_device_init(dhcp_device_context_t **context, + const char *intf, + int snaplen, + uint8_t is_uplink, + struct event_base *base); + +/** + * @code dhcp_device_shutdown(context); + * + * @brief shuts down device (interface). Also, stops packet capture on interface and cleans up any allocated memory + * + * @param context Device (interface) context + * + * @return nonedhcp_device_shutdown + */ +void dhcp_device_shutdown(dhcp_device_context_t *context); + +/** + * @code dhcp_device_get_status(context); + * + * @brief collects DHCP relay status info for a given interface. If context is null, it will report aggregate + * status + * + * @param context Device (interface) context + * + * @return DHCP_MON_STATUS_HEALTHY, DHCP_MON_STATUS_UNHEALTHY, or DHCP_MON_STATUS_INDETERMINATE + */ +dhcp_mon_status_t dhcp_device_get_status(dhcp_device_context_t *context); + +/** + * @code dhcp_device_print_status(); + * + * @brief prints status counters to syslog. If context is null, it will print aggregate status + * + * @return none + */ +void dhcp_device_print_status(dhcp_device_context_t *context); + +#endif /* DHCP_DEVICE_H_ */ diff --git a/src/dhcpmon/src/dhcp_devman.c b/src/dhcpmon/src/dhcp_devman.c new file mode 100644 index 000000000000..c19cbde591b8 --- /dev/null +++ b/src/dhcpmon/src/dhcp_devman.c @@ -0,0 +1,149 @@ +/** + * @file dhcp_devman.c + * + * Device (interface) manager + */ +#include +#include +#include +#include +#include +#include + +#include "dhcp_devman.h" + +/** struct for interface information */ +struct intf +{ + const char *name; /** interface name */ + uint8_t is_uplink; /** is uplink (north) interface */ + dhcp_device_context_t *dev_context; /** device (interface_ context */ + LIST_ENTRY(intf) entry; /** list link/pointers entries */ +}; + +/** intfs list of interfaces */ +static LIST_HEAD(intf_list, intf) intfs; +/** dhcp_num_south_intf number of south interfaces */ +static uint32_t dhcp_num_south_intf = 0; +/** dhcp_num_north_intf number of north interfaces */ +static uint32_t dhcp_num_north_intf = 0; + +/** + * @code dhcp_devman_init(); + * + * initializes device (interface) manager that keeps track of interfaces and assert that there is one south + * interface and as many north interfaces + */ +void dhcp_devman_init() +{ + LIST_INIT(&intfs); +} + +/** + * @code dhcp_devman_shutdown(); + * + * shuts down device (interface) manager. Also, stops packet capture on interface and cleans up any allocated + * memory + */ +void dhcp_devman_shutdown() +{ + struct intf *int_ptr, *prev_intf = NULL; + + LIST_FOREACH(int_ptr, &intfs, entry) { + dhcp_device_shutdown(int_ptr->dev_context); + if (prev_intf) { + LIST_REMOVE(prev_intf, entry); + free(prev_intf); + prev_intf = int_ptr; + } + } + + if (prev_intf) { + LIST_REMOVE(prev_intf, entry); + free(prev_intf); + } +} + +/** + * @code dhcp_devman_add_intf(name, uplink); + * + * @brief adds interface to the device manager. + */ +int dhcp_devman_add_intf(const char *name, uint8_t is_uplink) +{ + int rv = -1; + struct intf *dev = malloc(sizeof(struct intf)); + + if (dev != NULL) { + dev->name = name; + dev->is_uplink = is_uplink; + if (is_uplink) { + dhcp_num_north_intf++; + } else { + dhcp_num_south_intf++; + assert(dhcp_num_south_intf <= 1); + } + + LIST_INSERT_HEAD(&intfs, dev, entry); + + rv = 0; + } + else { + syslog(LOG_ALERT, "malloc: failed to allocate memory for intf '%s'\n", name); + } + + return rv; +} + +/** + * @code dhcp_devman_start_capture(snaplen, base); + * + * @brief start packet capture on the devman interface list + */ +int dhcp_devman_start_capture(int snaplen, struct event_base *base) +{ + int rv = -1; + struct intf *int_ptr; + + if ((dhcp_num_south_intf == 1) && (dhcp_num_north_intf >= 1)) { + LIST_FOREACH(int_ptr, &intfs, entry) { + rv = dhcp_device_init(&int_ptr->dev_context, int_ptr->name, snaplen, int_ptr->is_uplink, base); + if (rv == 0) { + syslog(LOG_INFO, + "Capturing DHCP packets on interface %s, ip: 0x%08x, mac [%02x:%02x:%02x:%02x:%02x:%02x] \n", + int_ptr->name, int_ptr->dev_context->ip, int_ptr->dev_context->mac[0], + int_ptr->dev_context->mac[1], int_ptr->dev_context->mac[2], int_ptr->dev_context->mac[3], + int_ptr->dev_context->mac[4], int_ptr->dev_context->mac[5]); + } + else { + break; + } + } + } + else { + syslog(LOG_ERR, "Invalid number of interfaces, downlink/south %d, uplink/north %d\n", + dhcp_num_south_intf, dhcp_num_north_intf); + } + + return rv; +} + +/** + * @code dhcp_devman_get_status(); + * + * @brief collects DHCP relay status info. + */ +dhcp_mon_status_t dhcp_devman_get_status() +{ + return dhcp_device_get_status(NULL); +} + +/** + * @code dhcp_devman_print_status(); + * + * @brief prints status counters to syslog + */ +void dhcp_devman_print_status() +{ + dhcp_device_print_status(NULL); +} diff --git a/src/dhcpmon/src/dhcp_devman.h b/src/dhcpmon/src/dhcp_devman.h new file mode 100644 index 000000000000..a0753b4b93a1 --- /dev/null +++ b/src/dhcpmon/src/dhcp_devman.h @@ -0,0 +1,76 @@ +/** + * @file dhcp_devman.h + * + * Device (interface) manager + */ + +#ifndef DHCP_DEVMAN_H_ +#define DHCP_DEVMAN_H_ + +#include + +#include "dhcp_device.h" + +/** + * @code dhcp_devman_init(); + * + * @brief initializes device (interface) manager that keeps track of interfaces and assert that there is one south + * interface and as many north interfaces + * + * @return none + */ +void dhcp_devman_init(); + +/** + * @code dhcp_devman_shutdown(); + * + * @brief shuts down device (interface) manager. Also, stops packet capture on interface and cleans up any allocated + * memory + * + * @return none + */ +void dhcp_devman_shutdown(); + +/** + * @code dhcp_devman_add_intf(name, uplink); + * + * @brief adds interface to the device manager. + * + * @param name interface name + * @param is_uplink true for uplink (north) interface + * + * @return 0 on success, nonzero otherwise + */ +int dhcp_devman_add_intf(const char *name, uint8_t is_uplink); + +/** + * @code dhcp_devman_start_capture(snaplen, timeout_ms); + * + * @brief start packet capture on the devman interface list + * + * @param snaplen packet capture snap length + * @param base libevent base + * + * @return 0 on success, nonzero otherwise + */ +int dhcp_devman_start_capture(int snaplen, struct event_base *base); + +/** + * @code dhcp_devman_get_status(); + * + * @brief collects DHCP relay status info. + * + * @return DHCP_MON_STATUS_HEALTHY, DHCP_MON_STATUS_UNHEALTHY, or DHCP_MON_STATUS_INDETERMINATE + */ +dhcp_mon_status_t dhcp_devman_get_status(); + +/** + * @code dhcp_devman_print_status(); + * + * @brief prints status counters to syslog + * + * @return none + */ +void dhcp_devman_print_status(); + +#endif /* DHCP_DEVMAN_H_ */ diff --git a/src/dhcpmon/src/dhcp_mon.c b/src/dhcpmon/src/dhcp_mon.c new file mode 100644 index 000000000000..dc0a7d94f149 --- /dev/null +++ b/src/dhcpmon/src/dhcp_mon.c @@ -0,0 +1,199 @@ +/** + * @file dhcp_mon.c + * + * @brief dhcp relay monitor module + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dhcp_mon.h" +#include "dhcp_devman.h" + +/** window_interval_sec monitoring window for dhcp relay health checks */ +static int window_interval_sec = 12; +/** dhcp_unhealthy_max_count max count of consecutive unhealthy statuses before reporting to syslog */ +static int dhcp_unhealthy_max_count = 10; +/** libevent base struct */ +static struct event_base *base; +/** libevent timeout event struct */ +static struct event *ev_timeout = NULL; +/** libevent SIGINT signal event struct */ +static struct event *ev_sigint; +/** libevent SIGTERM signal event struct */ +static struct event *ev_sigterm; + +/** + * @code signal_callback(fd, event, arg); + * + * @brief signal handler for dhcpmon. It will initiate shutdown when signal is caught + * + * @param fd libevent socket + * @param event event triggered + * @param arg pointer user provided context (libevent base) + * + * @return none + */ +static void signal_callback(evutil_socket_t fd, short event, void *arg) +{ + syslog(LOG_ALERT, "Received signal %d\n", event); + dhcp_devman_print_status(); + dhcp_mon_stop(); +} + +/** + * @code timeout_callback(fd, event, arg); + * + * @brief periodic timer call back + * + * @param fd libevent socket + * @param event event triggered + * @param arg pointer user provided context (libevent base) + * + * @return none + */ +static void timeout_callback(evutil_socket_t fd, short event, void *arg) +{ + static int count = 0; + dhcp_mon_status_t dhcp_mon_status = dhcp_devman_get_status(); + + switch (dhcp_mon_status) + { + case DHCP_MON_STATUS_UNHEALTHY: + if (++count > dhcp_unhealthy_max_count) { + syslog(LOG_ALERT, "DHCP Relay is not healthy after %d health checks\n", count); + } + break; + case DHCP_MON_STATUS_HEALTHY: + if (count > 0) { + count = 0; + } + break; + case DHCP_MON_STATUS_INDETERMINATE: + break; + default: + syslog(LOG_ERR, "DHCP Relay returned unknown status %d\n", dhcp_mon_status); + break; + } +} + +/** + * @code dhcp_mon_init(window_sec, max_count); + * + * initializes event base and periodic timer event that continuously collects dhcp relay health status every window_sec + * seconds. It also writes to syslog when dhcp relay has been unhealthy for consecutive max_count checks. + * + */ +int dhcp_mon_init(int window_sec, int max_count) +{ + int rv = -1; + + do { + window_interval_sec = window_sec; + dhcp_unhealthy_max_count = max_count; + + base = event_base_new(); + if (base == NULL) { + syslog(LOG_ERR, "Could not initialize libevent!\n"); + break; + } + + ev_sigint = evsignal_new(base, SIGINT, signal_callback, base); + if (ev_sigint == NULL) { + syslog(LOG_ERR, "Could not create SIGINT libevent signal!\n"); + break; + } + + ev_sigterm = evsignal_new(base, SIGTERM, signal_callback, base); + if (ev_sigterm == NULL) { + syslog(LOG_ERR, "Could not create SIGTERM libevent signal!\n"); + break; + } + + ev_timeout = event_new(base, -1, EV_PERSIST, timeout_callback, base); + if (ev_timeout == NULL) { + syslog(LOG_ERR, "Could not create libevent timer!\n"); + break; + } + + rv = 0; + } while (0); + + return rv; +} + +/** + * @code dhcp_mon_shutdown(); + * + * @brief shuts down libevent loop + */ +void dhcp_mon_shutdown() +{ + event_del(ev_timeout); + event_del(ev_sigint); + event_del(ev_sigterm); + + event_free(ev_timeout); + event_free(ev_sigint); + event_free(ev_sigterm); + + event_base_free(base); +} + +/** + * @code dhcp_mon_start(snaplen); + * + * @brief start monitoring DHCP Relay + */ +int dhcp_mon_start(int snaplen) +{ + int rv = -1; + + do + { + if (dhcp_devman_start_capture(snaplen, base) != 0) { + break; + } + + if (evsignal_add(ev_sigint, NULL) != 0) { + syslog(LOG_ERR, "Could not add SIGINT libevent signal!\n"); + break; + } + + if (evsignal_add(ev_sigterm, NULL) != 0) { + syslog(LOG_ERR, "Could not add SIGTERM libevent signal!\n"); + break; + } + + struct timeval event_time = {.tv_sec = window_interval_sec, .tv_usec = 0}; + if (evtimer_add(ev_timeout, &event_time) != 0) { + syslog(LOG_ERR, "Could not add event timer to libevent!\n"); + break; + } + + if (event_base_dispatch(base) != 0) { + syslog(LOG_ERR, "Could not start libevent dispatching loop!\n"); + break; + } + + rv = 0; + } while (0); + + return rv; +} + +/** + * @code dhcp_mon_stop(); + * + * @brief stop monitoring DHCP Relay + */ +void dhcp_mon_stop() +{ + event_base_loopexit(base, NULL); +} diff --git a/src/dhcpmon/src/dhcp_mon.h b/src/dhcpmon/src/dhcp_mon.h new file mode 100644 index 000000000000..44d361b32ec0 --- /dev/null +++ b/src/dhcpmon/src/dhcp_mon.h @@ -0,0 +1,54 @@ +/** + * @file dhcp_mon.h + * + * @brief dhcp relay monitor module + * + */ + +#ifndef DHCP_MON_H_ +#define DHCP_MON_H_ + +/** + * @code dhcp_mon_init(window_ssec, max_count); + * + * @brief initializes event base and periodic timer event that continuously collects dhcp relay health status every + * window_sec seconds. It also writes to syslog when dhcp relay has been unhealthy for consecutive max_count + * checks. + * + * @param window_sec time interval between health checks + * @param max_count max count of consecutive unhealthy statuses before reporting to syslog + * + * @return 0 upon success, otherwise upon failure + */ +int dhcp_mon_init(int window_sec, int max_count); + +/** + * @code dhcp_mon_shutdown(); + * + * @brief shuts down libevent loop + * + * @return none + */ +void dhcp_mon_shutdown(); + +/** + * @code dhcp_mon_start(snaplen); + * + * @brief start monitoring DHCP Relay + * + * @param snaplen packet capture length + * + * @return 0 upon success, otherwise upon failure + */ +int dhcp_mon_start(int snaplen); + +/** + * @code dhcp_mon_stop(); + * + * @brief stop monitoring DHCP Relay + * + * @return none + */ +void dhcp_mon_stop(); + +#endif /* DHCP_MON_H_ */ diff --git a/src/dhcpmon/src/main.c b/src/dhcpmon/src/main.c new file mode 100644 index 000000000000..11eab6ee9ea1 --- /dev/null +++ b/src/dhcpmon/src/main.c @@ -0,0 +1,174 @@ +/** + * @file main.c + * + * @brief: Main entry point for dhcpmon utility. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dhcp_mon.h" +#include "dhcp_devman.h" + +/** dhcpmon_default_snaplen: default snap length of packet being captured */ +static const uint32_t dhcpmon_default_snaplen = 65535; +/** dhcpmon_default_health_check_window: default value for a time window, during which DHCP DORA packet counts are being + * collected */ +static const uint32_t dhcpmon_default_health_check_window = 12; +/** dhcpmon_default_unhealthy_max_count: default max consecutive unhealthy status reported before reporting an issue + * with DHCP relay */ +static const uint32_t dhcpmon_default_unhealthy_max_count = 10; + +/** + * @code usage(prog); + * + * @brief prints help message about how to use dhcpmon utility + * + * @param prog program name + * + * @return none + */ +static void usage(const char *prog) +{ + printf("Usage: %s -id {-iu }+ [-w ]" + "[-c ] [-s ] [-d]\n", prog); + printf("where\n"); + printf("\tsouth interface: is a vlan interface,\n"); + printf("\tnorth interface: is a TOR-T1 interface,\n"); + printf("\tsnapshot window: during which DHCP counters are gathered and DHCP status is validated (default %d),\n", + dhcpmon_default_health_check_window); + printf("\tunhealthy status count: count of consecutive unhealthy status before writing an alert to syslog " + "(default %d),\n", + dhcpmon_default_unhealthy_max_count); + printf("\tsnap length: snap length of packet capture (default %d),\n", dhcpmon_default_snaplen); + printf("\t-d: daemonize %s.\n", prog); + + exit(EXIT_SUCCESS); +} + +/** + * @code dhcpmon_daemonize(); + * + * @brief make this utility run as a daemon. + * + * @return none + */ +static void dhcpmon_daemonize() +{ + pid_t pid, sid; + pid = fork(); + if (pid < 0) { + syslog(LOG_ALERT, "fork: %s", strerror(errno)); + exit(EXIT_FAILURE); + } + + if (pid > 0) { + exit(EXIT_SUCCESS); + } + + // this is the daemon running now + umask(0); + // Create a new SID for the child process + sid = setsid(); + if (sid < 0) { + syslog(LOG_ALERT, "setsid: %s", strerror(errno)); + exit(EXIT_FAILURE); + } + + // Change the current working directory + if ((chdir("/")) < 0) { + syslog(LOG_ALERT, "chdir: %s", strerror(errno)); + exit(EXIT_FAILURE); + } + + close(STDIN_FILENO); + close(STDOUT_FILENO); + close(STDERR_FILENO); +} + +/** + * @code main(argc, argv); + * + * @brief main entry point of dhcpmon utility + * + * @return int 0 on success, otherwise on failure + */ +int main(int argc, char **argv) +{ + int rv = EXIT_FAILURE; + int i; + int window_interval = dhcpmon_default_health_check_window; + int max_unhealthy_count = dhcpmon_default_unhealthy_max_count; + uint32_t snaplen = dhcpmon_default_snaplen; + int make_daemon = 0; + + setlogmask(LOG_UPTO(LOG_INFO)); + openlog(basename(argv[0]), LOG_CONS | LOG_PID | LOG_NDELAY, LOG_DAEMON); + + dhcp_devman_init(); + + for (i = 1; i < argc;) { + if ((argv[i] == NULL) || (argv[i][0] != '-')) { + break; + } + switch (argv[i][1]) + { + case 'h': + usage(basename(argv[0])); + break; + case 'i': + if (dhcp_devman_add_intf(argv[i + 1], argv[i][2] == 'u') != 0) { + usage(basename(argv[0])); + } + i += 2; + break; + case 'd': + make_daemon = 1; + i++; + break; + case 's': + snaplen = atoi(argv[i + 1]); + i += 2; + break; + case 'w': + window_interval = atoi(argv[i + 1]); + i += 2; + break; + case 'c': + max_unhealthy_count = atoi(argv[i + 1]); + i += 2; + break; + default: + fprintf(stderr, "%s: %c: Unknown option\n", basename(argv[0]), argv[i][1]); + usage(basename(argv[0])); + } + } + + if (make_daemon) { + dhcpmon_daemonize(); + } + + if ((dhcp_mon_init(window_interval, max_unhealthy_count) == 0) && + (dhcp_mon_start(snaplen) == 0)) { + + rv = EXIT_SUCCESS; + + dhcp_mon_shutdown(); + } + + dhcp_devman_shutdown(); + + closelog(); + + return rv; +} diff --git a/src/dhcpmon/src/subdir.mk b/src/dhcpmon/src/subdir.mk new file mode 100644 index 000000000000..324977aa39f7 --- /dev/null +++ b/src/dhcpmon/src/subdir.mk @@ -0,0 +1,29 @@ +# Add inputs and outputs from these tool invocations to the build variables +CC := gcc + +C_SRCS += \ +../src/dhcp_device.c \ +../src/dhcp_devman.c \ +../src/dhcp_mon.c \ +../src/main.c + +OBJS += \ +./src/dhcp_device.o \ +./src/dhcp_devman.o \ +./src/dhcp_mon.o \ +./src/main.o + +C_DEPS += \ +./src/dhcp_device.d \ +./src/dhcp_devman.d \ +./src/dhcp_mon.d \ +./src/main.d + + +# Each subdirectory must supply rules for building sources it contributes +src/%.o: ../src/%.c + @echo 'Building file: $<' + @echo 'Invoking: GCC C Compiler' + $(CC) -O3 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<" + @echo 'Finished building: $<' + @echo ' ' diff --git a/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf b/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf index bae273eeaf81..a29982a646f4 100644 --- a/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf +++ b/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf @@ -37,3 +37,16 @@ stdout_logfile=syslog stderr_logfile=syslog +[group:dhcpmon] +programs=dhcpmon-Vlan1000 + +[program:dhcpmon-Vlan1000] +command=/usr/sbin/dhcpmon -id Vlan1000 -iu PortChannel01 -iu PortChannel02 -iu PortChannel03 -iu PortChannel04 +priority=4 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + + + From 89eedb3f1fb21be5c8c1a0915e866993bb558f4d Mon Sep 17 00:00:00 2001 From: yozhao101 <56170650+yozhao101@users.noreply.github.com> Date: Fri, 10 Jan 2020 16:21:02 -0800 Subject: [PATCH 004/178] [Services] Allow monit system tool to monitor the critical processes status running in various SONiC containers. (#3940) * Add a monit config file for teamd container. Signed-off-by: Yong Zhao * Add a copy mechanism to put the monit config file in teamd container into base image. Signed-off-by: Yong Zhao * Add a monit config file for snmp container. Signed-off-by: Yong Zhao * Add a copy mechanism to put the monit config file of snmp container into the base image. Signed-off-by: Yong Zhao * Add a monit config file for dhcp_relay container in the dir base_image_files. Signed-off-by: Yong Zhao * Add a copy mechanism to put the monit config file of dhcp_relay container into base image under /etc/monit/conf.d. Signed-off-by: Yong Zhao * Add a monit config file for router advertiser container. Signed-off-by: Yong Zhao * Add a copy mechanism to put the monit config file of router advertiser contianer into base image. Signed-off-by: Yong Zhao * [Docker-Pmon] Add a monit config file for pmon container. Signed-off-by: Yong Zhao * [Docker-Pmon] Add a copy mechanism to put the monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-lldp] Add a monit config file for lldp container. Signed-off-by: Yong Zhao * [Docker-lldp] Add a copy mechanism to put the monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-bgp] Add a monit config file for BGP container. Signed-off-by: Yong Zhao * [Docker-bgp] Add a copy mechanism to put monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-swss] Add a monit config file for the swss container. Signed-off-by: Yong Zhao * [Docker-swss] Add a copy mechanism to put monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-syncd] Add a monit config file for syncd container on barefoot platform. Signed-off-by: Yong Zhao * [Docker-syncd] Add a copy mechanism to put the monit config file into the base image on barefoot. Signed-off-by: Yong Zhao * [Docker-syncd] Add a monit config file for syncd container on broadcom. Signed-off-by: Yong Zhao * [Docker-syncd] Add a copy mechanism to put the monit config file into the base image on broadcom. Signed-off-by: Yong Zhao * [Docker-syncd] Add a monit config file for syncd container on cavium. Signed-off-by: Yong Zhao * [Docker-syncd] Add a copy mechanism to put the monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-centec] Add a monit config file for syncd container on centen platform. Signed-off-by: Yong Zhao * [Docker-syncd] Add a copy mechanism to put the monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-syncd] Add a monit config file for syncd container on centen platform. Signed-off-by: Yong Zhao * [Docker-syncd] Add a copy mechanism to put the monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-syncd] Add a monit config file for syncd container on marvell. Signed-off-by: Yong Zhao * [Docker-syncd] Add a copy mechanism to put the monit conifg file into the base image. Signed-off-by: Yong Zhao * [Docker-syncd] Add a monit config file for syncd container on marvell-arm64. Signed-off-by: Yong Zhao * [Docker-syncd] Add a copy mechanism to put the monit config file into the base image on marvell-arm64. Signed-off-by: Yong Zhao * [Docker-syncd] Add a monit config file for syncd container on marvell-armhf. Signed-off-by: Yong Zhao * [Docker-syncd] Add a copy mechanism to put the monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-syncd] Add a monit config file for syncd container on mellanox. Signed-off-by: Yong Zhao * [Docker-syncd] Add a copy mechanism to put the monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-syncd] Add a monit config file for syncd container on nephos. Signed-off-by: Yong Zhao * [Docker-syncd] Add a copy mechanism to put the monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-sflow] Add a monit config file for sflow container. Signed-off-by: Yong Zhao * [Docker-sflow] Add a copy mechanism to put the monit conifg file into the base image. Signed-off-by: Yong Zhao * [Docker-telemetry] Add a monit config file for telemetry container. Signed-off-by: Yong Zhao * [Docker-telemetry] Add a copy mechanism to put the monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-database] Add a monit config file for database container. Signed-off-by: Yong Zhao * [Docker-database] Add a copy mechanism to put the monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-Dhcprelay] Change a typo. Signed-off-by: Yong Zhao * [Docker-Dhcprelay] Change the process name in monit config file to dhcrelay. Signed-off-by: Yong Zhao * [Docker-syncd] There is no desserve process in syncd container on barefoot. Signed-off-by: Yong Zhao * [Docker-syncd] There is no process desserve in syncd container on cavium. Signed-off-by: Yong Zhao * [Docker-syncd] There is no process named desserve in syncd on centec. Signed-off-by: Yong Zhao * [Docker-syncd] There is no process named desserve in syncd on marvell. Signed-off-by: Yong Zhao * [Docker-syncd] Should not delete the process desserve in syncd container on marvell. Signed-off-by: Yong Zhao * [Docker-syncd] Delete the process dsserve in syncd on marvell. Signed-off-by: Yong Zhao * [Docker-syncd] Delete the process dsserve in syncd container on marvell-arm64. Signed-off-by: Yong Zhao * [Docker-syncd] Delete the process dsserve in syncd container on marvell-armhf. Signed-off-by: Yong Zhao * [Docker-syncd] Delete the process dsserve in syncd container on mellanox. Signed-off-by: Yong Zhao * [Docker-Radv] Change the process name to radvd. Signed-off-by: Yong Zhao * [Docker-telemetry] Correct a typo in monit_telemetry. Signed-off-by: Yong Zhao * [Docker-teamd] Delete the monit config file for teamd. Signed-off-by: Yong Zhao * [Docker-teamd] Delete the mechanism to copy the monit config file into base image. Signed-off-by: Yong Zhao * [Docker-dhcprelay] Delete the monit config file for dhcp_relay container. Signed-off-by: Yong Zhao * [Docker-dhcprelay] Delete the mechanism to copy the monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-radv] Delete the monit config file foe radv container. Signed-off-by: Yong Zhao * [Docker-radv] Delete the mechanism to copy the monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-bgp] change the monit config file for BGP container such that monit only generates alert if the process is not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-snmp] Change the monit config file for snmp container such that monit only generates alret if the process is not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-pmon] Change the monit config file for pmon container such that monit only generates alert if the processes are not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-lldp] Change the monit config file for lldp container such that monit only generates alerts if some processes are not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-pmon] Delete the monit config file for pmon container since some of processes are not running depended on the type of box. Signed-off-by: Yong Zhao * [Docker-pmon] Delete the copy mechanism to copy the monit config file into the base image. Signed-off-by: Yong Zhao * [Docker-lldp] Change the matching name for the process lldpd. Signed-off-by: Yong Zhao * [Docker-swss] Change the monit config file for swss container such that monit only generates alerts if the processes are not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-syncd] Change the monit config file for syncd container on barefoot such that monit only generates alerts if the process is not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-syncd] Correct a typo in monit config file. Signed-off-by: Yong Zhao * [Docker-syncd] Change the monit config file for syncd container on broadcom such that monit only generates alerts if the processes are not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-syncd] Change the monit config file for syncd container on cavium such that monit only generates alerts if the process is not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-syncd] Change the monit config file for syncd container such that monit only generates alerts if the process is not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-syncd] Change the monit config file for syncd container on marvell such that monit only generates alerts if the process is not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-syncd] Change the monit config file for syncd container on marvell-arm64 such that monit only generates alerts if the process is not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-syncd] Change the monit config file for syncd container on marvell-armhf such that monit will generate alert if the process is not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-syncd] Change the monit config file for syncd container on mellanox such that monit only generates alerts if the process is not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-sycnd] Change the monit config file for syncd container such that monit only generates alerts if the processes are not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-sflow] Change the monit config file for sflow container such that monit only generates alerts if the process is not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-telemetry] Change the monit config file for telemetry container such that monit only generates alerts if the processes are not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-database] Change the monit config file for database container such that monit only generates alerts if the process is not running for 5 minutes. Signed-off-by: Yong Zhao * [Docker-database] Use 4 spaces to replace 2 spaces in monit config file. Signed-off-by: Yong Zhao * [Docker-bgp] Use 4 spcess to replace 2 spaces in monit config file. Signed-off-by: Yong Zhao * [Docker-lldp] Use 4 spaces to replace 2 spaces in monit config file. Signed-off-by: Yong Zhao * [Docker-swss] Use 4 spaces to replace 2 space in monit config file. Signed-off-by: Yong Zhao * [Docker-sflow] Use 4 spaces to replace 2 spaces in monit config file. Signed-off-by: Yong Zhao * [Docker-snmp] Use 4 spaces to replace 2 spaces in monit config file. Signed-off-by: Yong Zhao * [Docker-telemetry] Use 4 spaces to replace 2 spaces in monit config file. Signed-off-by: Yong Zhao * [Docker-syncd] Use 4 spaces to replace 2 spaces in the monit config file on barefoot. Signed-off-by: Yong Zhao * [Docker-syncd] Use 4 spaces to replace 2 spaces in the monit config file on broadcom. Signed-off-by: Yong Zhao * [Docker-syncd] Use 4 spaces to replace 2 spaces in the monit config file on cavium. Signed-off-by: Yong Zhao * [Docker-syncd] Use 4 spaces to replace 2 spaces in the monit config file on centec. Signed-off-by: Yong Zhao * [Docker-syncd] Use 4 spaces to replace 2 spaces in the monit config file on marvell. Signed-off-by: Yong Zhao * [Docker-syncd] Use 4 spaces to replace 2 spaces in the monit config file on mellanox. Signed-off-by: Yong Zhao * [Docker-syncd] Use 4 spaces to repalce 2 spaces in the monit config file on nephos. Signed-off-by: Yong Zhao * [Docker-bgp] Remove the trailing extra spaces in monit config file. Signed-off-by: Yong Zhao --- .../base_image_files/monit_database | 7 +++ .../docker-fpm-frr/base_image_files/monit_bgp | 23 ++++++++++ .../base_image_files/monit_lldp | 15 +++++++ .../base_image_files/monit_swss | 43 +++++++++++++++++++ .../docker-sflow/base_image_files/monit_sflow | 7 +++ .../base_image_files/monit_snmp | 11 +++++ .../base_image_files/monit_telemetry | 11 +++++ platform/barefoot/docker-syncd-bfn.mk | 2 +- .../base_image_files/monit_syncd | 7 +++ platform/broadcom/docker-syncd-brcm.mk | 1 + .../base_image_files/monit_syncd | 11 +++++ platform/cavium/docker-syncd-cavm.mk | 1 + .../base_image_files/monit_syncd | 7 +++ platform/centec/docker-syncd-centec.mk | 1 + .../base_image_files/monit_syncd | 7 +++ platform/marvell-arm64/docker-syncd-mrvl.mk | 1 + .../base_image_files/monit_syncd | 7 +++ platform/marvell-armhf/docker-syncd-mrvl.mk | 1 + .../base_image_files/monit_syncd | 7 +++ platform/marvell/docker-syncd-mrvl.mk | 1 + .../base_image_files/monit_syncd | 7 +++ platform/mellanox/docker-syncd-mlnx.mk | 2 +- .../base_image_files/monit_syncd | 7 +++ platform/nephos/docker-syncd-nephos.mk | 2 +- .../base_image_files/monit_syncd | 11 +++++ rules/docker-database.mk | 1 + rules/docker-fpm-frr.mk | 1 + rules/docker-lldp-sv2.mk | 1 + rules/docker-orchagent.mk | 1 + rules/docker-sflow.mk | 1 + rules/docker-snmp-sv2.mk | 1 + rules/docker-telemetry.mk | 1 + 32 files changed, 204 insertions(+), 3 deletions(-) create mode 100644 dockers/docker-database/base_image_files/monit_database create mode 100644 dockers/docker-fpm-frr/base_image_files/monit_bgp create mode 100644 dockers/docker-lldp-sv2/base_image_files/monit_lldp create mode 100644 dockers/docker-orchagent/base_image_files/monit_swss create mode 100644 dockers/docker-sflow/base_image_files/monit_sflow create mode 100644 dockers/docker-snmp-sv2/base_image_files/monit_snmp create mode 100644 dockers/docker-sonic-telemetry/base_image_files/monit_telemetry create mode 100644 platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd create mode 100644 platform/broadcom/docker-syncd-brcm/base_image_files/monit_syncd create mode 100644 platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd create mode 100644 platform/centec/docker-syncd-centec/base_image_files/monit_syncd create mode 100644 platform/marvell-arm64/docker-syncd-mrvl/base_image_files/monit_syncd create mode 100644 platform/marvell-armhf/docker-syncd-mrvl/base_image_files/monit_syncd create mode 100644 platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd create mode 100644 platform/mellanox/docker-syncd-mlnx/base_image_files/monit_syncd create mode 100644 platform/nephos/docker-syncd-nephos/base_image_files/monit_syncd diff --git a/dockers/docker-database/base_image_files/monit_database b/dockers/docker-database/base_image_files/monit_database new file mode 100644 index 000000000000..c5508922864e --- /dev/null +++ b/dockers/docker-database/base_image_files/monit_database @@ -0,0 +1,7 @@ +############################################################################### +## Monit configuration for database container +## process list: +## redis_server +############################################################################### +check process redis_server matching "/usr/bin/redis-server" + if does not exist for 5 times within 5 cycles then alert diff --git a/dockers/docker-fpm-frr/base_image_files/monit_bgp b/dockers/docker-fpm-frr/base_image_files/monit_bgp new file mode 100644 index 000000000000..5b943ea7c0bb --- /dev/null +++ b/dockers/docker-fpm-frr/base_image_files/monit_bgp @@ -0,0 +1,23 @@ +############################################################################### +## Monit configuration for BGP container +## process list: +## zebra +## fpmsyncd +## bgpd +## staticd +## bgpcfgd +############################################################################### +check process zebra matching "/usr/lib/frr/zebra" + if does not exist for 5 times within 5 cycles then alert + +check process fpmsyncd matching "fpmsyncd" + if does not exist for 5 times within 5 cycles then alert + +check process bgpd matching "/usr/lib/frr/bgpd" + if does not exist for 5 times within 5 cycles then alert + +check process staticd matching "/usr/lib/frr/staticd" + if does not exist for 5 times within 5 cycles then alert + +check process bgpcfgd matching "python /usr/bin/bgpcfgd" + if does not exist for 5 times within 5 cycles then alert diff --git a/dockers/docker-lldp-sv2/base_image_files/monit_lldp b/dockers/docker-lldp-sv2/base_image_files/monit_lldp new file mode 100644 index 000000000000..200c52c7d332 --- /dev/null +++ b/dockers/docker-lldp-sv2/base_image_files/monit_lldp @@ -0,0 +1,15 @@ +############################################################################### +## Monit configuration for lldp container +## process list: +## lldpd +## lldp-syncd +## lldpmgrd +############################################################################### +check process lldpd_monitor matching "lldpd: " + if does not exist for 5 times within 5 cycles then alert + +check process lldp_syncd matching "python2 -m lldp_syncd" + if does not exist for 5 times within 5 cycles then alert + +check process lldpmgrd matching "python /usr/bin/lldpmgrd" + if does not exist for 5 times within 5 cycles then alert diff --git a/dockers/docker-orchagent/base_image_files/monit_swss b/dockers/docker-orchagent/base_image_files/monit_swss new file mode 100644 index 000000000000..5928dbd4ddb0 --- /dev/null +++ b/dockers/docker-orchagent/base_image_files/monit_swss @@ -0,0 +1,43 @@ +############################################################################### +## Monit configuration for swss container +## process list: +## orchagent +## portsyncd +## neighsyncd +## vrfmgrd +## vlanmgrd +## intfmgrd +## portmgrd +## buffermgrd +## nbrmgrd +## vxlanmgrd +############################################################################### +check process orchagent matching "/usr/bin/orchagent -d /var/log/swss" + if does not exist for 5 times within 5 cycles then alert + +check process portsyncd matching "/usr/bin/portsyncd" + if does not exist for 5 times within 5 cycles then alert + +check process neighsyncd matching "/usr/bin/neighsyncd" + if does not exist for 5 times within 5 cycles then alert + +check process vrfmgrd matching "/usr/bin/vrfmgrd" + if does not exist for 5 times within 5 cycles then alert + +check process vlanmgrd matching "/usr/bin/vlanmgrd" + if does not exist for 5 times within 5 cycles then alert + +check process intfmgrd matching "/usr/bin/intfmgrd" + if does not exist for 5 times within 5 cycles then alert + +check process portmgrd matching "/usr/bin/portmgrd" + if does not exist for 5 times within 5 cycles then alert + +check process buffermgrd matching "/usr/bin/buffermgrd -l" + if does not exist for 5 times within 5 cycles then alert + +check process nbrmgrd matching "/usr/bin/nbrmgrd" + if does not exist for 5 times within 5 cycles then alert + +check process vxlanmgrd matching "/usr/bin/vxlanmgrd" + if does not exist for 5 times within 5 cycles then alert diff --git a/dockers/docker-sflow/base_image_files/monit_sflow b/dockers/docker-sflow/base_image_files/monit_sflow new file mode 100644 index 000000000000..d041f81001ea --- /dev/null +++ b/dockers/docker-sflow/base_image_files/monit_sflow @@ -0,0 +1,7 @@ +############################################################################### +## Monit configuration for sflow container +## process list: +## sflowmgrd +############################################################################### +check process sflowmgrd matching "/usr/bin/sflowmgrd" + if does not exist for 5 times within 5 cycles then alert diff --git a/dockers/docker-snmp-sv2/base_image_files/monit_snmp b/dockers/docker-snmp-sv2/base_image_files/monit_snmp new file mode 100644 index 000000000000..811f9d14b3d4 --- /dev/null +++ b/dockers/docker-snmp-sv2/base_image_files/monit_snmp @@ -0,0 +1,11 @@ +############################################################################### +## Monit configuration for snmp container +## process list: +## snmpd +## snmpd_subagent +############################################################################### +check process snmpd matching "/usr/sbin/snmpd -f" + if does not exist for 5 times within 5 cycles then alert + +check process snmp_subagent matching "python3.6 -m sonic_ax_impl" + if does not exist for 5 times within 5 cycles then alert diff --git a/dockers/docker-sonic-telemetry/base_image_files/monit_telemetry b/dockers/docker-sonic-telemetry/base_image_files/monit_telemetry new file mode 100644 index 000000000000..555822c57f80 --- /dev/null +++ b/dockers/docker-sonic-telemetry/base_image_files/monit_telemetry @@ -0,0 +1,11 @@ +############################################################################### +## Monit configuration for telemetry container +## process list: +## telemetry +## dialout_client +############################################################################### +check process telemetry matching "/usr/sbin/telemetry -logtostderr --insecure" + if does not exist for 5 times within 5 cycles then alert + +check process dialout_client matching "/usr/sbin/dialout_client_cli -insecure -logtostderr" + if does not exist for 5 times within 5 cycles then alert diff --git a/platform/barefoot/docker-syncd-bfn.mk b/platform/barefoot/docker-syncd-bfn.mk index 6f3ed59ad285..3a5c693e2fa8 100644 --- a/platform/barefoot/docker-syncd-bfn.mk +++ b/platform/barefoot/docker-syncd-bfn.mk @@ -11,4 +11,4 @@ $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ $(LIBSAIREDIS_DBG) $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot - +$(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd b/platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd new file mode 100644 index 000000000000..9cc5891c7c32 --- /dev/null +++ b/platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd @@ -0,0 +1,7 @@ +############################################################################### +## Monit configuration for syncd container +## process list: +## syncd +############################################################################### +check process syncd matching "/usr/bin/syncd --diag" + if does not exist for 5 times within 5 cycles then alert diff --git a/platform/broadcom/docker-syncd-brcm.mk b/platform/broadcom/docker-syncd-brcm.mk index 29727dbb2260..d3a6d67c5cbc 100644 --- a/platform/broadcom/docker-syncd-brcm.mk +++ b/platform/broadcom/docker-syncd-brcm.mk @@ -16,3 +16,4 @@ $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd $(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += bcmcmd:/usr/bin/bcmcmd $(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += bcmsh:/usr/bin/bcmsh +$(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/broadcom/docker-syncd-brcm/base_image_files/monit_syncd b/platform/broadcom/docker-syncd-brcm/base_image_files/monit_syncd new file mode 100644 index 000000000000..3f8bc50007d7 --- /dev/null +++ b/platform/broadcom/docker-syncd-brcm/base_image_files/monit_syncd @@ -0,0 +1,11 @@ +############################################################################### +## Monit configuration for syncd container +## process list: +## syncd +## dsserve +############################################################################### +check process syncd matching "/usr/bin/syncd --diag" + if does not exist for 5 times within 5 cycles then alert + +check process dsserve matching "/usr/bin/dsserve /usr/bin/syncd" + if does not exist for 5 times within 5 cycles then alert diff --git a/platform/cavium/docker-syncd-cavm.mk b/platform/cavium/docker-syncd-cavm.mk index a136828dbff1..ad43d6f1196f 100644 --- a/platform/cavium/docker-syncd-cavm.mk +++ b/platform/cavium/docker-syncd-cavm.mk @@ -20,3 +20,4 @@ $(DOCKER_SYNCD_CAVM)_CONTAINER_NAME = syncd $(DOCKER_SYNCD_CAVM)_RUN_OPT += --net=host --privileged -t $(DOCKER_SYNCD_CAVM)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf $(DOCKER_SYNCD_CAVM)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_SYNCD_CAVM)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd b/platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd new file mode 100644 index 000000000000..9cc5891c7c32 --- /dev/null +++ b/platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd @@ -0,0 +1,7 @@ +############################################################################### +## Monit configuration for syncd container +## process list: +## syncd +############################################################################### +check process syncd matching "/usr/bin/syncd --diag" + if does not exist for 5 times within 5 cycles then alert diff --git a/platform/centec/docker-syncd-centec.mk b/platform/centec/docker-syncd-centec.mk index 360690731a58..a0dbcc629dee 100644 --- a/platform/centec/docker-syncd-centec.mk +++ b/platform/centec/docker-syncd-centec.mk @@ -21,3 +21,4 @@ $(DOCKER_SYNCD_CENTEC)_RUN_OPT += --net=host --privileged -t $(DOCKER_SYNCD_CENTEC)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf $(DOCKER_SYNCD_CENTEC)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd $(DOCKER_SYNCD_CENTEC)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_SYNCD_CENTEC)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/centec/docker-syncd-centec/base_image_files/monit_syncd b/platform/centec/docker-syncd-centec/base_image_files/monit_syncd new file mode 100644 index 000000000000..9cc5891c7c32 --- /dev/null +++ b/platform/centec/docker-syncd-centec/base_image_files/monit_syncd @@ -0,0 +1,7 @@ +############################################################################### +## Monit configuration for syncd container +## process list: +## syncd +############################################################################### +check process syncd matching "/usr/bin/syncd --diag" + if does not exist for 5 times within 5 cycles then alert diff --git a/platform/marvell-arm64/docker-syncd-mrvl.mk b/platform/marvell-arm64/docker-syncd-mrvl.mk index e00769a59700..841e3b4b165f 100644 --- a/platform/marvell-arm64/docker-syncd-mrvl.mk +++ b/platform/marvell-arm64/docker-syncd-mrvl.mk @@ -11,3 +11,4 @@ $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ $(LIBSAIREDIS_DBG) $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot +$(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/marvell-arm64/docker-syncd-mrvl/base_image_files/monit_syncd b/platform/marvell-arm64/docker-syncd-mrvl/base_image_files/monit_syncd new file mode 100644 index 000000000000..9cc5891c7c32 --- /dev/null +++ b/platform/marvell-arm64/docker-syncd-mrvl/base_image_files/monit_syncd @@ -0,0 +1,7 @@ +############################################################################### +## Monit configuration for syncd container +## process list: +## syncd +############################################################################### +check process syncd matching "/usr/bin/syncd --diag" + if does not exist for 5 times within 5 cycles then alert diff --git a/platform/marvell-armhf/docker-syncd-mrvl.mk b/platform/marvell-armhf/docker-syncd-mrvl.mk index e00769a59700..841e3b4b165f 100644 --- a/platform/marvell-armhf/docker-syncd-mrvl.mk +++ b/platform/marvell-armhf/docker-syncd-mrvl.mk @@ -11,3 +11,4 @@ $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ $(LIBSAIREDIS_DBG) $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot +$(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/marvell-armhf/docker-syncd-mrvl/base_image_files/monit_syncd b/platform/marvell-armhf/docker-syncd-mrvl/base_image_files/monit_syncd new file mode 100644 index 000000000000..9cc5891c7c32 --- /dev/null +++ b/platform/marvell-armhf/docker-syncd-mrvl/base_image_files/monit_syncd @@ -0,0 +1,7 @@ +############################################################################### +## Monit configuration for syncd container +## process list: +## syncd +############################################################################### +check process syncd matching "/usr/bin/syncd --diag" + if does not exist for 5 times within 5 cycles then alert diff --git a/platform/marvell/docker-syncd-mrvl.mk b/platform/marvell/docker-syncd-mrvl.mk index 5257bf5e68e7..97b7eab19895 100644 --- a/platform/marvell/docker-syncd-mrvl.mk +++ b/platform/marvell/docker-syncd-mrvl.mk @@ -12,3 +12,4 @@ $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(SYNCD_DBG) \ $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd +$(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd b/platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd new file mode 100644 index 000000000000..9cc5891c7c32 --- /dev/null +++ b/platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd @@ -0,0 +1,7 @@ +############################################################################### +## Monit configuration for syncd container +## process list: +## syncd +############################################################################### +check process syncd matching "/usr/bin/syncd --diag" + if does not exist for 5 times within 5 cycles then alert diff --git a/platform/mellanox/docker-syncd-mlnx.mk b/platform/mellanox/docker-syncd-mlnx.mk index db582e517bff..9bdc5a8ad8ec 100644 --- a/platform/mellanox/docker-syncd-mlnx.mk +++ b/platform/mellanox/docker-syncd-mlnx.mk @@ -15,4 +15,4 @@ $(DOCKER_SYNCD_BASE)_DBG_DEPENDS += $(MLNX_SDK_DBG_DEBS) $(MLNX_SAI_DBGSYM) endif $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot - +$(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/mellanox/docker-syncd-mlnx/base_image_files/monit_syncd b/platform/mellanox/docker-syncd-mlnx/base_image_files/monit_syncd new file mode 100644 index 000000000000..9cc5891c7c32 --- /dev/null +++ b/platform/mellanox/docker-syncd-mlnx/base_image_files/monit_syncd @@ -0,0 +1,7 @@ +############################################################################### +## Monit configuration for syncd container +## process list: +## syncd +############################################################################### +check process syncd matching "/usr/bin/syncd --diag" + if does not exist for 5 times within 5 cycles then alert diff --git a/platform/nephos/docker-syncd-nephos.mk b/platform/nephos/docker-syncd-nephos.mk index 6829c91c67aa..67bad252870a 100644 --- a/platform/nephos/docker-syncd-nephos.mk +++ b/platform/nephos/docker-syncd-nephos.mk @@ -15,4 +15,4 @@ $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/warmboot:/var/warmboot $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /var/run/docker-syncd:/var/run/sswsyncd $(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += npx_diag:/usr/bin/npx_diag - +$(DOCKER_SYNCD_BASE)_BASE_IMAGE_FILES += monit_syncd:/etc/monit/conf.d diff --git a/platform/nephos/docker-syncd-nephos/base_image_files/monit_syncd b/platform/nephos/docker-syncd-nephos/base_image_files/monit_syncd new file mode 100644 index 000000000000..3f8bc50007d7 --- /dev/null +++ b/platform/nephos/docker-syncd-nephos/base_image_files/monit_syncd @@ -0,0 +1,11 @@ +############################################################################### +## Monit configuration for syncd container +## process list: +## syncd +## dsserve +############################################################################### +check process syncd matching "/usr/bin/syncd --diag" + if does not exist for 5 times within 5 cycles then alert + +check process dsserve matching "/usr/bin/dsserve /usr/bin/syncd" + if does not exist for 5 times within 5 cycles then alert diff --git a/rules/docker-database.mk b/rules/docker-database.mk index 43dc2ed5d446..9ad6b0b36b45 100644 --- a/rules/docker-database.mk +++ b/rules/docker-database.mk @@ -27,3 +27,4 @@ $(DOCKER_DATABASE)_RUN_OPT += --net=host --privileged -t $(DOCKER_DATABASE)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_DATABASE)_BASE_IMAGE_FILES += redis-cli:/usr/bin/redis-cli +$(DOCKER_DATABASE)_BASE_IMAGE_FILES += monit_database:/etc/monit/conf.d diff --git a/rules/docker-fpm-frr.mk b/rules/docker-fpm-frr.mk index 1d158effe7ff..e833d360bec2 100644 --- a/rules/docker-fpm-frr.mk +++ b/rules/docker-fpm-frr.mk @@ -30,3 +30,4 @@ $(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += vtysh:/usr/bin/vtysh $(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += TSA:/usr/bin/TSA $(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += TSB:/usr/bin/TSB $(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += TSC:/usr/bin/TSC +$(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += monit_bgp:/etc/monit/conf.d diff --git a/rules/docker-lldp-sv2.mk b/rules/docker-lldp-sv2.mk index 91acbe58ad82..8224239c1ced 100644 --- a/rules/docker-lldp-sv2.mk +++ b/rules/docker-lldp-sv2.mk @@ -30,4 +30,5 @@ $(DOCKER_LLDP_SV2)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_LLDP_SV2)_BASE_IMAGE_FILES += lldpctl:/usr/bin/lldpctl $(DOCKER_LLDP_SV2)_BASE_IMAGE_FILES += lldpcli:/usr/bin/lldpcli +$(DOCKER_LLDP_SV2)_BASE_IMAGE_FILES += monit_lldp:/etc/monit/conf.d $(DOCKER_LLDP_SV2)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/docker-orchagent.mk b/rules/docker-orchagent.mk index 20536adc2520..0244138cbfe2 100644 --- a/rules/docker-orchagent.mk +++ b/rules/docker-orchagent.mk @@ -34,4 +34,5 @@ $(DOCKER_ORCHAGENT)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_ORCHAGENT)_RUN_OPT += -v /var/log/swss:/var/log/swss:rw $(DOCKER_ORCHAGENT)_BASE_IMAGE_FILES += swssloglevel:/usr/bin/swssloglevel +$(DOCKER_ORCHAGENT)_BASE_IMAGE_FILES += monit_swss:/etc/monit/conf.d $(DOCKER_ORCHAGENT)_FILES += $(ARP_UPDATE_SCRIPT) $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/docker-sflow.mk b/rules/docker-sflow.mk index 94b568481885..449ff7c566f2 100644 --- a/rules/docker-sflow.mk +++ b/rules/docker-sflow.mk @@ -32,4 +32,5 @@ $(DOCKER_SFLOW)_RUN_OPT += -v /host/warmboot:/var/warmboot $(DOCKER_SFLOW)_BASE_IMAGE_FILES += psample:/usr/bin/psample $(DOCKER_SFLOW)_BASE_IMAGE_FILES += sflowtool:/usr/bin/sflowtool +$(DOCKER_SFLOW)_BASE_IMAGE_FILES += monit_sflow:/etc/monit/conf.d $(DOCKER_SFLOW)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/docker-snmp-sv2.mk b/rules/docker-snmp-sv2.mk index bd34f271b861..1f403b7a8c8a 100644 --- a/rules/docker-snmp-sv2.mk +++ b/rules/docker-snmp-sv2.mk @@ -31,3 +31,4 @@ $(DOCKER_SNMP_SV2)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro # mount Arista platform python libraries to support corresponding platforms SNMP power status query $(DOCKER_SNMP_SV2)_RUN_OPT += -v /usr/lib/python3/dist-packages/arista:/usr/lib/python3/dist-packages/arista:ro $(DOCKER_SNMP_SV2)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) +$(DOCKER_SNMP_SV2)_BASE_IMAGE_FILES += monit_snmp:/etc/monit/conf.d diff --git a/rules/docker-telemetry.mk b/rules/docker-telemetry.mk index 799bef1b1735..361136306337 100644 --- a/rules/docker-telemetry.mk +++ b/rules/docker-telemetry.mk @@ -30,3 +30,4 @@ $(DOCKER_TELEMETRY)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_TELEMETRY)_RUN_OPT += --mount type=bind,source="/var/platform/",target="/mnt/platform/" $(DOCKER_TELEMETRY)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) +$(DOCKER_TELEMETRY)_BASE_IMAGE_FILES += monit_telemetry:/etc/monit/conf.d From aad6b9c0345c94abdb87ac67a42abb04ecc95ba5 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Tue, 7 Jan 2020 15:52:49 -0800 Subject: [PATCH 005/178] [apt] Instruct apt-get to NOT check the "Valid Until" date in Release files (#3973) This is an addendum to #3958, which also instructs apt to ignore the "Valid Until" date in Release files inside the slave containers, making a complete solution, much like the previously abandoned PR #2609. This patch also unifies file names and contents. When the Debian team archives a repo, it stops updating the "Valid Until" date, thus apt-get will not apply updates for that repo unless we explicitly tell it to ignore the "Valid Until" date. Also, this has become an issue with active (i.e., non-archived) repos twice in the past year because the Debian folks seem to occasionally let the expiration lapse before updating the date. This will cause SONiC builds to fail with a message like E: Release file for http://debian-archive.trafficmanager.net/debian-security/dists/jessie/updates/InRelease is expired (invalid since 3d 3h 11min 20s). Updates for this repository will not be applied. until the dates have been updated and propagated to all mirrors. With this patch, SONiC should no longer be affected by lapsed "Valid Until" dates, whether they be accidental or purposeful. --- dockers/docker-base-stretch/Dockerfile.j2 | 2 +- dockers/docker-base-stretch/aptconf_archive_expired_release | 3 --- dockers/docker-base-stretch/no-check-valid-until | 4 ++++ dockers/docker-base/Dockerfile.j2 | 2 +- dockers/docker-base/aptconf_archive_expired_release | 3 --- dockers/docker-base/no-check-valid-until | 4 ++++ files/apt/apt.conf.d/no-check-valid-until | 3 +++ sonic-slave-jessie/Dockerfile.j2 | 2 ++ sonic-slave-jessie/no-check-valid-until | 4 ++++ sonic-slave-stretch/Dockerfile.j2 | 2 ++ sonic-slave-stretch/no-check-valid-until | 4 ++++ 11 files changed, 25 insertions(+), 8 deletions(-) delete mode 100644 dockers/docker-base-stretch/aptconf_archive_expired_release create mode 100644 dockers/docker-base-stretch/no-check-valid-until delete mode 100644 dockers/docker-base/aptconf_archive_expired_release create mode 100644 dockers/docker-base/no-check-valid-until create mode 100644 sonic-slave-jessie/no-check-valid-until create mode 100644 sonic-slave-stretch/no-check-valid-until diff --git a/dockers/docker-base-stretch/Dockerfile.j2 b/dockers/docker-base-stretch/Dockerfile.j2 index d8188a06afd6..dea58a210f89 100644 --- a/dockers/docker-base-stretch/Dockerfile.j2 +++ b/dockers/docker-base-stretch/Dockerfile.j2 @@ -34,7 +34,7 @@ COPY ["sources.list.arm64", "/etc/apt/sources.list"] COPY ["sources.list", "/etc/apt/sources.list"] {% endif %} COPY ["no_install_recommend_suggest", "/etc/apt/apt.conf.d"] -COPY ["aptconf_archive_expired_release", "/etc/apt/apt.conf.d"] +COPY ["no-check-valid-until", "/etc/apt/apt.conf.d"] # Update apt cache and # pre-install fundamental packages diff --git a/dockers/docker-base-stretch/aptconf_archive_expired_release b/dockers/docker-base-stretch/aptconf_archive_expired_release deleted file mode 100644 index 67bc409b2174..000000000000 --- a/dockers/docker-base-stretch/aptconf_archive_expired_release +++ /dev/null @@ -1,3 +0,0 @@ -# Instruct apt-get to override expired releases repo list for jessie archives - -Acquire::Check-Valid-Until "0"; diff --git a/dockers/docker-base-stretch/no-check-valid-until b/dockers/docker-base-stretch/no-check-valid-until new file mode 100644 index 000000000000..c7c25d017f7f --- /dev/null +++ b/dockers/docker-base-stretch/no-check-valid-until @@ -0,0 +1,4 @@ +# Instruct apt-get to NOT check the "Valid Until" date in Release files +# Once the Debian team archives a repo, they stop updating this date + +Acquire::Check-Valid-Until "false"; diff --git a/dockers/docker-base/Dockerfile.j2 b/dockers/docker-base/Dockerfile.j2 index cb2ff80186a3..e45235a1e139 100644 --- a/dockers/docker-base/Dockerfile.j2 +++ b/dockers/docker-base/Dockerfile.j2 @@ -32,7 +32,7 @@ COPY ["dpkg_01_drop", "/etc/dpkg/dpkg.cfg.d/01_drop"] COPY ["sources.list.armhf", "/etc/apt/sources.list"] {% elif CONFIGURED_ARCH == "arm64" %} COPY ["sources.list.arm64", "/etc/apt/sources.list"] -COPY ["aptconf_archive_expired_release", "/etc/apt/apt.conf.d"] +COPY ["no-check-valid-until", "/etc/apt/apt.conf.d"] {% else %} COPY ["sources.list", "/etc/apt/sources.list"] {% endif %} diff --git a/dockers/docker-base/aptconf_archive_expired_release b/dockers/docker-base/aptconf_archive_expired_release deleted file mode 100644 index 67bc409b2174..000000000000 --- a/dockers/docker-base/aptconf_archive_expired_release +++ /dev/null @@ -1,3 +0,0 @@ -# Instruct apt-get to override expired releases repo list for jessie archives - -Acquire::Check-Valid-Until "0"; diff --git a/dockers/docker-base/no-check-valid-until b/dockers/docker-base/no-check-valid-until new file mode 100644 index 000000000000..c7c25d017f7f --- /dev/null +++ b/dockers/docker-base/no-check-valid-until @@ -0,0 +1,4 @@ +# Instruct apt-get to NOT check the "Valid Until" date in Release files +# Once the Debian team archives a repo, they stop updating this date + +Acquire::Check-Valid-Until "false"; diff --git a/files/apt/apt.conf.d/no-check-valid-until b/files/apt/apt.conf.d/no-check-valid-until index 97b9c9005181..c7c25d017f7f 100644 --- a/files/apt/apt.conf.d/no-check-valid-until +++ b/files/apt/apt.conf.d/no-check-valid-until @@ -1 +1,4 @@ +# Instruct apt-get to NOT check the "Valid Until" date in Release files +# Once the Debian team archives a repo, they stop updating this date + Acquire::Check-Valid-Until "false"; diff --git a/sonic-slave-jessie/Dockerfile.j2 b/sonic-slave-jessie/Dockerfile.j2 index 7ed7c4eb7096..dce30193420c 100644 --- a/sonic-slave-jessie/Dockerfile.j2 +++ b/sonic-slave-jessie/Dockerfile.j2 @@ -8,6 +8,8 @@ FROM debian:jessie MAINTAINER johnar@microsoft.com +COPY ["no-check-valid-until", "/etc/apt/apt.conf.d/"] + ## Remove retired jessie-updates repo RUN sed -i '/http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list diff --git a/sonic-slave-jessie/no-check-valid-until b/sonic-slave-jessie/no-check-valid-until new file mode 100644 index 000000000000..c7c25d017f7f --- /dev/null +++ b/sonic-slave-jessie/no-check-valid-until @@ -0,0 +1,4 @@ +# Instruct apt-get to NOT check the "Valid Until" date in Release files +# Once the Debian team archives a repo, they stop updating this date + +Acquire::Check-Valid-Until "false"; diff --git a/sonic-slave-stretch/Dockerfile.j2 b/sonic-slave-stretch/Dockerfile.j2 index c5139f1dd6f7..b3c216d17cf2 100644 --- a/sonic-slave-stretch/Dockerfile.j2 +++ b/sonic-slave-stretch/Dockerfile.j2 @@ -8,6 +8,8 @@ FROM debian:stretch MAINTAINER gulv@microsoft.com +COPY ["no-check-valid-until", "/etc/apt/apt.conf.d/"] + RUN echo "deb [arch=amd64] http://debian-archive.trafficmanager.net/debian/ stretch main contrib non-free" >> /etc/apt/sources.list && \ echo "deb-src [arch=amd64] http://debian-archive.trafficmanager.net/debian/ stretch main contrib non-free" >> /etc/apt/sources.list && \ echo "deb [arch=amd64] http://debian-archive.trafficmanager.net/debian-security/ stretch/updates main contrib non-free" >> /etc/apt/sources.list && \ diff --git a/sonic-slave-stretch/no-check-valid-until b/sonic-slave-stretch/no-check-valid-until new file mode 100644 index 000000000000..c7c25d017f7f --- /dev/null +++ b/sonic-slave-stretch/no-check-valid-until @@ -0,0 +1,4 @@ +# Instruct apt-get to NOT check the "Valid Until" date in Release files +# Once the Debian team archives a repo, they stop updating this date + +Acquire::Check-Valid-Until "false"; From 82c2eee1e6ae26091ff6178e31d49c00fcd4e2ec Mon Sep 17 00:00:00 2001 From: yozhao101 <56170650+yozhao101@users.noreply.github.com> Date: Fri, 10 Jan 2020 13:01:24 -0800 Subject: [PATCH 006/178] [Monit] Change the monitoring period from 120 seconds to 60 seconds. (#3974) * [Monit] Change the monitoring period of monit from 120 seconds to 60 seconds and also at the same time double the interval for existing sonic monit config file in host. Signed-off-by: Yong Zhao --- files/image_config/monit/conf.d/sonic-host | 12 ++++++------ files/image_config/monit/monitrc | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/files/image_config/monit/conf.d/sonic-host b/files/image_config/monit/conf.d/sonic-host index 8eaa1671d821..5a67f7a9909b 100644 --- a/files/image_config/monit/conf.d/sonic-host +++ b/files/image_config/monit/conf.d/sonic-host @@ -6,17 +6,17 @@ ############################################################################### check filesystem root-overlay with path / - if space usage > 90% for 5 times within 10 cycles then alert + if space usage > 90% for 10 times within 20 cycles then alert check filesystem var-log with path /var/log - if space usage > 90% for 5 times within 10 cycles then alert + if space usage > 90% for 10 times within 20 cycles then alert check system $HOST - if memory usage > 90% for 5 times within 10 cycles then alert - if cpu usage (user) > 90% for 5 times within 10 cycles then alert - if cpu usage (system) > 90% for 5 times within 10 cycles then alert + if memory usage > 90% for 10 times within 20 cycles then alert + if cpu usage (user) > 90% for 10 times within 20 cycles then alert + if cpu usage (system) > 90% for 10 times within 20 cycles then alert check process rsyslog with pidfile /var/run/rsyslogd.pid start program = "/bin/systemctl start rsyslog.service" stop program = "/bin/systemctl stop rsyslog.service" - if totalmem > 800 MB for 5 times within 10 cycles then restart + if totalmem > 800 MB for 10 times within 20 cycles then restart diff --git a/files/image_config/monit/monitrc b/files/image_config/monit/monitrc index 7864069e3af1..3c3714882dcc 100644 --- a/files/image_config/monit/monitrc +++ b/files/image_config/monit/monitrc @@ -16,7 +16,7 @@ ## ## Start Monit in the background (run as a daemon): # - set daemon 120 # check services at 2-minute intervals + set daemon 60 # check services at 1-minute intervals # with start delay 240 # optional: delay the first check by 4-minutes (by # # default Monit check immediately after Monit start) # From e838295d35c1e9d64e9bfd0417ec646fcdab54a9 Mon Sep 17 00:00:00 2001 From: Sumukha Tumkur Vani Date: Fri, 10 Jan 2020 13:46:32 -0800 Subject: [PATCH 007/178] Changes to build restapi docker (#3993) --- .gitmodules | 7 ++++++ dockers/docker-sonic-restapi/Dockerfile.j2 | 25 +++++++++++++++++++ dockers/docker-sonic-restapi/start.sh | 10 ++++++++ dockers/docker-sonic-restapi/supervisord.conf | 12 +++++++++ rules/docker-restapi.mk | 20 +++++++++++++++ rules/restapi.mk | 9 +++++++ src/sonic-restapi | 1 + 7 files changed, 84 insertions(+) create mode 100644 dockers/docker-sonic-restapi/Dockerfile.j2 create mode 100755 dockers/docker-sonic-restapi/start.sh create mode 100644 dockers/docker-sonic-restapi/supervisord.conf create mode 100644 rules/docker-restapi.mk create mode 100644 rules/restapi.mk create mode 160000 src/sonic-restapi diff --git a/.gitmodules b/.gitmodules index b9831ba33296..4fd4bd52be6c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -75,3 +75,10 @@ [submodule "Switch-SDK-drivers"] path = platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers url = https://github.com/Mellanox/Switch-SDK-drivers +[submodule "src/sonic-ztp"] + path = src/sonic-ztp + url = https://github.com/Azure/sonic-ztp +[submodule "src/sonic-restapi"] + path = src/sonic-restapi + url = https://github.com/Azure/sonic-restapi.git + branch = master diff --git a/dockers/docker-sonic-restapi/Dockerfile.j2 b/dockers/docker-sonic-restapi/Dockerfile.j2 new file mode 100644 index 000000000000..de8080880fc7 --- /dev/null +++ b/dockers/docker-sonic-restapi/Dockerfile.j2 @@ -0,0 +1,25 @@ +{% from "dockers/dockerfile-macros.j2" import install_debian_packages, install_python_wheels, copy_files %} +FROM docker-config-engine-stretch + +ARG docker_container_name +RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf + +## Make apt-get non-interactive +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update + +{% if docker_sonic_restapi_debs.strip() -%} +# Copy locally-built Debian package dependencies +{{ copy_files("debs/", docker_sonic_restapi_debs.split(' '), "/debs/") }} + +# Install locally-built Debian packages and implicitly install their dependencies +{{ install_debian_packages( docker_sonic_restapi_debs.split(' ')) }} +{%- endif %} + +## Clean up +RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y + +COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] + +ENTRYPOINT ["/usr/bin/supervisord"] diff --git a/dockers/docker-sonic-restapi/start.sh b/dockers/docker-sonic-restapi/start.sh new file mode 100755 index 000000000000..015d246d1200 --- /dev/null +++ b/dockers/docker-sonic-restapi/start.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +mkdir -p /var/sonic +echo "# Config files managed by sonic-config-engine" > /var/sonic/config_status + +rm -f /var/run/rsyslogd.pid + +supervisorctl start rsyslogd + +supervisorctl start restapi diff --git a/dockers/docker-sonic-restapi/supervisord.conf b/dockers/docker-sonic-restapi/supervisord.conf new file mode 100644 index 000000000000..284c8aef423b --- /dev/null +++ b/dockers/docker-sonic-restapi/supervisord.conf @@ -0,0 +1,12 @@ +[supervisord] +logfile_maxbytes=1MB +logfile_backups=2 +nodaemon=true + +[program:restapi] +command=/usr/sbin/go-server-server -loglevel trace +priority=1 +autostart=true +autorestart=false +stdout_logfile=/tmp/rest-api.out.log +stderr_logfile=/tmp/rest-api.err.log diff --git a/rules/docker-restapi.mk b/rules/docker-restapi.mk new file mode 100644 index 000000000000..66d60205915a --- /dev/null +++ b/rules/docker-restapi.mk @@ -0,0 +1,20 @@ +# docker image for rest-api + +DOCKER_RESTAPI_STEM = docker-sonic-restapi +DOCKER_RESTAPI = $(DOCKER_RESTAPI_STEM).gz + +$(DOCKER_RESTAPI)_DEPENDS += $(LIBHIREDIS) $(LIBNL3) $(LIBNL_GENL3) \ + $(LIBNL_ROUTE3) $(LIBSWSSCOMMON) $(RESTAPI) + +$(DOCKER_RESTAPI)_PATH = $(DOCKERS_PATH)/$(DOCKER_RESTAPI_STEM) + +$(DOCKER_RESTAPI)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) + +SONIC_DOCKER_IMAGES += $(DOCKER_RESTAPI) +SONIC_STRETCH_DOCKERS += $(DOCKER_RESTAPI) +SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_RESTAPI) + +$(DOCKER_RESTAPI)_CONTAINER_NAME = rest-api +$(DOCKER_RESTAPI)_RUN_OPT += --cap-add NET_ADMIN --privileged -t +$(DOCKER_RESTAPI)_RUN_OPT += -v /var/run/redis/redis.sock:/var/run/redis/redis.sock +$(DOCKER_RESTAPI)_RUN_OPT += -p=8090:8090/tcp diff --git a/rules/restapi.mk b/rules/restapi.mk new file mode 100644 index 000000000000..e66b4a1d976a --- /dev/null +++ b/rules/restapi.mk @@ -0,0 +1,9 @@ +# sonic-rest-api package + +RESTAPI = sonic-rest-api_1.0.1_amd64.deb +$(RESTAPI)_SRC_PATH = $(SRC_PATH)/sonic-restapi +$(RESTAPI)_DEPENDS += $(LIBHIREDIS_DEV) $(LIBNL3_DEV) $(LIBNL_GENL3_DEV) \ + $(LIBNL_ROUTE3_DEV) $(LIBSWSSCOMMON_DEV) $(LIBSWSSCOMMON) +$(RESTAPI)_RDEPENDS += $(LIBHIREDIS) $(LIBNL3) $(LIBNL_GENL3) \ + $(LIBNL_ROUTE3) $(LIBSWSSCOMMON) +SONIC_DPKG_DEBS += $(RESTAPI) diff --git a/src/sonic-restapi b/src/sonic-restapi new file mode 160000 index 000000000000..163ee272ae99 --- /dev/null +++ b/src/sonic-restapi @@ -0,0 +1 @@ +Subproject commit 163ee272ae992f5885990dcca6552cd86b74391a From 9deb8c15f30484a234b0c6b6848ff1e132d5fe03 Mon Sep 17 00:00:00 2001 From: Sujin Kang Date: Fri, 10 Jan 2020 09:47:13 -0800 Subject: [PATCH 008/178] [reboot cause]: Delay process-reboot-cause service until network connection is stable (#4003) --- files/build_templates/process-reboot-cause.timer | 9 +++++++++ files/build_templates/sonic_debian_extension.j2 | 5 +++++ .../process-reboot-cause/process-reboot-cause.service | 3 --- 3 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 files/build_templates/process-reboot-cause.timer diff --git a/files/build_templates/process-reboot-cause.timer b/files/build_templates/process-reboot-cause.timer new file mode 100644 index 000000000000..222c51a79a03 --- /dev/null +++ b/files/build_templates/process-reboot-cause.timer @@ -0,0 +1,9 @@ +[Unit] +Description=Delays process-reboot-cause until network is stably connected + +[Timer] +OnBootSec=1min 30 sec +Unit=process-reboot-cause.service + +[Install] +WantedBy=timers.target diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 81bec67796d2..b584407bc2b3 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -283,6 +283,11 @@ sudo cp $IMAGE_CONFIGS/procdockerstatsd/procdockerstatsd.service $FILESYSTEM_RO echo "procdockerstatsd.service" | sudo tee -a $GENERATED_SERVICE_FILE sudo cp $IMAGE_CONFIGS/procdockerstatsd/procdockerstatsd $FILESYSTEM_ROOT/usr/bin/ +# Copy systemd timer configuration +# It implements delayed start of services +sudo cp $BUILD_TEMPLATES/process-reboot-cause.timer $FILESYSTEM_ROOT/etc/systemd/system/ +sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable process-reboot-cause.timer + # Copy process-reboot-cause service files sudo cp $IMAGE_CONFIGS/process-reboot-cause/process-reboot-cause.service $FILESYSTEM_ROOT/etc/systemd/system/ echo "process-reboot-cause.service" | sudo tee -a $GENERATED_SERVICE_FILE diff --git a/files/image_config/process-reboot-cause/process-reboot-cause.service b/files/image_config/process-reboot-cause/process-reboot-cause.service index a429339dbe58..b9821f60c420 100644 --- a/files/image_config/process-reboot-cause/process-reboot-cause.service +++ b/files/image_config/process-reboot-cause/process-reboot-cause.service @@ -5,6 +5,3 @@ After=rc-local.service [Service] Type=simple ExecStart=/usr/bin/process-reboot-cause - -[Install] -WantedBy=multi-user.target From e7b75b0091cea0d38a30803d8c81c5730c137323 Mon Sep 17 00:00:00 2001 From: Sumukha Tumkur Vani Date: Tue, 14 Jan 2020 17:13:45 -0800 Subject: [PATCH 009/178] [docker-restapi]: Avoid building RestAPI docker by default (#4018) Provide build option for RESTAPI docker --- Makefile.work | 1 + rules/config | 3 +++ rules/docker-restapi.mk | 2 ++ slave.mk | 8 ++++++++ 4 files changed, 14 insertions(+) diff --git a/Makefile.work b/Makefile.work index b81ac591246f..c81586ecf577 100644 --- a/Makefile.work +++ b/Makefile.work @@ -175,6 +175,7 @@ SONIC_BUILD_INSTRUCTION := make \ HTTP_PROXY=$(http_proxy) \ HTTPS_PROXY=$(https_proxy) \ SONIC_ENABLE_SYSTEM_TELEMETRY=$(ENABLE_SYSTEM_TELEMETRY) \ + SONIC_ENABLE_RESTAPI=$(ENABLE_RESTAPI) \ EXTRA_JESSIE_TARGETS=$(EXTRA_JESSIE_TARGETS) \ $(SONIC_OVERRIDE_BUILD_VARS) diff --git a/rules/config b/rules/config index b9dba045fa91..2ba9dcf301fe 100644 --- a/rules/config +++ b/rules/config @@ -101,3 +101,6 @@ ENABLE_SFLOW = y # ENABLE_MGMT_FRAMEWORK - build docker-sonic-mgt-framework for CLI and REST server support ENABLE_MGMT_FRAMEWORK = y + +# ENABLE_RESTAPI - build docker-sonic-restapi for configuring the switch using REST APIs +ENABLE_RESTAPI = n diff --git a/rules/docker-restapi.mk b/rules/docker-restapi.mk index 66d60205915a..7c02e0d4e44b 100644 --- a/rules/docker-restapi.mk +++ b/rules/docker-restapi.mk @@ -10,9 +10,11 @@ $(DOCKER_RESTAPI)_PATH = $(DOCKERS_PATH)/$(DOCKER_RESTAPI_STEM) $(DOCKER_RESTAPI)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) +ifeq ($(ENABLE_RESTAPI), y) SONIC_DOCKER_IMAGES += $(DOCKER_RESTAPI) SONIC_STRETCH_DOCKERS += $(DOCKER_RESTAPI) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_RESTAPI) +endif $(DOCKER_RESTAPI)_CONTAINER_NAME = rest-api $(DOCKER_RESTAPI)_RUN_OPT += --cap-add NET_ADMIN --privileged -t diff --git a/slave.mk b/slave.mk index 147b2a95a793..62a55597b129 100644 --- a/slave.mk +++ b/slave.mk @@ -100,6 +100,10 @@ ifneq (,$(filter $(CONFIGURED_ARCH), armhf arm64)) ENABLE_SYSTEM_TELEMETRY = N endif +ifeq ($(SONIC_ENABLE_RESTAPI),y) +ENABLE_RESTAPI = y +endif + ifeq ($(SONIC_ENABLE_SYNCD_RPC),y) ENABLE_SYNCD_RPC = y endif @@ -190,6 +194,8 @@ $(info "ENABLE_ORGANIZATION_EXTENSIONS" : "$(ENABLE_ORGANIZATION_EXTENSIONS)") $(info "HTTP_PROXY" : "$(HTTP_PROXY)") $(info "HTTPS_PROXY" : "$(HTTPS_PROXY)") $(info "ENABLE_SYSTEM_TELEMETRY" : "$(ENABLE_SYSTEM_TELEMETRY)") +$(info "ENABLE_RESTAPI" : "$(ENABLE_RESTAPI)") +$(info "ENABLE_ZTP" : "$(ENABLE_ZTP)") $(info "SONIC_DEBUGGING_ON" : "$(SONIC_DEBUGGING_ON)") $(info "SONIC_PROFILING_ON" : "$(SONIC_PROFILING_ON)") $(info "KERNEL_PROCURE_METHOD" : "$(KERNEL_PROCURE_METHOD)") @@ -641,6 +647,8 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export enable_organization_extensions="$(ENABLE_ORGANIZATION_EXTENSIONS)" export enable_dhcp_graph_service="$(ENABLE_DHCP_GRAPH_SERVICE)" export enable_system_telemetry="$(ENABLE_SYSTEM_TELEMETRY)" + export enable_restapi="$(ENABLE_RESTAPI)" + export enable_ztp="$(ENABLE_ZTP)" export shutdown_bgp_on_start="$(SHUTDOWN_BGP_ON_START)" export enable_pfcwd_on_start="$(ENABLE_PFCWD_ON_START)" export installer_debs="$(addprefix $(STRETCH_DEBS_PATH)/,$($*_INSTALLS))" From 9618c801276200795e44106aac9b9abd7c5ce631 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Fri, 17 Jan 2020 14:04:14 -0800 Subject: [PATCH 010/178] [bgpcfgd]: Fix bgpcfgd. Don't notify before all deps are ready. (#4027) * Fix bgpcfgd error. Previously subscribers were notified before all dependencies were ready --- dockers/docker-fpm-frr/bgpcfgd | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dockers/docker-fpm-frr/bgpcfgd b/dockers/docker-fpm-frr/bgpcfgd index 4211f49d2272..972c85ee271b 100755 --- a/dockers/docker-fpm-frr/bgpcfgd +++ b/dockers/docker-fpm-frr/bgpcfgd @@ -203,6 +203,8 @@ class Manager(object): syslog.syslog(syslog.LOG_ERR, 'Invalid operation "%s" for key "%s"' % (op, key)) def on_deps_change(self): + if not self.directory.available_deps(self.deps): + return new_queue = [] for key, data in self.set_queue: res = self.set_handler(key, data) From ccdc097a8ff294b68766f1d1ba488e69b5d4febf Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Fri, 17 Jan 2020 17:33:31 -0800 Subject: [PATCH 011/178] [caclmgrd] Fix application of IPv6 service ACL rules (part 2) (#4036) --- files/image_config/caclmgrd/caclmgrd | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/files/image_config/caclmgrd/caclmgrd b/files/image_config/caclmgrd/caclmgrd index 6226bb16768f..e5744c7ca65b 100755 --- a/files/image_config/caclmgrd/caclmgrd +++ b/files/image_config/caclmgrd/caclmgrd @@ -225,7 +225,9 @@ class ControlPlaneAclManager(object): rule_cmd = "ip6tables" if table_ip_version == 6 else "iptables" rule_cmd += " -A INPUT -p {}".format(ip_protocol) - if "SRC_IP" in rule_props and rule_props["SRC_IP"]: + if "SRC_IPV6" in rule_props and rule_props["SRC_IPV6"]: + rule_cmd += " -s {}".format(rule_props["SRC_IPV6"]) + elif "SRC_IP" in rule_props and rule_props["SRC_IP"]: rule_cmd += " -s {}".format(rule_props["SRC_IP"]) rule_cmd += " --dport {}".format(dst_port) From 030a34e8c9548ef3a47ce6e5274ffcaa20becaaf Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Wed, 15 Jan 2020 17:23:25 +0200 Subject: [PATCH 012/178] [mellanox] Update FW to 13/29.2000.2714. (#3998) Signed-off-by: Nazarii Hnydyn --- platform/mellanox/fw.mk | 4 ++-- platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/mellanox/fw.mk b/platform/mellanox/fw.mk index eb1a58cfda9d..4f6e7199eac8 100644 --- a/platform/mellanox/fw.mk +++ b/platform/mellanox/fw.mk @@ -11,12 +11,12 @@ else FW_FROM_URL = n endif -MLNX_SPC_FW_VERSION = 13.2000.2696 +MLNX_SPC_FW_VERSION = 13.2000.2714 MLNX_SPC_FW_FILE = fw-SPC-rel-$(subst .,_,$(MLNX_SPC_FW_VERSION))-EVB.mfa $(MLNX_SPC_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC_FW_FILE) -MLNX_SPC2_FW_VERSION = 29.2000.2696 +MLNX_SPC2_FW_VERSION = 29.2000.2714 MLNX_SPC2_FW_FILE = fw-SPC2-rel-$(subst .,_,$(MLNX_SPC2_FW_VERSION))-EVB.mfa $(MLNX_SPC2_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC2_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC2_FW_FILE) diff --git a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers index c08b5bb3810f..b85c06417b2d 160000 --- a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers +++ b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers @@ -1 +1 @@ -Subproject commit c08b5bb3810fe7da2811622aa7003ac9cc95344b +Subproject commit b85c06417b2df7e18990d0143a30ab1c46e34225 From 67ff781611eb0efc1456b93482b525d333096c48 Mon Sep 17 00:00:00 2001 From: noaOrMlnx <58519608+noaOrMlnx@users.noreply.github.com> Date: Wed, 15 Jan 2020 17:19:49 +0200 Subject: [PATCH 013/178] Change MFT version to 14.13.3 (#4022) --- platform/mellanox/mft.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/mellanox/mft.mk b/platform/mellanox/mft.mk index ae2c92e0ac18..af2192de4543 100644 --- a/platform/mellanox/mft.mk +++ b/platform/mellanox/mft.mk @@ -1,7 +1,7 @@ # Mellanox SAI -MFT_VERSION = 4.12.0 -MFT_REVISION = 104 +MFT_VERSION = 4.13.3 +MFT_REVISION = 6 export MFT_VERSION MFT_REVISION From 6d72353a6178156bce541bb13c019b5c134f6d5d Mon Sep 17 00:00:00 2001 From: Abhishek Date: Tue, 21 Jan 2020 12:05:24 -0800 Subject: [PATCH 014/178] [Submoduloe update] sonic-utilities Cherry-pick PR 743, 754, 773, 784 --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 72f0e77aa172..4d82ff82e880 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 72f0e77aa172a7096b49b661e84512785efee4e0 +Subproject commit 4d82ff82e8800f9b3b6213f2d79b7e6752eae069 From 298fbfc768be7ab6475aff40bb87b9a33edd1de0 Mon Sep 17 00:00:00 2001 From: Abhishek Date: Tue, 21 Jan 2020 12:08:07 -0800 Subject: [PATCH 015/178] [Submodule Commit] sonic-py-swsssdk. Cherry-pick PR 59, 60 --- src/sonic-py-swsssdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-py-swsssdk b/src/sonic-py-swsssdk index dd21b345d71d..7410ba1283e5 160000 --- a/src/sonic-py-swsssdk +++ b/src/sonic-py-swsssdk @@ -1 +1 @@ -Subproject commit dd21b345d71dae02c6309c8faca911b1e25bc7b7 +Subproject commit 7410ba1283e5454de4b66556d7b47c25ec793e1e From d6706f6cf84613d644f4a092180b501b78aa9e8d Mon Sep 17 00:00:00 2001 From: Abhishek Date: Tue, 21 Jan 2020 12:09:37 -0800 Subject: [PATCH 016/178] [Submodule Update] sonic-swss. Pointing to PR 1168 --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index 7b9661b2aea0..b5cde3c58429 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 7b9661b2aea0d9c3c770c421ca9963e2d742197f +Subproject commit b5cde3c58429e1cc37538dc23466b7bc2657247a From 9c08d078ea938aae5cd74a369c8583d5fc2f03bd Mon Sep 17 00:00:00 2001 From: Abhishek Date: Tue, 21 Jan 2020 12:32:14 -0800 Subject: [PATCH 017/178] [Submodule Update] Cherry-pick PR's 1108, 1156, 1159 --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index b5cde3c58429..15441fe0fe80 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit b5cde3c58429e1cc37538dc23466b7bc2657247a +Subproject commit 15441fe0fe80cba16d05c1759de0a392fdc27231 From e884e583dd1e28ff26ae3a43d3ee523d80b08167 Mon Sep 17 00:00:00 2001 From: Abhishek Date: Tue, 21 Jan 2020 13:46:25 -0800 Subject: [PATCH 018/178] Removed ZTP submodule from 201911. Bad Cherry-pick --- .gitmodules | 3 --- 1 file changed, 3 deletions(-) diff --git a/.gitmodules b/.gitmodules index 4fd4bd52be6c..afaa78686c14 100644 --- a/.gitmodules +++ b/.gitmodules @@ -75,9 +75,6 @@ [submodule "Switch-SDK-drivers"] path = platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers url = https://github.com/Mellanox/Switch-SDK-drivers -[submodule "src/sonic-ztp"] - path = src/sonic-ztp - url = https://github.com/Azure/sonic-ztp [submodule "src/sonic-restapi"] path = src/sonic-restapi url = https://github.com/Azure/sonic-restapi.git From f5ca0c7a94d70d717a8a6f1ee7a801e9a5dfb833 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Sat, 25 Jan 2020 19:43:22 -0800 Subject: [PATCH 019/178] [frr]: Update FRR to 7.2.1 (#4066) Update rules for frr package. Update frr submodule --- rules/frr.mk | 5 +++-- src/sonic-frr/Makefile | 1 - src/sonic-frr/frr | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rules/frr.mk b/rules/frr.mk index 27391ce0cf73..b2e347e0b12d 100644 --- a/rules/frr.mk +++ b/rules/frr.mk @@ -1,8 +1,9 @@ # FRRouting (frr) package -FRR_VERSION = 7.2 +FRR_VERSION = 7.2.1 FRR_SUBVERSION = 0 -export FRR_VERSION FRR_SUBVERSION +FRR_BRANCH = frr/7.2 +export FRR_VERSION FRR_SUBVERSION FRR_BRANCH FRR = frr_$(FRR_VERSION)-sonic-$(FRR_SUBVERSION)_$(CONFIGURED_ARCH).deb diff --git a/src/sonic-frr/Makefile b/src/sonic-frr/Makefile index abd9adc3fc67..8910798c5827 100644 --- a/src/sonic-frr/Makefile +++ b/src/sonic-frr/Makefile @@ -5,7 +5,6 @@ SHELL = /bin/bash MAIN_TARGET = $(FRR) DERIVED_TARGET = $(FRR_PYTHONTOOLS) $(FRR_DBG) $(FRR_SNMP) $(FRR_SNMP_DBG) SUFFIX = $(shell date +%Y%m%d\.%H%M%S) -FRR_BRANCH = frr/$(FRR_VERSION) STG_BRANCH = stg_temp.$(SUFFIX) $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : diff --git a/src/sonic-frr/frr b/src/sonic-frr/frr index d49e8f75bd46..90446e3c3310 160000 --- a/src/sonic-frr/frr +++ b/src/sonic-frr/frr @@ -1 +1 @@ -Subproject commit d49e8f75bd46879c799375f304506dbc5d26230f +Subproject commit 90446e3c3310001a7b84017fa4b237ea7914f45e From 5a4f19e04ae79ef38284c2b0335a13592af855a7 Mon Sep 17 00:00:00 2001 From: B S Rama krishna <54837361+banagiri@users.noreply.github.com> Date: Wed, 29 Jan 2020 22:37:12 +0530 Subject: [PATCH 020/178] [kdump]: porting kdump installation skip on arm to 201911 (#4081) --- files/build_templates/sonic_debian_extension.j2 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index b584407bc2b3..a221e51d61cf 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -163,8 +163,10 @@ sudo LANG=C chroot $FILESYSTEM_ROOT pam-auth-update --remove tacplus sudo sed -i -e '/^passwd/s/ tacplus//' $FILESYSTEM_ROOT/etc/nsswitch.conf # Install a custom version of kdump-tools (and its dependencies via 'apt-get -y install -f') +if [[ $CONFIGURED_ARCH == amd64 ]]; then sudo DEBIAN_FRONTEND=noninteractive dpkg --root=$FILESYSTEM_ROOT -i $debs_path/kdump-tools_*.deb || \ sudo LANG=C DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=truechroot $FILESYSTEM_ROOT apt-get -q --no-install-suggests --no-install-recommends --force-no install +fi # Install custom-built monit package and SONiC configuration files sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/monit_*.deb || \ From d8153280434c6ae60349632f53b4c4decc8419bb Mon Sep 17 00:00:00 2001 From: judyjoseph <53951155+judyjoseph@users.noreply.github.com> Date: Thu, 30 Jan 2020 00:46:55 -0800 Subject: [PATCH 021/178] [teamd]: increase startsecs to 5 seconds for teamsyncd (#4083) Updating the startsecs=5sec for teamsyncd to make the time for which the process needs to stay up before declaring the startup successfull. --- dockers/docker-teamd/supervisord.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/dockers/docker-teamd/supervisord.conf b/dockers/docker-teamd/supervisord.conf index 3a420e0fcdcf..43d6d2d6d116 100644 --- a/dockers/docker-teamd/supervisord.conf +++ b/dockers/docker-teamd/supervisord.conf @@ -36,6 +36,7 @@ stderr_logfile=syslog [program:teamsyncd] command=/usr/bin/teamsyncd priority=3 +startsecs=5 autostart=false autorestart=false stdout_logfile=syslog From a943e6ce4502b9f417a238ac5c94aa797fd913b8 Mon Sep 17 00:00:00 2001 From: Kiran Kumar Kella <45939429+kirankella@users.noreply.github.com> Date: Thu, 30 Jan 2020 07:10:43 +0530 Subject: [PATCH 022/178] Changes in sonic-buildimage to support the NAT feature (#3494) * Changes in sonic-buildimage for the NAT feature - Docker for NAT - installing the required tools iptables and conntrack for nat Signed-off-by: kiran.kella@broadcom.com * Add redis-tools dependencies in the docker nat compilation * Addressed review comments * add natsyncd to warm-boot finalizer list * addressed review comments * using swsscommon.DBConnector instead of swsssdk.SonicV2Connector * Enable NAT application in docker-sonic-vs --- build_debian.sh | 3 +- dockers/docker-nat/Dockerfile.j2 | 46 +++ dockers/docker-nat/base_image_files/natctl | 5 + dockers/docker-nat/restore_nat_entries.py | 104 +++++++ dockers/docker-nat/start.sh | 15 + dockers/docker-nat/supervisord.conf | 47 +++ dockers/docker-orchagent/Dockerfile.j2 | 3 +- files/build_templates/nat.service.j2 | 15 + .../build_templates/sonic_debian_extension.j2 | 4 + .../warmboot-finalizer/finalize-warmboot.sh | 2 +- platform/vs/docker-sonic-vs/start.sh | 4 + platform/vs/docker-sonic-vs/supervisord.conf | 16 ++ rules/docker-nat.mk | 30 ++ rules/iptables.mk | 27 ++ sonic-slave-stretch/Dockerfile.j2 | 3 + src/iptables/Makefile | 47 +++ ...ng-fullcone-option-for-SNAT-and-DNAT.patch | 267 ++++++++++++++++++ src/iptables/patch/series | 1 + 18 files changed, 636 insertions(+), 3 deletions(-) create mode 100644 dockers/docker-nat/Dockerfile.j2 create mode 100644 dockers/docker-nat/base_image_files/natctl create mode 100755 dockers/docker-nat/restore_nat_entries.py create mode 100755 dockers/docker-nat/start.sh create mode 100644 dockers/docker-nat/supervisord.conf create mode 100644 files/build_templates/nat.service.j2 create mode 100644 rules/docker-nat.mk create mode 100644 rules/iptables.mk create mode 100644 src/iptables/Makefile create mode 100644 src/iptables/patch/0001-Passing-fullcone-option-for-SNAT-and-DNAT.patch create mode 100644 src/iptables/patch/series diff --git a/build_debian.sh b/build_debian.sh index cf545ff2fe47..d5820ef5edd5 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -272,7 +272,8 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in cgroup-tools \ ipmitool \ ndisc6 \ - makedumpfile + makedumpfile \ + conntrack if [[ $CONFIGURED_ARCH == amd64 ]]; then diff --git a/dockers/docker-nat/Dockerfile.j2 b/dockers/docker-nat/Dockerfile.j2 new file mode 100644 index 000000000000..3cfbd99e95e1 --- /dev/null +++ b/dockers/docker-nat/Dockerfile.j2 @@ -0,0 +1,46 @@ +{% from "dockers/dockerfile-macros.j2" import install_debian_packages, copy_files %} +FROM docker-config-engine-stretch + +ARG docker_container_name +RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf + +RUN echo + +## Make apt-get non-interactive +ENV DEBIAN_FRONTEND=noninteractive + +## Install redis-tools dependencies +## TODO: implicitly install dependencies +RUN apt-get update \ +&& apt-get install -f -y \ + libdbus-1-3 \ + libdaemon0 \ + libjansson4 \ + libpython2.7 \ + libatomic1 \ + libjemalloc1 \ + liblua5.1-0 \ + lua-bitop \ + lua-cjson \ + libelf1 \ + libmnl0 \ + bridge-utils \ + conntrack + +{% if docker_nat_debs.strip() -%} +# Copy locally-built Debian package dependencies +{{copy_files ("debs/", docker_nat_debs.split(' '), "/debs/") }} + +# Install locally-built Debian packages and implicitly install their dependencies +{{ install_debian_packages(docker_nat_debs.split(' ')) }} +{%- endif %} + +COPY ["start.sh", "/usr/bin/"] +COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["restore_nat_entries.py", "/usr/bin/"] + +RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y +RUN rm -rf /debs + +ENTRYPOINT ["/usr/bin/supervisord"] + diff --git a/dockers/docker-nat/base_image_files/natctl b/dockers/docker-nat/base_image_files/natctl new file mode 100644 index 000000000000..6cba3c86be70 --- /dev/null +++ b/dockers/docker-nat/base_image_files/natctl @@ -0,0 +1,5 @@ +#!/bin/bash + +# -t option needed only for shell, not for commands + +docker exec -i nat natctl "$@" diff --git a/dockers/docker-nat/restore_nat_entries.py b/dockers/docker-nat/restore_nat_entries.py new file mode 100755 index 000000000000..9fb62e82f573 --- /dev/null +++ b/dockers/docker-nat/restore_nat_entries.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python + +"""" +Description: restore_nat_entries.py -- restoring nat entries table into kernel during system warm reboot. + The script is started by supervisord in nat docker when the docker is started. + It does not do anything in case neither system nor nat warm restart is enabled. + In case nat warm restart enabled only, it sets the stateDB flag so natsyncd can continue + the reconciation process. + In case system warm reboot is enabled, it will try to restore the nat entries table into kernel + , then it sets the stateDB flag for natsyncd to continue the + reconciliation process. +""" + +import sys +import subprocess +from swsscommon import swsscommon +import logging +import logging.handlers +import re +import os + +WARM_BOOT_FILE_DIR = '/var/warmboot/nat/' +NAT_WARM_BOOT_FILE = 'nat_entries.dump' +IP_PROTO_TCP = '6' + +MATCH_CONNTRACK_ENTRY = '^(\w+)\s+(\d+).*src=([\d.]+)\s+dst=([\d.]+)\s+sport=(\d+)\s+dport=(\d+).*src=([\d.]+)\s+dst=([\d.]+)\s+sport=(\d+)\s+dport=(\d+)' +REDIS_SOCK = "/var/run/redis/redis.sock" + +logger = logging.getLogger(__name__) +logger.setLevel(logging.INFO) +handler = logging.handlers.SysLogHandler(address = '/dev/log') +logger.addHandler(handler) + +def add_nat_conntrack_entry_in_kernel(ipproto, srcip, dstip, srcport, dstport, natsrcip, natdstip, natsrcport, natdstport): + # pyroute2 doesn't have support for adding conntrack entries via netlink yet. So, invoking the conntrack utility to add the entries. + state = '' + if (ipproto == IP_PROTO_TCP): + state = ' --state ESTABLISHED ' + ctcmd = 'conntrack -I -n ' + natdstip + ':' + natdstport + ' -g ' + natsrcip + ':' + natsrcport + \ + ' --protonum ' + ipproto + state + ' --timeout 600 --src ' + srcip + ' --sport ' + srcport + \ + ' --dst ' + dstip + ' --dport ' + dstport + ' -u ASSURED' + subprocess.call(ctcmd, shell=True) + logger.info("Restored NAT entry: {}".format(ctcmd)) + +# Set the statedb "NAT_RESTORE_TABLE|Flags", so natsyncd can start reconciliation +def set_statedb_nat_restore_done(): + statedb = swsscommon.DBConnector(swsscommon.STATE_DB, REDIS_SOCK, 0) + tbl = swsscommon.Table(statedb, "NAT_RESTORE_TABLE") + fvs = swsscommon.FieldValuePairs([("restored", "true")]) + tbl.set("Flags", fvs) + return + +# This function is to restore the kernel nat entries based on the saved nat entries. +def restore_update_kernel_nat_entries(filename): + # Read the entries from nat_entries.dump file and add them to kernel + conntrack_match_pattern = re.compile(r'{}'.format(MATCH_CONNTRACK_ENTRY)) + with open(filename, 'r') as fp: + for line in fp: + ctline = conntrack_match_pattern.findall(line) + if not ctline: + continue + cmdargs = list(ctline.pop(0)) + proto = cmdargs.pop(0) + if proto not in ('tcp', 'udp'): + continue + add_nat_conntrack_entry_in_kernel(*cmdargs) + +def main(): + logger.info("restore_nat_entries service is started") + + # Use warmstart python binding to check warmstart information + warmstart = swsscommon.WarmStart() + warmstart.initialize("natsyncd", "nat") + warmstart.checkWarmStart("natsyncd", "nat", False) + + # if swss or system warm reboot not enabled, don't run + if not warmstart.isWarmStart(): + logger.info("restore_nat_entries service is skipped as warm restart not enabled") + return + + # NAT restart not system warm reboot, set statedb directly + if not warmstart.isSystemWarmRebootEnabled(): + set_statedb_nat_restore_done() + logger.info("restore_nat_entries service is done as system warm reboot not enabled") + return + + # Program the nat conntrack entries in the kernel by reading the + # entries from nat_entries.dump + try: + restore_update_kernel_nat_entries(WARM_BOOT_FILE_DIR + NAT_WARM_BOOT_FILE) + except Exception as e: + logger.exception(str(e)) + sys.exit(1) + + # Remove the dump file after restoration + os.remove(WARM_BOOT_FILE_DIR + NAT_WARM_BOOT_FILE) + + # set statedb to signal other processes like natsyncd + set_statedb_nat_restore_done() + logger.info("restore_nat_entries service is done for system warmreboot") + return + +if __name__ == '__main__': + main() diff --git a/dockers/docker-nat/start.sh b/dockers/docker-nat/start.sh new file mode 100755 index 000000000000..e1f303fee6f2 --- /dev/null +++ b/dockers/docker-nat/start.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +rm -f /var/run/rsyslogd.pid +rm -f /var/run/nat/* + +mkdir -p /var/warmboot/nat + +supervisorctl start rsyslogd + +supervisorctl start natmgrd + +supervisorctl start natsyncd + +supervisorctl start restore_nat_entries + diff --git a/dockers/docker-nat/supervisord.conf b/dockers/docker-nat/supervisord.conf new file mode 100644 index 000000000000..bb42d23fe355 --- /dev/null +++ b/dockers/docker-nat/supervisord.conf @@ -0,0 +1,47 @@ +[supervisord] +logfile_maxbytes=1MB +logfile_backups=2 +nodaemon=true + +[program:start.sh] +command=/usr/bin/start.sh +priority=1 +autostart=true +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n +priority=2 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + +[program:natmgrd] +command=/usr/bin/natmgrd +priority=3 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + +[program:natsyncd] +command=/usr/bin/natsyncd +priority=4 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + +[program:restore_nat_entries] +command=/usr/bin/restore_nat_entries.py +priority=5 +autostart=false +autorestart=false +startsecs=0 +startretries=0 +stdout_logfile=syslog +stderr_logfile=syslog + diff --git a/dockers/docker-orchagent/Dockerfile.j2 b/dockers/docker-orchagent/Dockerfile.j2 index 8a66e2adbe43..f95acd48fdbd 100755 --- a/dockers/docker-orchagent/Dockerfile.j2 +++ b/dockers/docker-orchagent/Dockerfile.j2 @@ -20,7 +20,8 @@ RUN apt-get update && \ tcpdump \ libelf1 \ libmnl0 \ - bridge-utils + bridge-utils \ + conntrack {% if ( CONFIGURED_ARCH == "armhf" or CONFIGURED_ARCH == "arm64" ) %} ## Fix for gcc/python not found in arm docker diff --git a/files/build_templates/nat.service.j2 b/files/build_templates/nat.service.j2 new file mode 100644 index 000000000000..2e3e17439ef7 --- /dev/null +++ b/files/build_templates/nat.service.j2 @@ -0,0 +1,15 @@ +[Unit] +Description=NAT container +Requires=updategraph.service swss.service +After=updategraph.service swss.service syncd.service +Before=ntp-config.service + +[Service] +User={{ sonicadmin_user }} +ExecStartPre=/usr/bin/{{docker_container_name}}.sh start +ExecStart=/usr/bin/{{docker_container_name}}.sh wait +ExecStop=/usr/bin/{{docker_container_name}}.sh stop + +[Install] +WantedBy=multi-user.target swss.service + diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index a221e51d61cf..a30cc3db9207 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -81,6 +81,10 @@ sudo mkdir -p $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/ifupdown2_*.deb || \ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f +# Install ipables (and its dependencies via 'apt-get -y install -f') +sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/iptables_*.deb || \ + sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f + # Install dependencies for SONiC config engine sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install \ python-dev \ diff --git a/files/image_config/warmboot-finalizer/finalize-warmboot.sh b/files/image_config/warmboot-finalizer/finalize-warmboot.sh index 32c9c8444cc3..ba473feab0ab 100755 --- a/files/image_config/warmboot-finalizer/finalize-warmboot.sh +++ b/files/image_config/warmboot-finalizer/finalize-warmboot.sh @@ -3,7 +3,7 @@ VERBOSE=no # Check components -COMP_LIST="orchagent neighsyncd bgp" +COMP_LIST="orchagent neighsyncd bgp natsyncd" EXP_STATE="reconciled" ASSISTANT_SCRIPT="/usr/bin/neighbor_advertiser" diff --git a/platform/vs/docker-sonic-vs/start.sh b/platform/vs/docker-sonic-vs/start.sh index 614541961c87..dd9fee4deb3d 100755 --- a/platform/vs/docker-sonic-vs/start.sh +++ b/platform/vs/docker-sonic-vs/start.sh @@ -70,6 +70,10 @@ supervisorctl start vxlanmgrd supervisorctl start sflowmgrd +supervisorctl start natmgrd + +supervisorctl start natsyncd + # Start arp_update when VLAN exists VLAN=`sonic-cfggen -d -v 'VLAN.keys() | join(" ") if VLAN'` if [ "$VLAN" != "" ]; then diff --git a/platform/vs/docker-sonic-vs/supervisord.conf b/platform/vs/docker-sonic-vs/supervisord.conf index 143fe49d44a9..3a7acfd20bbe 100644 --- a/platform/vs/docker-sonic-vs/supervisord.conf +++ b/platform/vs/docker-sonic-vs/supervisord.conf @@ -188,3 +188,19 @@ autostart=false autorestart=false stdout_logfile=syslog stderr_logfile=syslog + +[program:natmgrd] +command=/usr/bin/natmgrd +priority=23 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog + +[program:natsyncd] +command=/usr/bin/natsyncd +priority=24 +autostart=false +autorestart=false +stdout_logfile=syslog +stderr_logfile=syslog diff --git a/rules/docker-nat.mk b/rules/docker-nat.mk new file mode 100644 index 000000000000..765b6f7d3b0f --- /dev/null +++ b/rules/docker-nat.mk @@ -0,0 +1,30 @@ +# docker image for nat + +DOCKER_NAT_STEM = docker-nat +DOCKER_NAT = $(DOCKER_NAT_STEM).gz +DOCKER_NAT_DBG = $(DOCKER_NAT_STEM)-$(DBG_IMAGE_MARK).gz + +$(DOCKER_NAT)_PATH = $(DOCKERS_PATH)/$(DOCKER_NAT_STEM) + +$(DOCKER_NAT)_DEPENDS += $(SWSS) $(REDIS_TOOLS) $(IPTABLESIP4TC) $(IPTABLESIP6TC) $(IPTABLESIPTC) $(IPXTABLES12) $(IPTABLES) +$(DOCKER_NAT)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) +$(DOCKER_NAT)_DBG_DEPENDS += $(SWSS_DBG) $(LIBSWSSCOMMON_DBG) +$(DOCKER_NAT)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) + +$(DOCKER_NAT)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) + +SONIC_DOCKER_IMAGES += $(DOCKER_NAT) +SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_NAT) +SONIC_STRETCH_DOCKERS += $(DOCKER_NAT) + +SONIC_DOCKER_DBG_IMAGES += $(DOCKER_NAT_DBG) +SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_NAT_DBG) +SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_NAT_DBG) + +$(DOCKER_NAT)_CONTAINER_NAME = nat +$(DOCKER_NAT)_RUN_OPT += --net=host --privileged -t +$(DOCKER_NAT)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_NAT)_RUN_OPT += -v /host/warmboot:/var/warmboot + +$(DOCKER_NAT)_BASE_IMAGE_FILES += natctl:/usr/bin/natctl + diff --git a/rules/iptables.mk b/rules/iptables.mk new file mode 100644 index 000000000000..4d88c0a224b2 --- /dev/null +++ b/rules/iptables.mk @@ -0,0 +1,27 @@ +# iptables package + +IPTABLES_VERSION = 1.6.0+snapshot20161117 +IPTABLES_VERSION_SUFFIX = 6 +IPTABLES_VERSION_FULL = $(IPTABLES_VERSION)-$(IPTABLES_VERSION_SUFFIX) + +IPTABLES = iptables_$(IPTABLES_VERSION_FULL)_amd64.deb +$(IPTABLES)_SRC_PATH = $(SRC_PATH)/iptables +SONIC_MAKE_DEBS += $(IPTABLES) +SONIC_STRETCH_DEBS += $(IPTABLES) + +IPTABLESIP4TC = libip4tc0_$(IPTABLES_VERSION_FULL)_amd64.deb +$(eval $(call add_derived_package,$(IPTABLES),$(IPTABLESIP4TC))) + +IPTABLESIP6TC = libip6tc0_$(IPTABLES_VERSION_FULL)_amd64.deb +$(eval $(call add_derived_package,$(IPTABLES),$(IPTABLESIP6TC))) + +IPTABLESIPTC = libiptc0_$(IPTABLES_VERSION_FULL)_amd64.deb +$(eval $(call add_derived_package,$(IPTABLES),$(IPTABLESIPTC))) + +IPXTABLES12 = libxtables12_$(IPTABLES_VERSION_FULL)_amd64.deb +$(eval $(call add_derived_package,$(IPTABLES),$(IPXTABLES12))) + +# Export these variables so they can be used in a sub-make +export IPTABLES_VERSION +export IPTABLES_VERSION_FULL +export IPTABLES diff --git a/sonic-slave-stretch/Dockerfile.j2 b/sonic-slave-stretch/Dockerfile.j2 index b3c216d17cf2..d76cccbdc2c8 100644 --- a/sonic-slave-stretch/Dockerfile.j2 +++ b/sonic-slave-stretch/Dockerfile.j2 @@ -294,6 +294,9 @@ RUN apt-get update && apt-get install -y \ libselinux1-dev \ # For kdump-tools liblzo2-dev \ +# For iptables + libnetfilter-conntrack-dev \ + libnftnl-dev \ # For SAI3.7 libprotobuf-dev \ # For DHCP Monitor tool diff --git a/src/iptables/Makefile b/src/iptables/Makefile new file mode 100644 index 000000000000..60154c19ddb1 --- /dev/null +++ b/src/iptables/Makefile @@ -0,0 +1,47 @@ +.ONESHELL: +SHELL = /bin/bash +.SHELLFLAGS += -e + +MAIN_TARGET = $(IPTABLES) +DERIVED_TARGETS = libip4tc0_$(IPTABLES_VERSION_FULL)_amd64.deb \ + libip6tc0_$(IPTABLES_VERSION_FULL)_amd64.deb \ + libiptc0_$(IPTABLES_VERSION_FULL)_amd64.deb \ + libxtables12_$(IPTABLES_VERSION_FULL)_amd64.deb + +IPTABLES_URL = http://deb.debian.org/debian/pool/main/i/iptables + +DSC_FILE = iptables_$(IPTABLES_VERSION_FULL).dsc +ORIG_FILE = iptables_$(IPTABLES_VERSION).orig.tar.bz2 +DEBIAN_FILE = iptables_$(IPTABLES_VERSION_FULL).debian.tar.xz + +DSC_FILE_URL = $(IPTABLES_URL)/$(DSC_FILE) +ORIG_FILE_URL = $(IPTABLES_URL)/$(ORIG_FILE) +DEBIAN_FILE_URL = $(IPTABLES_URL)/$(DEBIAN_FILE) + +$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : + # Remove any stale files + rm -rf ./iptables-$(IPTABLES_VERSION) + + # Get iptables release + wget -NO "$(DSC_FILE)" $(DSC_FILE_URL) + wget -NO "$(ORIG_FILE)" $(ORIG_FILE_URL) + wget -NO "$(DEBIAN_FILE)" $(DEBIAN_FILE_URL) + dpkg-source -x iptables_$(IPTABLES_VERSION_FULL).dsc + + pushd iptables-$(IPTABLES_VERSION) + git init + git add -f * + git commit -m "unmodified iptables source" + + # Apply patches + stg init + stg import -s ../patch/series + + # Build source and Debian packages + dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) + popd + + # Move the newly-built .deb packages to the destination directory + mv $(DERIVED_TARGETS) $* $(DEST)/ + +$(addprefix $(DEST)/, $(DERIVED_TARGETS)): $(DEST)/% : $(DEST)/$(MAIN_TARGET) diff --git a/src/iptables/patch/0001-Passing-fullcone-option-for-SNAT-and-DNAT.patch b/src/iptables/patch/0001-Passing-fullcone-option-for-SNAT-and-DNAT.patch new file mode 100644 index 000000000000..f7fba85a270b --- /dev/null +++ b/src/iptables/patch/0001-Passing-fullcone-option-for-SNAT-and-DNAT.patch @@ -0,0 +1,267 @@ +From 92f5aee7372748845f11b7a10d880f968769e860 Mon Sep 17 00:00:00 2001 +From: Kiran Kella +Date: Wed, 7 Aug 2019 07:22:42 -0700 +Subject: [PATCH] Passing fullcone option for SNAT and DNAT + +--- + extensions/libipt_DNAT.c | 22 +++++++++++++++++++++- + extensions/libipt_MASQUERADE.c | 21 ++++++++++++++++++++- + extensions/libipt_SNAT.c | 22 +++++++++++++++++++++- + 3 files changed, 62 insertions(+), 3 deletions(-) + +diff --git a/extensions/libipt_DNAT.c b/extensions/libipt_DNAT.c +index a14d16f..4bfab98 100644 +--- a/extensions/libipt_DNAT.c ++++ b/extensions/libipt_DNAT.c +@@ -8,14 +8,20 @@ + #include + #include + ++/* Temporarily defining here, need to be picked up from the ++ * new kernel header linux/netfilter/nf_nat.h */ ++#define NF_NAT_RANGE_FULLCONE (1 << 5) ++ + enum { + O_TO_DEST = 0, + O_RANDOM, + O_PERSISTENT, + O_X_TO_DEST, /* hidden flag */ ++ O_FULLCONE, + F_TO_DEST = 1 << O_TO_DEST, + F_RANDOM = 1 << O_RANDOM, + F_X_TO_DEST = 1 << O_X_TO_DEST, ++ F_FULLCONE = 1 << O_FULLCONE + }; + + /* Dest NAT data consists of a multi-range, indicating where to map +@@ -32,7 +38,7 @@ static void DNAT_help(void) + "DNAT target options:\n" + " --to-destination [[-]][:port[-port]]\n" + " Address to map destination to.\n" +-"[--random] [--persistent]\n"); ++"[--random] [--persistent] [--fullcone]\n"); + } + + static const struct xt_option_entry DNAT_opts[] = { +@@ -40,6 +46,7 @@ static const struct xt_option_entry DNAT_opts[] = { + .flags = XTOPT_MAND | XTOPT_MULTI}, + {.name = "random", .id = O_RANDOM, .type = XTTYPE_NONE}, + {.name = "persistent", .id = O_PERSISTENT, .type = XTTYPE_NONE}, ++ {.name = "fullcone", .id = O_FULLCONE, .type = XTTYPE_NONE}, + XTOPT_TABLEEND, + }; + +@@ -185,10 +192,14 @@ static void DNAT_parse(struct xt_option_call *cb) + static void DNAT_fcheck(struct xt_fcheck_call *cb) + { + static const unsigned int f = F_TO_DEST | F_RANDOM; ++ static const unsigned int c = F_FULLCONE; + struct nf_nat_ipv4_multi_range_compat *mr = cb->data; + + if ((cb->xflags & f) == f) + mr->range[0].flags |= NF_NAT_RANGE_PROTO_RANDOM; ++ ++ if ((cb->xflags & c) == c) ++ mr->range[0].flags |= NF_NAT_RANGE_FULLCONE; + } + + static void print_range(const struct nf_nat_ipv4_range *r) +@@ -224,6 +235,8 @@ static void DNAT_print(const void *ip, const struct xt_entry_target *target, + printf(" random"); + if (info->mr.range[i].flags & NF_NAT_RANGE_PERSISTENT) + printf(" persistent"); ++ if (info->mr.range[i].flags & NF_NAT_RANGE_FULLCONE) ++ printf(" fullcone"); + } + } + +@@ -239,6 +252,8 @@ static void DNAT_save(const void *ip, const struct xt_entry_target *target) + printf(" --random"); + if (info->mr.range[i].flags & NF_NAT_RANGE_PERSISTENT) + printf(" --persistent"); ++ if (info->mr.range[i].flags & NF_NAT_RANGE_FULLCONE) ++ printf(" --fullcone"); + } + } + +@@ -282,6 +297,11 @@ static int DNAT_xlate(struct xt_xlate *xl, + sep = ","; + xt_xlate_add(xl, "%spersistent", sep); + } ++ if (info->mr.range[i].flags & NF_NAT_RANGE_FULLCONE) { ++ if (sep_need) ++ sep = ","; ++ xt_xlate_add(xl, "%sfullcone", sep); ++ } + } + + return 1; +diff --git a/extensions/libipt_MASQUERADE.c b/extensions/libipt_MASQUERADE.c +index b7b5fc7..88ff650 100644 +--- a/extensions/libipt_MASQUERADE.c ++++ b/extensions/libipt_MASQUERADE.c +@@ -8,9 +8,15 @@ + #include + #include + ++/* Temporarily defining here, need to be picked up from the ++ * new kernel header linux/netfilter/nf_nat.h */ ++#define NF_NAT_RANGE_FULLCONE (1 << 5) ++ + enum { + O_TO_PORTS = 0, + O_RANDOM, ++ O_RANDOM_FULLY, ++ O_FULLCONE + }; + + static void MASQUERADE_help(void) +@@ -20,12 +26,15 @@ static void MASQUERADE_help(void) + " --to-ports [-]\n" + " Port (range) to map to.\n" + " --random\n" +-" Randomize source port.\n"); ++" Randomize source port.\n" ++" --fullcone\n" ++" Do fullcone NAT mapping.\n"); + } + + static const struct xt_option_entry MASQUERADE_opts[] = { + {.name = "to-ports", .id = O_TO_PORTS, .type = XTTYPE_STRING}, + {.name = "random", .id = O_RANDOM, .type = XTTYPE_NONE}, ++ {.name = "fullcone", .id = O_FULLCONE, .type = XTTYPE_NONE}, + XTOPT_TABLEEND, + }; + +@@ -97,6 +106,9 @@ static void MASQUERADE_parse(struct xt_option_call *cb) + case O_RANDOM: + mr->range[0].flags |= NF_NAT_RANGE_PROTO_RANDOM; + break; ++ case O_FULLCONE: ++ mr->range[0].flags |= NF_NAT_RANGE_FULLCONE; ++ break; + } + } + +@@ -116,6 +128,8 @@ MASQUERADE_print(const void *ip, const struct xt_entry_target *target, + + if (r->flags & NF_NAT_RANGE_PROTO_RANDOM) + printf(" random"); ++ if (r->flags & NF_NAT_RANGE_FULLCONE) ++ printf(" fullcone"); + } + + static void +@@ -132,6 +146,8 @@ MASQUERADE_save(const void *ip, const struct xt_entry_target *target) + + if (r->flags & NF_NAT_RANGE_PROTO_RANDOM) + printf(" --random"); ++ if (r->flags & NF_NAT_RANGE_FULLCONE) ++ printf(" --fullcone"); + } + + static int MASQUERADE_xlate(struct xt_xlate *xl, +@@ -153,6 +169,9 @@ static int MASQUERADE_xlate(struct xt_xlate *xl, + if (r->flags & NF_NAT_RANGE_PROTO_RANDOM) + xt_xlate_add(xl, "random "); + ++ if (r->flags & NF_NAT_RANGE_FULLCONE) ++ xt_xlate_add(xl, "fullcone "); ++ + return 1; + } + +diff --git a/extensions/libipt_SNAT.c b/extensions/libipt_SNAT.c +index e92d811..9634ba9 100644 +--- a/extensions/libipt_SNAT.c ++++ b/extensions/libipt_SNAT.c +@@ -8,16 +8,22 @@ + #include + #include + ++/* Temporarily defining here, need to be picked up from the ++ * new kernel header linux/netfilter/nf_nat.h */ ++#define NF_NAT_RANGE_FULLCONE (1 << 5) ++ + enum { + O_TO_SRC = 0, + O_RANDOM, + O_RANDOM_FULLY, + O_PERSISTENT, + O_X_TO_SRC, ++ O_FULLCONE, + F_TO_SRC = 1 << O_TO_SRC, + F_RANDOM = 1 << O_RANDOM, + F_RANDOM_FULLY = 1 << O_RANDOM_FULLY, + F_X_TO_SRC = 1 << O_X_TO_SRC, ++ F_FULLCONE = 1 << O_FULLCONE + }; + + /* Source NAT data consists of a multi-range, indicating where to map +@@ -34,7 +40,7 @@ static void SNAT_help(void) + "SNAT target options:\n" + " --to-source [[-]][:port[-port]]\n" + " Address to map source to.\n" +-"[--random] [--random-fully] [--persistent]\n"); ++"[--random] [--random-fully] [--persistent] [--fullcone]\n"); + } + + static const struct xt_option_entry SNAT_opts[] = { +@@ -43,6 +49,7 @@ static const struct xt_option_entry SNAT_opts[] = { + {.name = "random", .id = O_RANDOM, .type = XTTYPE_NONE}, + {.name = "random-fully", .id = O_RANDOM_FULLY, .type = XTTYPE_NONE}, + {.name = "persistent", .id = O_PERSISTENT, .type = XTTYPE_NONE}, ++ {.name = "fullcone", .id = O_FULLCONE, .type = XTTYPE_NONE}, + XTOPT_TABLEEND, + }; + +@@ -189,12 +196,15 @@ static void SNAT_fcheck(struct xt_fcheck_call *cb) + { + static const unsigned int f = F_TO_SRC | F_RANDOM; + static const unsigned int r = F_TO_SRC | F_RANDOM_FULLY; ++ static const unsigned int c = F_TO_SRC | F_FULLCONE; + struct nf_nat_ipv4_multi_range_compat *mr = cb->data; + + if ((cb->xflags & f) == f) + mr->range[0].flags |= NF_NAT_RANGE_PROTO_RANDOM; + if ((cb->xflags & r) == r) + mr->range[0].flags |= NF_NAT_RANGE_PROTO_RANDOM_FULLY; ++ if ((cb->xflags & c) == c) ++ mr->range[0].flags |= NF_NAT_RANGE_FULLCONE; + } + + static void print_range(const struct nf_nat_ipv4_range *r) +@@ -232,6 +242,8 @@ static void SNAT_print(const void *ip, const struct xt_entry_target *target, + printf(" random-fully"); + if (info->mr.range[i].flags & NF_NAT_RANGE_PERSISTENT) + printf(" persistent"); ++ if (info->mr.range[i].flags & NF_NAT_RANGE_FULLCONE) ++ printf(" fullcone"); + } + } + +@@ -249,6 +261,8 @@ static void SNAT_save(const void *ip, const struct xt_entry_target *target) + printf(" --random-fully"); + if (info->mr.range[i].flags & NF_NAT_RANGE_PERSISTENT) + printf(" --persistent"); ++ if (info->mr.range[i].flags & NF_NAT_RANGE_FULLCONE) ++ printf(" --fullcone"); + } + } + +@@ -299,6 +313,12 @@ static int SNAT_xlate(struct xt_xlate *xl, + sep = ","; + xt_xlate_add(xl, "%spersistent", sep); + } ++ if (info->mr.range[i].flags & NF_NAT_RANGE_FULLCONE) { ++ if (sep_need) ++ sep = ","; ++ xt_xlate_add(xl, "%sfullcone", sep); ++ sep_need = true; ++ } + } + + return 1; +-- +2.18.0 + diff --git a/src/iptables/patch/series b/src/iptables/patch/series new file mode 100644 index 000000000000..df084ed96ed3 --- /dev/null +++ b/src/iptables/patch/series @@ -0,0 +1 @@ +0001-Passing-fullcone-option-for-SNAT-and-DNAT.patch From 939de3d5ccea874f5b6e2604431d5ef3545de337 Mon Sep 17 00:00:00 2001 From: Arun Saravanan Balachandran <52521751+ArunSaravananBalachandran@users.noreply.github.com> Date: Wed, 4 Dec 2019 00:06:41 +0530 Subject: [PATCH 023/178] DellEMC : Platform2.0 API Implementation [S6100, S6000, Z9100] (#3740) --- .../common/dell_pmc.c | 36 +++++++++----- .../s6000/sonic_platform/chassis.py | 14 +++--- .../s6000/sonic_platform/eeprom.py | 25 +++++++--- .../s6000/sonic_platform/fan.py | 44 +++++++++++++---- .../s6000/sonic_platform/psu.py | 3 ++ .../s6100/scripts/platform_sensors.py | 8 ++-- .../s6100/scripts/s6100_platform.sh | 24 +++++++++- .../s6100/sonic_platform/chassis.py | 15 +++--- .../s6100/sonic_platform/eeprom.py | 27 ++++++++--- .../s6100/sonic_platform/fan.py | 48 ++++++++++++++----- .../s6100/sonic_platform/module.py | 13 ++--- .../z9100/scripts/platform_sensors.py | 8 ++-- .../z9100/sonic_platform/chassis.py | 14 +++--- .../z9100/sonic_platform/fan.py | 48 ++++++++++++++----- 14 files changed, 233 insertions(+), 94 deletions(-) diff --git a/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c b/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c index 7c258cdfeab7..e8cddf4fad11 100644 --- a/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c +++ b/platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c @@ -631,7 +631,7 @@ static ssize_t show_fan(struct device *dev, ret = smf_read_reg16(data, PSU_2_FAN_SPEED); break; case 12: - ret = ~smf_read_reg(data, FAN_TRAY_PRESENCE); + ret = (~smf_read_reg(data, FAN_TRAY_PRESENCE) & 0xff); export_hex = 1; break; @@ -682,14 +682,26 @@ static ssize_t show_fan_alarm(struct device *dev, struct smf_data *data = dev_get_drvdata(dev); int ret, psu_fan_status=0; - if(index < 2) - psu_fan_status = smf_read_reg(data, FAN_STATUS_GROUP_B); + if (data->kind == z9100smf) { + if ((index % 2) == 0) + index = index / 2; + else + index = (index / 2) + 5; + } + + if (data->kind == s6100smf) + index = index / 2; + + if (index > 7) { + psu_fan_status = ~smf_read_reg(data, FAN_STATUS_GROUP_A); + index = index % 8; + } else + psu_fan_status = ~smf_read_reg(data, FAN_STATUS_GROUP_B); if (psu_fan_status & (1 << (index))) ret=0; - - if (ret < 0) - return ret; + else + ret=1; return sprintf(buf, "%d\n", ret); } @@ -726,12 +738,12 @@ static ssize_t show_psu_fan(struct device *dev, if (index < FAN_601_FAULT){ fan_status = smf_read_reg(data, PSU_1_FAN_STATUS); - ret = fan_status & (1 << index); + ret = (fan_status >> index) & 1; } else{ fan_status = smf_read_reg(data, PSU_2_FAN_STATUS); - ret = fan_status & (1 << (index - 3)); + ret = (fan_status >> (index - 3)) & 1; } if (ret < 0) @@ -1319,17 +1331,15 @@ static ssize_t show_current(struct device *dev, else ret = smf_read_reg16(data, SWITCH_CURRENT_Z9100 + index * 2); else if (index < CURR602_INPUT) - curr = smf_read_reg16(data, PSU_1_INPUT_CURRENT + (index % 4) * 2); + ret = smf_read_reg16(data, PSU_1_INPUT_CURRENT + (index % 2) * 2); else - curr = smf_read_reg16(data, PSU_2_INPUT_CURRENT + (index % 4) * 2); + ret = smf_read_reg16(data, PSU_2_INPUT_CURRENT + (index % 4) * 2); if (ret < 0) return ret; - /* TODO: docs say 10mA, value look like A? */ - if(index < 2) - curr = ret*1000; + curr = ret*10; return sprintf(buf, "%d\n", curr); } diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py index 005fdd15b269..c212df88c147 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py @@ -65,7 +65,7 @@ def __init__(self): # Get Transceiver status self.modprs_register = self._get_transceiver_status() - self.sys_eeprom = Eeprom() + self._eeprom = Eeprom() for i in range(MAX_S6000_FAN): fan = Fan(i) self._fan_list.append(fan) @@ -105,7 +105,7 @@ def get_name(self): Returns: string: The name of the chassis """ - return self.sys_eeprom.modelstr() + return self._eeprom.modelstr() def get_presence(self): """ @@ -121,7 +121,7 @@ def get_model(self): Returns: string: Model/part number of chassis """ - return self.sys_eeprom.part_number_str() + return self._eeprom.part_number_str() def get_serial(self): """ @@ -129,7 +129,7 @@ def get_serial(self): Returns: string: Serial number of chassis """ - return self.sys_eeprom.serial_str() + return self._eeprom.serial_str() def get_status(self): """ @@ -148,7 +148,7 @@ def get_base_mac(self): A string containing the MAC address in the format 'XX:XX:XX:XX:XX:XX' """ - return self.sys_eeprom.base_mac_addr() + return self._eeprom.base_mac_addr() def get_serial_number(self): """ @@ -158,7 +158,7 @@ def get_serial_number(self): A string containing the hardware serial number for this chassis. """ - return self.sys_eeprom.serial_number_str() + return self._eeprom.serial_number_str() def get_system_eeprom_info(self): """ @@ -170,7 +170,7 @@ def get_system_eeprom_info(self): OCP ONIE TlvInfo EEPROM format and values are their corresponding values. """ - return self.sys_eeprom.system_eeprom_info() + return self._eeprom.system_eeprom_info() def get_reboot_cause(self): """ diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/eeprom.py index 3d824ba28268..32462e5a256e 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/eeprom.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/eeprom.py @@ -28,14 +28,15 @@ psu_eeprom_format = [ ('PPID', 's', 20), ('DPN Rev', 's', 3), ('Service Tag', 's', 7), ('Part Number', 's', 10), ('Part Num Revision', 's', 3), - ('Mfg Test', 's', 2), ('PSU Type', 's', 1), ('Fab Rev', 's', 2) + ('Mfg Test', 's', 2), ('Redundant copy', 's', 83), ('PSU Type', 's', 1), + ('Fab Rev', 's', 2) ] # Fan eeprom fields in format required by EepromDecoder fan_eeprom_format = [ ('PPID', 's', 20), ('DPN Rev', 's', 3), ('Service Tag', 's', 7), ('Part Number', 's', 10), ('Part Num Revision', 's', 3), - ('Mfg Test', 's', 2), ('Redundant copy', 's', 82), + ('Mfg Test', 's', 2), ('Redundant copy', 's', 83), ('Number of Fans', 's', 1), ('Fan Type', 's', 1), ('Fab Rev', 's', 2) ] @@ -168,11 +169,18 @@ def _load_device_eeprom(self): else: self.part_number = 'NA' - (valid, data) = self._get_eeprom_field("Fan Type") - if valid: - self.fan_type = data + if self.is_psu_eeprom: + (valid, data) = self._get_eeprom_field("PSU Type") + if valid: + self.psu_type = data + else: + self.psu_type = 'NA' else: - self.fan_type = 'NA' + (valid, data) = self._get_eeprom_field("Fan Type") + if valid: + self.fan_type = data + else: + self.fan_type = 'NA' def _get_eeprom_field(self, field_name): """ @@ -204,7 +212,10 @@ def airflow_fan_type(self): """ Returns the airflow fan type. """ - return int(self.fan_type.encode('hex'), 16) + if self.is_psu_eeprom: + return int(self.psu_type.encode('hex'), 16) + else: + return int(self.fan_type.encode('hex'), 16) # System EEPROM specific methods def base_mac_addr(self): diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/fan.py index 3350b4818401..29555b443a22 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/fan.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/fan.py @@ -17,6 +17,7 @@ raise ImportError(str(e) + "- required module not found") +MAX_S6000_PSU_FAN_SPEED = 18000 MAX_S6000_FAN_SPEED = 19000 @@ -26,12 +27,12 @@ class Fan(FanBase): CPLD_DIR = "/sys/devices/platform/dell-s6000-cpld.0/" I2C_DIR = "/sys/class/i2c-adapter/" - def __init__(self, fan_index, psu_fan=False): - # Fan is 1-based in DellEMC platforms - self.index = fan_index + 1 + def __init__(self, fan_index, psu_fan=False, dependency=None): self.is_psu_fan = psu_fan if not self.is_psu_fan: + # Fan is 1-based in DellEMC platforms + self.index = fan_index + 1 self.fan_presence_reg = "fan_prs" self.fan_led_reg = "fan{}_led".format(fan_index) self.get_fan_speed_reg = self.I2C_DIR + "i2c-11/11-0029/" +\ @@ -42,8 +43,13 @@ def __init__(self, fan_index, psu_fan=False): self.max_fan_speed = MAX_S6000_FAN_SPEED self.supported_led_color = ['off', 'green', 'amber'] else: - self.get_fan_speed_reg = self.I2C_DIR + "i2c-1/1-005{}/" +\ - "fan1_input".format(10 - self.index) + self.index = fan_index + self.dependency = dependency + self.get_fan_speed_reg = self.I2C_DIR +\ + "i2c-1/1-005{}/fan1_target".format(10 - self.index) + self.set_fan_speed_reg = self.I2C_DIR +\ + "i2c-1/1-005{}/fan1_target".format(10 - self.index) + self.max_fan_speed = MAX_S6000_PSU_FAN_SPEED def _get_cpld_register(self, reg_name): # On successful read, returns the value read from given @@ -136,6 +142,9 @@ def get_presence(self): bool: True if Fan is present, False if not """ status = False + if self.is_psu_fan: + return self.dependency.get_presence() + fan_presence = self._get_cpld_register(self.fan_presence_reg) if (fan_presence != 'ERR'): fan_presence = int(fan_presence,16) & self.index @@ -151,7 +160,10 @@ def get_model(self): Returns: string: Part number of Fan """ - return self.eeprom.part_number_str() + if not self.is_psu_fan: + return self.eeprom.part_number_str() + else: + return 'NA' def get_serial(self): """ @@ -161,7 +173,10 @@ def get_serial(self): string: Serial number of Fan """ # Sample Serial number format "US-01234D-54321-25A-0123-A00" - return self.eeprom.serial_number_str() + if not self.is_psu_fan: + return self.eeprom.serial_number_str() + else: + return 'NA' def get_status(self): """ @@ -186,8 +201,13 @@ def get_direction(self): A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST depending on fan direction """ - direction = {1: 'FAN_DIRECTION_INTAKE', 2: 'FAN_DIRECTION_EXHAUST'} - fan_direction = self.eeprom.airflow_fan_type() + if self.is_psu_fan: + direction = {1: 'FAN_DIRECTION_EXHAUST', 2: 'FAN_DIRECTION_INTAKE', + 3: 'FAN_DIRECTION_EXHAUST', 4: 'FAN_DIRECTION_INTAKE'} + fan_direction = self.dependency.eeprom.airflow_fan_type() + else: + direction = {1: 'FAN_DIRECTION_EXHAUST', 2: 'FAN_DIRECTION_INTAKE'} + fan_direction = self.eeprom.airflow_fan_type() return direction.get(fan_direction,'NA') @@ -248,7 +268,7 @@ def set_status_led(self, color): Returns: bool: True if set success, False if fail. """ - if color not in self.supported_led_color: + if self.is_psu_fan or (color not in self.supported_led_color): return False if(color == self.STATUS_LED_COLOR_AMBER): color = 'yellow' @@ -266,6 +286,10 @@ def get_status_led(self): Returns: A string, one of the predefined STATUS_LED_COLOR_* strings. """ + if self.is_psu_fan: + # No LED available for PSU Fan + return None + fan_led = self._get_cpld_register(self.fan_led_reg) if (fan_led != 'ERR'): if (fan_led == 'yellow'): diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/psu.py index dfbd2a87eb5d..e2897a78d9fd 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/psu.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/psu.py @@ -13,6 +13,7 @@ import os from sonic_platform_base.psu_base import PsuBase from sonic_platform.eeprom import Eeprom + from sonic_platform.fan import Fan except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -46,6 +47,8 @@ def __init__(self, psu_index): # make it unique per Psu object self._fan_list = [] + self._fan_list.append(Fan(self.index, psu_fan=True, dependency=self)) + def _get_cpld_register(self, reg_name): # On successful read, returns the value read from given # reg_name and on failure returns 'ERR' diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/platform_sensors.py b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/platform_sensors.py index a0231bc507cf..b94b69388300 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/platform_sensors.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/platform_sensors.py @@ -255,8 +255,8 @@ def print_psu(psu): psu_fan_present = int(get_pmc_register('fan11_fault')) input_voltage = float(get_pmc_register('in29_input')) / 1000 output_voltage = float(get_pmc_register('in30_input')) / 1000 - input_current = float(get_pmc_register('curr601_input')) / 100 - output_current = float(get_pmc_register('curr602_input')) / 100 + input_current = float(get_pmc_register('curr601_input')) / 1000 + output_current = float(get_pmc_register('curr602_input')) / 1000 input_power = float(get_pmc_register('power1_input')) / 1000000 output_power = float(get_pmc_register('power2_input')) / 1000000 if (input_power != 0): @@ -268,8 +268,8 @@ def print_psu(psu): psu_fan_present = int(get_pmc_register('fan12_fault')) input_voltage = float(get_pmc_register('in31_input')) / 1000 output_voltage = float(get_pmc_register('in32_input')) / 1000 - input_current = float(get_pmc_register('curr701_input')) / 100 - output_current = float(get_pmc_register('curr702_input')) / 100 + input_current = float(get_pmc_register('curr701_input')) / 1000 + output_current = float(get_pmc_register('curr702_input')) / 1000 input_power = float(get_pmc_register('power3_input')) / 1000000 output_power = float(get_pmc_register('power4_input')) / 1000000 if (input_power != 0): diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh index d8b13ca02c1e..8533d9a198e2 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh @@ -54,6 +54,26 @@ sys_eeprom() { esac } +#Attach/Detach eeprom on each IOM +switch_board_eeprom() { + case $1 in + "new_device") + for ((i=14;i<=17;i++)); + do + i2c_config "echo 24c02 0x50 > /sys/bus/i2c/devices/i2c-$i/$1" + done + ;; + "delete_device") + for ((i=14;i<=17;i++)); + do + i2c_config "echo 0x50 > /sys/bus/i2c/devices/i2c-$i/$1" + done + ;; + *) echo "s6100_platform: switch_board_eeprom : invalid command !" + ;; + esac +} + #Attach/Detach CPLD devices to drivers for each IOM switch_board_cpld() { case $1 in @@ -245,7 +265,7 @@ install_python_api_package() { remove_python_api_package() { rv=$(pip show sonic-platform > /dev/null 2>/dev/null) if [ $? -eq 0 ]; then - rv = $(pip uninstall -y sonic-platform > /dev/null 2>/dev/null) + rv=$(pip uninstall -y sonic-platform > /dev/null 2>/dev/null) fi } @@ -267,6 +287,7 @@ if [[ "$1" == "init" ]]; then cpu_board_mux "new_device" switch_board_mux "new_device" sys_eeprom "new_device" + switch_board_eeprom "new_device" switch_board_cpld "new_device" switch_board_qsfp_mux "new_device" switch_board_sfp "new_device" @@ -280,6 +301,7 @@ elif [[ "$1" == "deinit" ]]; then xcvr_presence_interrupts "disable" switch_board_sfp "delete_device" switch_board_cpld "delete_device" + switch_board_eeprom "delete_device" switch_board_mux "delete_device" sys_eeprom "delete_device" switch_board_qsfp "delete_device" diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py index e39e8480e2c7..ec1848fc8dca 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py @@ -54,10 +54,11 @@ def __init__(self): ChassisBase.__init__(self) # Initialize EEPROM - self.sys_eeprom = Eeprom() + self._eeprom = Eeprom() for i in range(MAX_S6100_MODULE): module = Module(i) self._module_list.append(module) + self._sfp_list.extend(module._sfp_list) for i in range(MAX_S6100_FAN): fan = Fan(i) @@ -107,7 +108,7 @@ def get_name(self): Returns: string: The name of the chassis """ - return self.sys_eeprom.modelstr() + return self._eeprom.modelstr() def get_presence(self): """ @@ -123,7 +124,7 @@ def get_model(self): Returns: string: Model/part number of chassis """ - return self.sys_eeprom.part_number_str() + return self._eeprom.part_number_str() def get_serial(self): """ @@ -131,7 +132,7 @@ def get_serial(self): Returns: string: Serial number of chassis """ - return self.sys_eeprom.serial_str() + return self._eeprom.serial_str() def get_status(self): """ @@ -150,7 +151,7 @@ def get_base_mac(self): A string containing the MAC address in the format 'XX:XX:XX:XX:XX:XX' """ - return self.sys_eeprom.base_mac_addr() + return self._eeprom.base_mac_addr() def get_serial_number(self): """ @@ -160,7 +161,7 @@ def get_serial_number(self): A string containing the hardware serial number for this chassis. """ - return self.sys_eeprom.serial_number_str() + return self._eeprom.serial_number_str() def get_system_eeprom_info(self): """ @@ -170,7 +171,7 @@ def get_system_eeprom_info(self): OCP ONIE TlvInfo EEPROM format and values are their corresponding values. """ - return self.sys_eeprom.system_eeprom_info() + return self._eeprom.system_eeprom_info() def get_reboot_cause(self): """ diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/eeprom.py index 4e683e1e511b..8bd900b6c26b 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/eeprom.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/eeprom.py @@ -18,15 +18,26 @@ class Eeprom(eeprom_tlvinfo.TlvInfoDecoder): - def __init__(self): - self.eeprom_path = "/sys/class/i2c-adapter/i2c-2/2-0050/eeprom" + def __init__(self, i2c_line=0, iom_eeprom=False): + self.is_module = iom_eeprom + if self.is_module: + self.eeprom_path = ("/sys/class/i2c-adapter" + "/i2c-{0}/{0}-0050/eeprom").format(i2c_line) + else: + self.eeprom_path = "/sys/class/i2c-adapter/i2c-2/2-0050/eeprom" super(Eeprom, self).__init__(self.eeprom_path, 0, '', True) self.eeprom_tlv_dict = dict() + try: - self.eeprom_data = self.read_eeprom() + if self.is_module: + self.write_eeprom("\x00\x00") + self.eeprom_data = self.read_eeprom_bytes(256) + else: + self.eeprom_data = self.read_eeprom() except: self.eeprom_data = "N/A" - raise RuntimeError("Eeprom is not Programmed") + if not self.is_module: + raise RuntimeError("Eeprom is not Programmed") else: eeprom = self.eeprom_data @@ -76,8 +87,12 @@ def base_mac_addr(self): return ":".join([binascii.b2a_hex(T) for T in results[2]]) def modelstr(self): - (is_valid, results) = self.get_tlv_field( - self.eeprom_data, self._TLV_CODE_PRODUCT_NAME) + if self.is_module: + (is_valid, results) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_PLATFORM_NAME) + else: + (is_valid, results) = self.get_tlv_field( + self.eeprom_data, self._TLV_CODE_PRODUCT_NAME) if not is_valid: return "N/A" diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan.py index 2aef71b756e7..a2ee0cd10421 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan.py @@ -33,6 +33,10 @@ def __init__(self, fantray_index=1, fan_index=1, psu_fan=False): # from 1 self.fantrayindex = fantray_index + 1 self.fanindex = fan_index + 1 + self.fan_presence_reg = "fan{}_fault".format( + 2 * self.fantrayindex - 1) + self.fan_status_reg = "fan{}_alarm".format( + 2 * self.fantrayindex - 1) self.get_fan_speed_reg = "fan{}_input".format( 2 * self.fantrayindex - 1) self.get_fan_dir_reg = "fan{}_airflow".format( @@ -43,7 +47,9 @@ def __init__(self, fantray_index=1, fan_index=1, psu_fan=False): else: # PSU Fan index starts from 11 self.fanindex = fan_index + 10 + self.fan_presence_reg = "fan{}_fault".format(self.fanindex) self.get_fan_speed_reg = "fan{}_input".format(self.fanindex) + self.get_fan_dir_reg = "fan{}_airflow".format(self.fanindex) self.max_fan_speed = MAX_S6100_PSU_FAN_SPEED def _get_pmc_register(self, reg_name): @@ -84,6 +90,9 @@ def get_model(self): """ # For Serial number "US-01234D-54321-25A-0123-A00", the part # number is "01234D" + if self.is_psu_fan: + return 'NA' + fan_serialno = self._get_pmc_register(self.fan_serialno_reg) if (fan_serialno != 'ERR') and self.get_presence(): if (len(fan_serialno.split('-')) > 1): @@ -102,6 +111,9 @@ def get_serial(self): string: Serial number of FAN """ # Sample Serial number format "US-01234D-54321-25A-0123-A00" + if self.is_psu_fan: + return 'NA' + fan_serialno = self._get_pmc_register(self.fan_serialno_reg) if (fan_serialno == 'ERR') or not self.get_presence(): fan_serialno = 'NA' @@ -115,11 +127,11 @@ def get_presence(self): bool: True if fan is present, False if not """ status = False - fantray_presence = self._get_pmc_register(self.get_fan_speed_reg) + fantray_presence = self._get_pmc_register(self.fan_presence_reg) if (fantray_presence != 'ERR'): fantray_presence = int(fantray_presence, 10) - if (fantray_presence > 0): - status = True + if (~fantray_presence & 0b1): + status = True return status @@ -130,11 +142,18 @@ def get_status(self): bool: True if FAN is operating properly, False if not """ status = False - fantray_status = self._get_pmc_register(self.get_fan_speed_reg) - if (fantray_status != 'ERR'): - fantray_status = int(fantray_status, 10) - if (fantray_status > 5000): - status = True + if self.is_psu_fan: + fantray_status = self._get_pmc_register(self.get_fan_speed_reg) + if (fantray_status != 'ERR'): + fantray_status = int(fantray_status, 10) + if (fantray_status > 5000): + status = True + else: + fantray_status = self._get_pmc_register(self.fan_status_reg) + if (fantray_status != 'ERR'): + fantray_status = int(fantray_status, 10) + if (~fantray_status & 0b1): + status = True return status @@ -216,10 +235,17 @@ def get_status_led(self): Returns: A string, one of the predefined STATUS_LED_COLOR_* strings. """ - if self.get_status(): - return self.STATUS_LED_COLOR_GREEN + if self.is_psu_fan: + # No LED available for PSU Fan + return None else: - return self.STATUS_LED_COLOR_OFF + if self.get_presence(): + if self.get_status(): + return self.STATUS_LED_COLOR_GREEN + else: + return self.STATUS_LED_COLOR_AMBER + else: + return self.STATUS_LED_COLOR_OFF def get_target_speed(self): """ diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/module.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/module.py index 265dc206ad0c..19198098dfd7 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/module.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/module.py @@ -14,6 +14,7 @@ from sonic_platform_base.module_base import ModuleBase from sonic_platform.sfp import Sfp from sonic_platform.component import Component + from sonic_platform.eeprom import Eeprom except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -55,7 +56,7 @@ def __init__(self, module_index): self.port_start = (self.index - 1) * 16 self.port_end = (self.index * 16) - 1 self.port_i2c_line = self.IOM_I2C_MAPPING[self.index] - self.eeprom_tlv_dict = dict() + self._eeprom = Eeprom(iom_eeprom=True, i2c_line=self.port_i2c_line) self.iom_status_reg = "iom_status" self.iom_presence_reg = "iom_presence" @@ -108,7 +109,7 @@ def get_name(self): Returns: string: The name of the device """ - return "IOM{}: 16xQSFP+".format(self.index) + return "IOM{}: {}".format(self.index, self._eeprom.modelstr()) def get_presence(self): """ @@ -133,7 +134,7 @@ def get_model(self): Returns: string: part number of module """ - return 'NA' + return self._eeprom.part_number_str() def get_serial(self): """ @@ -142,7 +143,7 @@ def get_serial(self): Returns: string: Serial number of module """ - return 'NA' + return self._eeprom.serial_str() def get_status(self): """ @@ -178,7 +179,7 @@ def get_serial_number(self): Returns: A string containing the hardware serial number for this module. """ - return 'NA' + return self._eeprom.serial_number_str() def get_system_eeprom_info(self): """ @@ -192,4 +193,4 @@ def get_system_eeprom_info(self): ‘0x24’:’001c0f000fcd0a’, ‘0x25’:’02/03/2018 16:22:00’, ‘0x26’:’01’, ‘0x27’:’REV01’, ‘0x28’:’AG9064-C2358-16G’} """ - return self.eeprom_tlv_dict + return self._eeprom.system_eeprom_info() diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/platform_sensors.py b/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/platform_sensors.py index 76e527e13d73..05cbb3a1a4c1 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/platform_sensors.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/scripts/platform_sensors.py @@ -262,8 +262,8 @@ def print_psu(psu): psu_fan_present = int(get_pmc_register('fan11_fault')) input_voltage = float(get_pmc_register('in29_input')) / 1000 output_voltage = float(get_pmc_register('in30_input')) / 1000 - input_current = float(get_pmc_register('curr601_input')) / 100 - output_current = float(get_pmc_register('curr602_input')) /100 + input_current = float(get_pmc_register('curr601_input')) / 1000 + output_current = float(get_pmc_register('curr602_input')) / 1000 input_power = float(get_pmc_register('power1_input')) / 1000000 output_power = float(get_pmc_register('power2_input')) / 1000000 if (input_power != 0): @@ -275,8 +275,8 @@ def print_psu(psu): psu_fan_present = int(get_pmc_register('fan12_fault')) input_voltage = float(get_pmc_register('in31_input')) / 1000 output_voltage = float(get_pmc_register('in32_input')) / 1000 - input_current = float(get_pmc_register('curr701_input')) / 100 - output_current = float(get_pmc_register('curr702_input')) / 100 + input_current = float(get_pmc_register('curr701_input')) / 1000 + output_current = float(get_pmc_register('curr702_input')) / 1000 input_power = float(get_pmc_register('power3_input')) / 1000000 output_power = float(get_pmc_register('power4_input')) / 1000000 if (input_power != 0): diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py index 3472bb3e7fb0..27164409d962 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py @@ -94,7 +94,7 @@ def __init__(self): ChassisBase.__init__(self) # Initialize EEPROM - self.sys_eeprom = Eeprom() + self._eeprom = Eeprom() for i in range(MAX_Z9100_FANTRAY): for j in range(MAX_Z9100_FAN): fan = Fan(i, j) @@ -137,7 +137,7 @@ def get_name(self): Returns: string: The name of the chassis """ - return self.sys_eeprom.modelstr() + return self._eeprom.modelstr() def get_presence(self): """ @@ -153,7 +153,7 @@ def get_model(self): Returns: string: Model/part number of chassis """ - return self.sys_eeprom.part_number_str() + return self._eeprom.part_number_str() def get_serial(self): """ @@ -161,7 +161,7 @@ def get_serial(self): Returns: string: Serial number of chassis """ - return self.sys_eeprom.serial_str() + return self._eeprom.serial_str() def get_status(self): """ @@ -180,7 +180,7 @@ def get_base_mac(self): A string containing the MAC address in the format 'XX:XX:XX:XX:XX:XX' """ - return self.sys_eeprom.base_mac_addr() + return self._eeprom.base_mac_addr() def get_serial_number(self): """ @@ -189,7 +189,7 @@ def get_serial_number(self): Returns: A string containing the hardware serial number for this chassis. """ - return self.sys_eeprom.serial_number_str() + return self._eeprom.serial_number_str() def get_system_eeprom_info(self): """ @@ -200,7 +200,7 @@ def get_system_eeprom_info(self): OCP ONIE TlvInfo EEPROM format and values are their corresponding values. """ - return self.sys_eeprom.system_eeprom_info() + return self._eeprom.system_eeprom_info() def get_reboot_cause(self): """ diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/fan.py index ae3c5e9fbcab..03ac8cd5c71f 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/fan.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/fan.py @@ -33,6 +33,10 @@ def __init__(self, fantray_index=1, fan_index=1, psu_fan=False): # from 1 self.fantrayindex = fantray_index + 1 self.fanindex = fan_index + 1 + self.fan_presence_reg = "fan{}_fault".format( + 2 * (self.fantrayindex - 1) + (self.fanindex - 1) + 1 ) + self.fan_status_reg = "fan{}_alarm".format( + 2 * (self.fantrayindex - 1) + (self.fanindex - 1) + 1 ) self.get_fan_speed_reg = "fan{}_input".format( 2 * (self.fantrayindex - 1) + (self.fanindex - 1) + 1 ) self.get_fan_dir_reg = "fan{}_airflow".format( @@ -43,7 +47,9 @@ def __init__(self, fantray_index=1, fan_index=1, psu_fan=False): else: # PSU Fan index starts from 11 self.fanindex = fan_index + 10 + self.fan_presence_reg = "fan{}_fault".format(self.fanindex) self.get_fan_speed_reg = "fan{}_input".format(self.fanindex) + self.get_fan_dir_reg = "fan{}_airflow".format(self.fanindex) self.max_fan_speed = MAX_Z9100_PSU_FAN_SPEED def _get_pmc_register(self, reg_name): @@ -83,6 +89,9 @@ def get_model(self): """ # For Serial number "US-01234D-54321-25A-0123-A00", the part # number is "01234D" + if self.is_psu_fan: + return 'NA' + fan_serialno = self._get_pmc_register(self.fan_serialno_reg) if (fan_serialno != 'ERR') and self.get_presence(): if (len(fan_serialno.split('-')) > 1): @@ -101,6 +110,9 @@ def get_serial(self): string: Serial number of FAN """ # Sample Serial number format "US-01234D-54321-25A-0123-A00" + if self.is_psu_fan: + return 'NA' + fan_serialno = self._get_pmc_register(self.fan_serialno_reg) if (fan_serialno == 'ERR') or not self.get_presence(): fan_serialno = 'NA' @@ -114,11 +126,11 @@ def get_presence(self): bool: True if fan is present, False if not """ status = False - fantray_presence = self._get_pmc_register(self.get_fan_speed_reg) + fantray_presence = self._get_pmc_register(self.fan_presence_reg) if (fantray_presence != 'ERR'): fantray_presence = int(fantray_presence, 10) - if (fantray_presence > 0): - status = True + if (~fantray_presence & 0b1): + status = True return status @@ -129,11 +141,18 @@ def get_status(self): bool: True if FAN is operating properly, False if not """ status = False - fantray_status = self._get_pmc_register(self.get_fan_speed_reg) - if (fantray_status != 'ERR'): - fantray_status = int(fantray_status, 10) - if (fantray_status > 5000): - status = True + if self.is_psu_fan: + fantray_status = self._get_pmc_register(self.get_fan_speed_reg) + if (fantray_status != 'ERR'): + fantray_status = int(fantray_status, 10) + if (fantray_status > 5000): + status = True + else: + fantray_status = self._get_pmc_register(self.fan_status_reg) + if (fantray_status != 'ERR'): + fantray_status = int(fantray_status, 10) + if (~fantray_status & 0b1): + status = True return status @@ -215,10 +234,17 @@ def get_status_led(self): Returns: A string, one of the predefined STATUS_LED_COLOR_* strings. """ - if self.get_status(): - return self.STATUS_LED_COLOR_GREEN + if self.is_psu_fan: + # No LED available for PSU Fan + return None else: - return self.STATUS_LED_COLOR_OFF + if self.get_presence(): + if self.get_status(): + return self.STATUS_LED_COLOR_GREEN + else: + return self.STATUS_LED_COLOR_AMBER + else: + return self.STATUS_LED_COLOR_OFF def get_target_speed(self): """ From abe7ef7e2e2e1215c97cee19a83aab0b130cebe5 Mon Sep 17 00:00:00 2001 From: SuvarnaMeenakshi <50386592+SuvarnaMeenakshi@users.noreply.github.com> Date: Sun, 26 Jan 2020 13:56:42 -0800 Subject: [PATCH 024/178] [baseimage]: support building multi-asic component (#3856) - move single instance services into their own folder - generate Systemd templates for any multi-instance service files in slave.mk - detect single or multi-instance platform in systemd-sonic-generator based on asic.conf platform specific file. - update container hostname after creation instead of during creation (docker_image_ctl) - run Docker containers in a network namespace if specified - add a service to create a simulated multi-ASIC topology on the virtual switch platform Signed-off-by: Lawrence Lee Signed-off-by: Suvarna Meenakshi --- device/virtual/x86_64-kvm_x86_64-r0/asic.conf | 1 + .../msft_multi_asic_vs/0/buffers.json.j2 | 3 + .../0/buffers_defaults_def.j2 | 45 ++ .../0/buffers_defaults_t0.j2 | 45 ++ .../0/buffers_defaults_t1.j2 | 45 ++ .../0/pg_profile_lookup.ini | 17 + .../msft_multi_asic_vs/0/port_config.ini | 33 + .../msft_multi_asic_vs/0/qos.json.j2 | 1 + .../msft_multi_asic_vs/0/sai.profile | 2 + .../0/td2-s6000-32x40G.config.bcm | 646 ++++++++++++++++++ .../msft_multi_asic_vs/1/buffers.json.j2 | 3 + .../1/buffers_defaults_def.j2 | 45 ++ .../1/buffers_defaults_t0.j2 | 45 ++ .../1/buffers_defaults_t1.j2 | 45 ++ .../1/pg_profile_lookup.ini | 17 + .../msft_multi_asic_vs/1/port_config.ini | 33 + .../msft_multi_asic_vs/1/qos.json.j2 | 1 + .../msft_multi_asic_vs/1/sai.profile | 2 + .../1/td2-s6000-32x40G.config.bcm | 646 ++++++++++++++++++ .../msft_multi_asic_vs/2/buffers.json.j2 | 3 + .../2/buffers_defaults_def.j2 | 45 ++ .../2/buffers_defaults_t0.j2 | 45 ++ .../2/buffers_defaults_t1.j2 | 45 ++ .../2/pg_profile_lookup.ini | 17 + .../msft_multi_asic_vs/2/port_config.ini | 33 + .../msft_multi_asic_vs/2/qos.json.j2 | 1 + .../msft_multi_asic_vs/2/sai.profile | 2 + .../2/td2-s6000-32x40G.config.bcm | 646 ++++++++++++++++++ .../msft_multi_asic_vs/3/buffers.json.j2 | 3 + .../3/buffers_defaults_def.j2 | 45 ++ .../3/buffers_defaults_t0.j2 | 45 ++ .../3/buffers_defaults_t1.j2 | 45 ++ .../3/pg_profile_lookup.ini | 17 + .../msft_multi_asic_vs/3/port_config.ini | 33 + .../msft_multi_asic_vs/3/qos.json.j2 | 1 + .../msft_multi_asic_vs/3/sai.profile | 2 + .../3/td2-s6000-32x40G.config.bcm | 646 ++++++++++++++++++ .../msft_multi_asic_vs/4/buffers.json.j2 | 3 + .../4/buffers_defaults_def.j2 | 45 ++ .../4/buffers_defaults_t0.j2 | 45 ++ .../4/buffers_defaults_t1.j2 | 45 ++ .../4/pg_profile_lookup.ini | 17 + .../msft_multi_asic_vs/4/port_config.ini | 33 + .../msft_multi_asic_vs/4/qos.json.j2 | 1 + .../msft_multi_asic_vs/4/sai.profile | 2 + .../4/td2-s6000-32x40G.config.bcm | 646 ++++++++++++++++++ .../msft_multi_asic_vs/5/buffers.json.j2 | 3 + .../5/buffers_defaults_def.j2 | 45 ++ .../5/buffers_defaults_t0.j2 | 45 ++ .../5/buffers_defaults_t1.j2 | 45 ++ .../5/pg_profile_lookup.ini | 17 + .../msft_multi_asic_vs/5/port_config.ini | 33 + .../msft_multi_asic_vs/5/qos.json.j2 | 1 + .../msft_multi_asic_vs/5/sai.profile | 2 + .../5/td2-s6000-32x40G.config.bcm | 646 ++++++++++++++++++ .../msft_multi_asic_vs/topology.sh | 81 +++ files/build_templates/docker_image_ctl.j2 | 96 ++- .../{ => single_instance}/bgp.service.j2 | 0 .../{ => single_instance}/database.service.j2 | 0 .../{ => single_instance}/swss.service.j2 | 0 .../{ => single_instance}/syncd.service.j2 | 0 .../{ => single_instance}/teamd.service.j2 | 0 .../build_templates/sonic_debian_extension.j2 | 14 + files/image_config/topology/topology.service | 16 + files/image_config/topology/topology.sh | 30 + platform/template/docker-syncd-base.mk | 2 +- platform/vs/README.vsvm.md | 58 +- platform/vs/sonic_multiasic.xml | 110 +++ rules/docker-database.mk | 2 +- rules/docker-dhcp-relay.mk | 2 +- rules/docker-fpm-frr.mk | 2 +- rules/docker-fpm-gobgp.mk | 2 +- rules/docker-fpm-quagga.mk | 2 +- rules/docker-lldp-sv2.mk | 2 +- rules/docker-orchagent.mk | 2 +- rules/docker-platform-monitor.mk | 2 +- rules/docker-router-advertiser.mk | 2 +- rules/docker-sflow.mk | 2 +- rules/docker-snmp-sv2.mk | 2 +- rules/docker-teamd.mk | 2 +- rules/docker-telemetry.mk | 2 +- slave.mk | 29 +- .../systemd-sonic-generator.c | 378 +++++++++- 83 files changed, 5781 insertions(+), 82 deletions(-) create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/asic.conf create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers.json.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers_defaults_def.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers_defaults_t0.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers_defaults_t1.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/pg_profile_lookup.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/port_config.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/qos.json.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/sai.profile create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/td2-s6000-32x40G.config.bcm create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers.json.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers_defaults_def.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers_defaults_t0.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers_defaults_t1.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/pg_profile_lookup.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/port_config.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/qos.json.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/sai.profile create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/td2-s6000-32x40G.config.bcm create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers.json.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers_defaults_def.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers_defaults_t0.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers_defaults_t1.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/pg_profile_lookup.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/port_config.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/qos.json.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/sai.profile create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/td2-s6000-32x40G.config.bcm create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers.json.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers_defaults_def.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers_defaults_t0.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers_defaults_t1.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/pg_profile_lookup.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/port_config.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/qos.json.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/sai.profile create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/td2-s6000-32x40G.config.bcm create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers.json.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers_defaults_def.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers_defaults_t0.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers_defaults_t1.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/pg_profile_lookup.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/port_config.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/qos.json.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/sai.profile create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/td2-s6000-32x40G.config.bcm create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers.json.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers_defaults_def.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers_defaults_t0.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers_defaults_t1.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/pg_profile_lookup.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/port_config.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/qos.json.j2 create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/sai.profile create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/td2-s6000-32x40G.config.bcm create mode 100755 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/topology.sh rename files/build_templates/{ => single_instance}/bgp.service.j2 (100%) rename files/build_templates/{ => single_instance}/database.service.j2 (100%) rename files/build_templates/{ => single_instance}/swss.service.j2 (100%) rename files/build_templates/{ => single_instance}/syncd.service.j2 (100%) rename files/build_templates/{ => single_instance}/teamd.service.j2 (100%) create mode 100644 files/image_config/topology/topology.service create mode 100755 files/image_config/topology/topology.sh create mode 100644 platform/vs/sonic_multiasic.xml diff --git a/device/virtual/x86_64-kvm_x86_64-r0/asic.conf b/device/virtual/x86_64-kvm_x86_64-r0/asic.conf new file mode 100644 index 000000000000..58c5d5348bb9 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/asic.conf @@ -0,0 +1 @@ +NUM_ASIC=1 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers.json.j2 new file mode 100644 index 000000000000..b67cf577ab75 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers.json.j2 @@ -0,0 +1,3 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} + diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers_defaults_def.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers_defaults_def.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers_defaults_def.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers_defaults_t0.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers_defaults_t0.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers_defaults_t1.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/buffers_defaults_t1.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/pg_profile_lookup.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/pg_profile_lookup.ini new file mode 100644 index 000000000000..9f2eacb6fc42 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 56368 18432 55120 -3 2496 + 25000 5m 56368 18432 55120 -3 2496 + 40000 5m 56368 18432 55120 -3 2496 + 50000 5m 56368 18432 55120 -3 2496 + 100000 5m 56368 18432 55120 -3 2496 + 10000 40m 56368 18432 55120 -3 2496 + 25000 40m 56368 18432 55120 -3 2496 + 40000 40m 56368 18432 55120 -3 2496 + 50000 40m 56368 18432 55120 -3 2496 + 100000 40m 56368 18432 55120 -3 2496 + 10000 300m 56368 18432 55120 -3 2496 + 25000 300m 56368 18432 55120 -3 2496 + 40000 300m 56368 18432 55120 -3 2496 + 50000 300m 56368 18432 55120 -3 2496 + 100000 300m 56368 18432 55120 -3 2496 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/port_config.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/port_config.ini new file mode 100644 index 000000000000..95cf5eec9e4e --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias index speed +Ethernet0 25,26,27,28 fortyGigE0/0 0 40000 +Ethernet4 29,30,31,32 fortyGigE0/4 1 40000 +Ethernet8 33,34,35,36 fortyGigE0/8 2 40000 +Ethernet12 37,38,39,40 fortyGigE0/12 3 40000 +Ethernet16 45,46,47,48 fortyGigE0/16 4 40000 +Ethernet20 41,42,43,44 fortyGigE0/20 5 40000 +Ethernet24 1,2,3,4 fortyGigE0/24 6 40000 +Ethernet28 5,6,7,8 fortyGigE0/28 7 40000 +Ethernet32 13,14,15,16 fortyGigE0/32 8 40000 +Ethernet36 9,10,11,12 fortyGigE0/36 9 40000 +Ethernet40 17,18,19,20 fortyGigE0/40 10 40000 +Ethernet44 21,22,23,24 fortyGigE0/44 11 40000 +Ethernet48 53,54,55,56 fortyGigE0/48 12 40000 +Ethernet52 49,50,51,52 fortyGigE0/52 13 40000 +Ethernet56 57,58,59,60 fortyGigE0/56 14 40000 +Ethernet60 61,62,63,64 fortyGigE0/60 15 40000 +Ethernet64 69,70,71,72 fortyGigE0/64 16 40000 +Ethernet68 65,66,67,68 fortyGigE0/68 17 40000 +Ethernet72 73,74,75,76 fortyGigE0/72 18 40000 +Ethernet76 77,78,79,80 fortyGigE0/76 19 40000 +Ethernet80 109,110,111,112 fortyGigE0/80 20 40000 +Ethernet84 105,106,107,108 fortyGigE0/84 21 40000 +Ethernet88 113,114,115,116 fortyGigE0/88 22 40000 +Ethernet92 117,118,119,120 fortyGigE0/92 23 40000 +Ethernet96 125,126,127,128 fortyGigE0/96 24 40000 +Ethernet100 121,122,123,124 fortyGigE0/100 25 40000 +Ethernet104 81,82,83,84 fortyGigE0/104 26 40000 +Ethernet108 85,86,87,88 fortyGigE0/108 27 40000 +Ethernet112 93,94,95,96 fortyGigE0/112 28 40000 +Ethernet116 89,90,91,92 fortyGigE0/116 29 40000 +Ethernet120 101,102,103,104 fortyGigE0/120 30 40000 +Ethernet124 97,98,99,100 fortyGigE0/124 31 40000 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/qos.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/sai.profile new file mode 100644 index 000000000000..52e2e289af60 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/sai.profile @@ -0,0 +1,2 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm +SAI_NUM_ECMP_MEMBERS=32 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/td2-s6000-32x40G.config.bcm b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/td2-s6000-32x40G.config.bcm new file mode 100644 index 000000000000..4c94db7107c7 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/td2-s6000-32x40G.config.bcm @@ -0,0 +1,646 @@ +# Old LPM only configuration +# l2_mem_entries=163840 +# l3_mem_entries=90112 +# l3_alpm_enable=0 +# ipv6_lpm_128b_enable=0 +# +# ALPM enable +l3_alpm_enable=2 +ipv6_lpm_128b_enable=1 +l2_mem_entries=32768 +l3_mem_entries=16384 + +# From old config file +os=unix +higig2_hdr_mode=1 + +# Parity +parity_correction=1 +parity_enable=1 +stat_if_parity_enable=0 + +# +bcm_num_cos=8 +bcm_stat_interval=2000000 +l2xmsg_hostbuf_size=8192 +l2xmsg_mode=1 +lls_num_l2uc=12 +max_vp_lags=0 +miim_intr_enable=0 +mmu_lossless=0 +module_64ports=0 +schan_intr_enable=0 +stable_size=0x2000000 +tdma_timeout_usec=5000000 + +pbmp_oversubscribe=0x000007fffffffffffffffffffffffffe +pbmp_xport_xe=0x000007fffffffffffffffffffffffffe + +# Ports configuration +# xe0 (40G) +portmap_1=25:40 +xgxs_rx_lane_map_1=0x213 +xgxs_tx_lane_map_1=0x2031 +phy_xaui_rx_polarity_flip_1=0xe +phy_xaui_tx_polarity_flip_1=0x2 +serdes_driver_current_lane0_xe0=0x5 +serdes_driver_current_lane1_xe0=0x5 +serdes_driver_current_lane2_xe0=0x5 +serdes_driver_current_lane3_xe0=0x5 +serdes_pre_driver_current_lane0_xe0=0x5 +serdes_pre_driver_current_lane1_xe0=0x5 +serdes_pre_driver_current_lane2_xe0=0x5 +serdes_pre_driver_current_lane3_xe0=0x5 +serdes_preemphasis_lane0_xe0=0xcad0 +serdes_preemphasis_lane1_xe0=0xc6e0 +serdes_preemphasis_lane2_xe0=0xc6e0 +serdes_preemphasis_lane3_xe0=0xd2b0 + +# xe1 (40G) +portmap_2=29:40 +xgxs_rx_lane_map_2=0x213 +xgxs_tx_lane_map_2=0x213 +phy_xaui_rx_polarity_flip_2=0xc +phy_xaui_tx_polarity_flip_2=0x9 +serdes_driver_current_lane0_xe1=0x6 +serdes_driver_current_lane1_xe1=0x7 +serdes_driver_current_lane2_xe1=0x6 +serdes_driver_current_lane3_xe1=0x6 +serdes_pre_driver_current_lane0_xe1=0x6 +serdes_pre_driver_current_lane1_xe1=0x7 +serdes_pre_driver_current_lane2_xe1=0x6 +serdes_pre_driver_current_lane3_xe1=0x6 +serdes_preemphasis_lane0_xe1=0xc2f0 +serdes_preemphasis_lane1_xe1=0xd2b0 +serdes_preemphasis_lane2_xe1=0xc6e0 +serdes_preemphasis_lane3_xe1=0xc2f0 + +# xe2 (40G) +portmap_3=33:40 +xgxs_rx_lane_map_3=0x213 +xgxs_tx_lane_map_3=0x132 +phy_xaui_rx_polarity_flip_3=0xe +phy_xaui_tx_polarity_flip_3=0x2 +serdes_driver_current_lane0_xe2=0x4 +serdes_driver_current_lane1_xe2=0x4 +serdes_driver_current_lane2_xe2=0x4 +serdes_driver_current_lane3_xe2=0x4 +serdes_pre_driver_current_lane0_xe2=0x4 +serdes_pre_driver_current_lane1_xe2=0x4 +serdes_pre_driver_current_lane2_xe2=0x4 +serdes_pre_driver_current_lane3_xe2=0x4 +serdes_preemphasis_lane0_xe2=0xc6e0 +serdes_preemphasis_lane1_xe2=0xc6e0 +serdes_preemphasis_lane2_xe2=0xc6e0 +serdes_preemphasis_lane3_xe2=0xc6e0 + +# xe3 (40G) +portmap_4=37:40 +xgxs_rx_lane_map_4=0x213 +xgxs_tx_lane_map_4=0x1203 +phy_xaui_rx_polarity_flip_4=0x3 +phy_xaui_tx_polarity_flip_4=0xe +serdes_driver_current_lane0_xe3=0x4 +serdes_driver_current_lane1_xe3=0x4 +serdes_driver_current_lane2_xe3=0x4 +serdes_driver_current_lane3_xe3=0x4 +serdes_pre_driver_current_lane0_xe3=0x4 +serdes_pre_driver_current_lane1_xe3=0x4 +serdes_pre_driver_current_lane2_xe3=0x4 +serdes_pre_driver_current_lane3_xe3=0x4 +serdes_preemphasis_lane0_xe3=0xcad0 +serdes_preemphasis_lane1_xe3=0xcad0 +serdes_preemphasis_lane2_xe3=0xc2f0 +serdes_preemphasis_lane3_xe3=0xc2f0 + +# xe4 (40G) +portmap_5=45:40 +xgxs_rx_lane_map_5=0x213 +xgxs_tx_lane_map_5=0x213 +phy_xaui_rx_polarity_flip_5=0xe +phy_xaui_tx_polarity_flip_5=0x8 +serdes_driver_current_lane0_xe4=0x4 +serdes_driver_current_lane1_xe4=0x4 +serdes_driver_current_lane2_xe4=0x4 +serdes_driver_current_lane3_xe4=0x4 +serdes_pre_driver_current_lane0_xe4=0x4 +serdes_pre_driver_current_lane1_xe4=0x4 +serdes_pre_driver_current_lane2_xe4=0x4 +serdes_pre_driver_current_lane3_xe4=0x4 +serdes_preemphasis_lane0_xe4=0xc2f0 +serdes_preemphasis_lane1_xe4=0xc2f0 +serdes_preemphasis_lane2_xe4=0xc2f0 +serdes_preemphasis_lane3_xe4=0xc2f0 + +# xe5 (40G) +portmap_6=41:40 +xgxs_rx_lane_map_6=0x213 +xgxs_tx_lane_map_6=0x3021 +phy_xaui_rx_polarity_flip_6=0x3 +phy_xaui_tx_polarity_flip_6=0xb +serdes_driver_current_lane0_xe5=0x4 +serdes_driver_current_lane1_xe5=0x4 +serdes_driver_current_lane2_xe5=0x4 +serdes_driver_current_lane3_xe5=0x4 +serdes_pre_driver_current_lane0_xe5=0x4 +serdes_pre_driver_current_lane1_xe5=0x4 +serdes_pre_driver_current_lane2_xe5=0x4 +serdes_pre_driver_current_lane3_xe5=0x4 +serdes_preemphasis_lane0_xe5=0xc6e0 +serdes_preemphasis_lane1_xe5=0xc2f0 +serdes_preemphasis_lane2_xe5=0xc2f0 +serdes_preemphasis_lane3_xe5=0xcad0 + +# xe6 (40G) +portmap_7=1:40 +xgxs_rx_lane_map_7=0x213 +xgxs_tx_lane_map_7=0x2031 +phy_xaui_rx_polarity_flip_7=0xe +phy_xaui_tx_polarity_flip_7=0xd +serdes_driver_current_lane0_xe6=0x5 +serdes_driver_current_lane1_xe6=0x5 +serdes_driver_current_lane2_xe6=0x5 +serdes_driver_current_lane3_xe6=0x5 +serdes_pre_driver_current_lane0_xe6=0x5 +serdes_pre_driver_current_lane1_xe6=0x5 +serdes_pre_driver_current_lane2_xe6=0x5 +serdes_pre_driver_current_lane3_xe6=0x5 +serdes_preemphasis_lane0_xe6=0xc6e0 +serdes_preemphasis_lane1_xe6=0xcad0 +serdes_preemphasis_lane2_xe6=0xc6e0 +serdes_preemphasis_lane3_xe6=0xcad0 + +# xe7 (40G) +portmap_8=5:40 +xgxs_rx_lane_map_8=0x213 +xgxs_tx_lane_map_8=0x1203 +phy_xaui_rx_polarity_flip_8=0xc +phy_xaui_tx_polarity_flip_8=0x1 +serdes_driver_current_lane0_xe7=0x4 +serdes_driver_current_lane1_xe7=0x4 +serdes_driver_current_lane2_xe7=0x4 +serdes_driver_current_lane3_xe7=0x4 +serdes_pre_driver_current_lane0_xe7=0x4 +serdes_pre_driver_current_lane1_xe7=0x4 +serdes_pre_driver_current_lane2_xe7=0x4 +serdes_pre_driver_current_lane3_xe7=0x4 +serdes_preemphasis_lane0_xe7=0xc6e0 +serdes_preemphasis_lane1_xe7=0xc6e0 +serdes_preemphasis_lane2_xe7=0xc6e0 +serdes_preemphasis_lane3_xe7=0xc6e0 + +# xe8 (40G) +portmap_9=13:40 +xgxs_rx_lane_map_9=0x213 +xgxs_tx_lane_map_9=0x132 +phy_xaui_rx_polarity_flip_9=0xe +phy_xaui_tx_polarity_flip_9=0x0 +serdes_driver_current_lane0_xe8=0x2 +serdes_driver_current_lane1_xe8=0x3 +serdes_driver_current_lane2_xe8=0x2 +serdes_driver_current_lane3_xe8=0x2 +serdes_pre_driver_current_lane0_xe8=0x2 +serdes_pre_driver_current_lane1_xe8=0x3 +serdes_pre_driver_current_lane2_xe8=0x2 +serdes_pre_driver_current_lane3_xe8=0x2 +serdes_preemphasis_lane0_xe8=0xb270 +serdes_preemphasis_lane1_xe8=0xbb10 +serdes_preemphasis_lane2_xe8=0xb720 +serdes_preemphasis_lane3_xe8=0xb720 + +# xe9 (40G) +portmap_10=9:40 +xgxs_rx_lane_map_10=0x3120 +xgxs_tx_lane_map_10=0x3021 +phy_xaui_rx_polarity_flip_10=0x0 +phy_xaui_tx_polarity_flip_10=0x4 +serdes_driver_current_lane0_xe9=0x3 +serdes_driver_current_lane1_xe9=0x3 +serdes_driver_current_lane2_xe9=0x3 +serdes_driver_current_lane3_xe9=0x3 +serdes_pre_driver_current_lane0_xe9=0x3 +serdes_pre_driver_current_lane1_xe9=0x3 +serdes_pre_driver_current_lane2_xe9=0x3 +serdes_pre_driver_current_lane3_xe9=0x3 +serdes_preemphasis_lane0_xe9=0xc2f0 +serdes_preemphasis_lane1_xe9=0xc6e0 +serdes_preemphasis_lane2_xe9=0xbf00 +serdes_preemphasis_lane3_xe9=0xc2f0 + +# xe10 (40G) +portmap_11=17:40 +xgxs_rx_lane_map_11=0x213 +xgxs_tx_lane_map_11=0x132 +phy_xaui_rx_polarity_flip_11=0xe +phy_xaui_tx_polarity_flip_11=0x0 +serdes_driver_current_lane0_xe10=0x2 +serdes_driver_current_lane1_xe10=0x2 +serdes_driver_current_lane2_xe10=0x2 +serdes_driver_current_lane3_xe10=0x2 +serdes_pre_driver_current_lane0_xe10=0x2 +serdes_pre_driver_current_lane1_xe10=0x2 +serdes_pre_driver_current_lane2_xe10=0x2 +serdes_pre_driver_current_lane3_xe10=0x2 +serdes_preemphasis_lane0_xe10=0xb330 +serdes_preemphasis_lane1_xe10=0xbb10 +serdes_preemphasis_lane2_xe10=0xbb10 +serdes_preemphasis_lane3_xe10=0xbb10 + +# xe11 (40G) +portmap_12=21:40 +xgxs_rx_lane_map_12=0x123 +xgxs_tx_lane_map_12=0x1203 +phy_xaui_rx_polarity_flip_12=0xc +phy_xaui_tx_polarity_flip_12=0xe +serdes_driver_current_lane0_xe11=0x2 +serdes_driver_current_lane1_xe11=0x2 +serdes_driver_current_lane2_xe11=0x2 +serdes_driver_current_lane3_xe11=0x2 +serdes_pre_driver_current_lane0_xe11=0x2 +serdes_pre_driver_current_lane1_xe11=0x2 +serdes_pre_driver_current_lane2_xe11=0x2 +serdes_pre_driver_current_lane3_xe11=0x2 +serdes_preemphasis_lane0_xe11=0xb330 +serdes_preemphasis_lane1_xe11=0xb330 +serdes_preemphasis_lane2_xe11=0xb330 +serdes_preemphasis_lane3_xe11=0xb330 + +# xe12 (40G) +portmap_13=53:40 +xgxs_rx_lane_map_13=0x213 +xgxs_tx_lane_map_13=0x231 +phy_xaui_rx_polarity_flip_13=0x1 +phy_xaui_tx_polarity_flip_13=0x0 +serdes_driver_current_lane0_xe12=0x2 +serdes_driver_current_lane1_xe12=0x2 +serdes_driver_current_lane2_xe12=0x2 +serdes_driver_current_lane3_xe12=0x2 +serdes_pre_driver_current_lane0_xe12=0x2 +serdes_pre_driver_current_lane1_xe12=0x2 +serdes_pre_driver_current_lane2_xe12=0x2 +serdes_pre_driver_current_lane3_xe12=0x2 +serdes_preemphasis_lane0_xe12=0xaf40 +serdes_preemphasis_lane1_xe12=0xaf40 +serdes_preemphasis_lane2_xe12=0xaf40 +serdes_preemphasis_lane3_xe12=0xaf40 + +# xe13 (40G) +portmap_14=49:40 +xgxs_rx_lane_map_14=0x1302 +xgxs_tx_lane_map_14=0x2031 +phy_xaui_rx_polarity_flip_14=0xb +phy_xaui_tx_polarity_flip_14=0x3 +serdes_driver_current_lane0_xe13=0x2 +serdes_driver_current_lane1_xe13=0x2 +serdes_driver_current_lane2_xe13=0x2 +serdes_driver_current_lane3_xe13=0x2 +serdes_pre_driver_current_lane0_xe13=0x2 +serdes_pre_driver_current_lane1_xe13=0x2 +serdes_pre_driver_current_lane2_xe13=0x2 +serdes_pre_driver_current_lane3_xe13=0x2 +serdes_preemphasis_lane0_xe13=0xa760 +serdes_preemphasis_lane1_xe13=0xa760 +serdes_preemphasis_lane2_xe13=0xa760 +serdes_preemphasis_lane3_xe13=0xa760 + +# xe14 (40G) +portmap_15=57:40 +xgxs_rx_lane_map_15=0x213 +xgxs_tx_lane_map_15=0x2031 +phy_xaui_rx_polarity_flip_15=0x1 +phy_xaui_tx_polarity_flip_15=0x0 +serdes_driver_current_lane0_xe14=0x1 +serdes_driver_current_lane1_xe14=0x1 +serdes_driver_current_lane2_xe14=0x1 +serdes_driver_current_lane3_xe14=0x1 +serdes_pre_driver_current_lane0_xe14=0x1 +serdes_pre_driver_current_lane1_xe14=0x1 +serdes_pre_driver_current_lane2_xe14=0x1 +serdes_pre_driver_current_lane3_xe14=0x1 +serdes_preemphasis_lane0_xe14=0xa760 +serdes_preemphasis_lane1_xe14=0xa760 +serdes_preemphasis_lane2_xe14=0xa760 +serdes_preemphasis_lane3_xe14=0xa760 + +# xe15 (40G) +portmap_16=61:40 +xgxs_rx_lane_map_16=0x132 +xgxs_tx_lane_map_16=0x213 +phy_xaui_rx_polarity_flip_16=0x0 +phy_xaui_tx_polarity_flip_16=0x0 +serdes_driver_current_lane0_xe15=0x2 +serdes_driver_current_lane1_xe15=0x2 +serdes_driver_current_lane2_xe15=0x2 +serdes_driver_current_lane3_xe15=0x2 +serdes_pre_driver_current_lane0_xe15=0x2 +serdes_pre_driver_current_lane1_xe15=0x2 +serdes_pre_driver_current_lane2_xe15=0x2 +serdes_pre_driver_current_lane3_xe15=0x2 +serdes_preemphasis_lane0_xe15=0xa760 +serdes_preemphasis_lane1_xe15=0xa760 +serdes_preemphasis_lane2_xe15=0xa760 +serdes_preemphasis_lane3_xe15=0xa760 + +# xe16 (40G) +portmap_17=69:40 +xgxs_rx_lane_map_17=0x213 +xgxs_tx_lane_map_17=0x2130 +phy_xaui_rx_polarity_flip_17=0x1 +phy_xaui_tx_polarity_flip_17=0xf +serdes_driver_current_lane0_xe16=0x1 +serdes_driver_current_lane1_xe16=0x1 +serdes_driver_current_lane2_xe16=0x1 +serdes_driver_current_lane3_xe16=0x1 +serdes_pre_driver_current_lane0_xe16=0x1 +serdes_pre_driver_current_lane1_xe16=0x1 +serdes_pre_driver_current_lane2_xe16=0x1 +serdes_pre_driver_current_lane3_xe16=0x1 +serdes_preemphasis_lane0_xe16=0xa760 +serdes_preemphasis_lane1_xe16=0xa760 +serdes_preemphasis_lane2_xe16=0xa760 +serdes_preemphasis_lane3_xe16=0xa760 + +# xe17 (40G) +portmap_18=65:40 +xgxs_rx_lane_map_18=0x132 +xgxs_tx_lane_map_18=0x2031 +phy_xaui_rx_polarity_flip_18=0x3 +phy_xaui_tx_polarity_flip_18=0x9 +serdes_driver_current_lane0_xe17=0x1 +serdes_driver_current_lane1_xe17=0x1 +serdes_driver_current_lane2_xe17=0x1 +serdes_driver_current_lane3_xe17=0x1 +serdes_pre_driver_current_lane0_xe17=0x1 +serdes_pre_driver_current_lane1_xe17=0x1 +serdes_pre_driver_current_lane2_xe17=0x1 +serdes_pre_driver_current_lane3_xe17=0x1 +serdes_preemphasis_lane0_xe17=0xa370 +serdes_preemphasis_lane1_xe17=0xa370 +serdes_preemphasis_lane2_xe17=0xa370 +serdes_preemphasis_lane3_xe17=0xa370 + +# xe18 (40G) +portmap_19=73:40 +xgxs_rx_lane_map_19=0x213 +xgxs_tx_lane_map_19=0x2031 +phy_xaui_rx_polarity_flip_19=0x1 +phy_xaui_tx_polarity_flip_19=0x0 +serdes_driver_current_lane0_xe18=0x2 +serdes_driver_current_lane1_xe18=0x2 +serdes_driver_current_lane2_xe18=0x2 +serdes_driver_current_lane3_xe18=0x2 +serdes_pre_driver_current_lane0_xe18=0x2 +serdes_pre_driver_current_lane1_xe18=0x2 +serdes_pre_driver_current_lane2_xe18=0x2 +serdes_pre_driver_current_lane3_xe18=0x2 +serdes_preemphasis_lane0_xe18=0xa760 +serdes_preemphasis_lane1_xe18=0xa760 +serdes_preemphasis_lane2_xe18=0xa760 +serdes_preemphasis_lane3_xe18=0xa760 + +# xe19 (40G) +portmap_20=77:40 +xgxs_rx_lane_map_20=0x123 +xgxs_tx_lane_map_20=0x1203 +phy_xaui_rx_polarity_flip_20=0x3 +phy_xaui_tx_polarity_flip_20=0xe +serdes_driver_current_lane0_xe19=0x2 +serdes_driver_current_lane1_xe19=0x2 +serdes_driver_current_lane2_xe19=0x2 +serdes_driver_current_lane3_xe19=0x2 +serdes_pre_driver_current_lane0_xe19=0x2 +serdes_pre_driver_current_lane1_xe19=0x2 +serdes_pre_driver_current_lane2_xe19=0x2 +serdes_pre_driver_current_lane3_xe19=0x2 +serdes_preemphasis_lane0_xe19=0xaf40 +serdes_preemphasis_lane1_xe19=0xaf40 +serdes_preemphasis_lane2_xe19=0xaf40 +serdes_preemphasis_lane3_xe19=0xaf40 + +# xe20 (40G) +portmap_21=109:40 +xgxs_rx_lane_map_21=0x132 +xgxs_tx_lane_map_21=0x132 +phy_xaui_rx_polarity_flip_21=0x8 +phy_xaui_tx_polarity_flip_21=0x0 +serdes_driver_current_lane0_xe20=0x1 +serdes_driver_current_lane1_xe20=0x1 +serdes_driver_current_lane2_xe20=0x1 +serdes_driver_current_lane3_xe20=0x2 +serdes_pre_driver_current_lane0_xe20=0x1 +serdes_pre_driver_current_lane1_xe20=0x1 +serdes_pre_driver_current_lane2_xe20=0x1 +serdes_pre_driver_current_lane3_xe20=0x2 +serdes_preemphasis_lane0_xe20=0xb330 +serdes_preemphasis_lane1_xe20=0xb330 +serdes_preemphasis_lane2_xe20=0xb330 +serdes_preemphasis_lane3_xe20=0xbff0 + +# xe21 (40G) +portmap_22=105:40 +xgxs_rx_lane_map_22=0x1320 +xgxs_tx_lane_map_22=0x3021 +phy_xaui_rx_polarity_flip_22=0xd +phy_xaui_tx_polarity_flip_22=0xb +serdes_driver_current_lane0_xe21=0x1 +serdes_driver_current_lane1_xe21=0x1 +serdes_driver_current_lane2_xe21=0x1 +serdes_driver_current_lane3_xe21=0x1 +serdes_pre_driver_current_lane0_xe21=0x1 +serdes_pre_driver_current_lane1_xe21=0x1 +serdes_pre_driver_current_lane2_xe21=0x1 +serdes_pre_driver_current_lane3_xe21=0x1 +serdes_preemphasis_lane0_xe21=0xb330 +serdes_preemphasis_lane1_xe21=0xb330 +serdes_preemphasis_lane2_xe21=0xb330 +serdes_preemphasis_lane3_xe21=0xb330 + +# xe22 (40G) +portmap_23=113:40 +xgxs_rx_lane_map_23=0x132 +xgxs_tx_lane_map_23=0x132 +phy_xaui_rx_polarity_flip_23=0x8 +phy_xaui_tx_polarity_flip_23=0x0 +serdes_driver_current_lane0_xe22=0x1 +serdes_driver_current_lane1_xe22=0x1 +serdes_driver_current_lane2_xe22=0x1 +serdes_driver_current_lane3_xe22=0x1 +serdes_pre_driver_current_lane0_xe22=0x1 +serdes_pre_driver_current_lane1_xe22=0x1 +serdes_pre_driver_current_lane2_xe22=0x1 +serdes_pre_driver_current_lane3_xe22=0x1 +serdes_preemphasis_lane0_xe22=0xbb10 +serdes_preemphasis_lane1_xe22=0xbb10 +serdes_preemphasis_lane2_xe22=0xbb10 +serdes_preemphasis_lane3_xe22=0xc2f0 + +# xe23 (40G) +portmap_24=117:40 +xgxs_rx_lane_map_24=0x231 +xgxs_tx_lane_map_24=0x1203 +phy_xaui_rx_polarity_flip_24=0x3 +phy_xaui_tx_polarity_flip_24=0xe +serdes_driver_current_lane0_xe23=0x3 +serdes_driver_current_lane1_xe23=0x5 +serdes_driver_current_lane2_xe23=0x3 +serdes_driver_current_lane3_xe23=0x3 +serdes_pre_driver_current_lane0_xe23=0x3 +serdes_pre_driver_current_lane1_xe23=0x5 +serdes_pre_driver_current_lane2_xe23=0x3 +serdes_pre_driver_current_lane3_xe23=0x3 +serdes_preemphasis_lane0_xe23=0xc6e0 +serdes_preemphasis_lane1_xe23=0xc6e0 +serdes_preemphasis_lane2_xe23=0xc6e0 +serdes_preemphasis_lane3_xe23=0xc6e0 + +# xe24 (40G) +portmap_25=125:40 +xgxs_rx_lane_map_25=0x132 +xgxs_tx_lane_map_25=0x132 +phy_xaui_rx_polarity_flip_25=0x8 +phy_xaui_tx_polarity_flip_25=0x0 +serdes_driver_current_lane0_xe24=0x4 +serdes_driver_current_lane1_xe24=0x4 +serdes_driver_current_lane2_xe24=0x4 +serdes_driver_current_lane3_xe24=0x4 +serdes_pre_driver_current_lane0_xe24=0x4 +serdes_pre_driver_current_lane1_xe24=0x4 +serdes_pre_driver_current_lane2_xe24=0x4 +serdes_pre_driver_current_lane3_xe24=0x4 +serdes_preemphasis_lane0_xe24=0xc6e0 +serdes_preemphasis_lane1_xe24=0xc6e0 +serdes_preemphasis_lane2_xe24=0xc6e0 +serdes_preemphasis_lane3_xe24=0xcec0 + +# xe25 (40G) +portmap_26=121:40 +xgxs_rx_lane_map_26=0x1320 +xgxs_tx_lane_map_26=0x3021 +phy_xaui_rx_polarity_flip_26=0xd +phy_xaui_tx_polarity_flip_26=0xb +serdes_driver_current_lane0_xe25=0x4 +serdes_driver_current_lane1_xe25=0x4 +serdes_driver_current_lane2_xe25=0x4 +serdes_driver_current_lane3_xe25=0x4 +serdes_pre_driver_current_lane0_xe25=0x4 +serdes_pre_driver_current_lane1_xe25=0x4 +serdes_pre_driver_current_lane2_xe25=0x4 +serdes_pre_driver_current_lane3_xe25=0x4 +serdes_preemphasis_lane0_xe25=0xc6e0 +serdes_preemphasis_lane1_xe25=0xc6e0 +serdes_preemphasis_lane2_xe25=0xc6e0 +serdes_preemphasis_lane3_xe25=0xc6e0 + +# xe26 (40G) +portmap_27=81:40 +xgxs_rx_lane_map_27=0x1320 +xgxs_tx_lane_map_27=0x2031 +phy_xaui_rx_polarity_flip_27=0x1 +phy_xaui_tx_polarity_flip_27=0x2 +serdes_driver_current_lane0_xe26=0x2 +serdes_driver_current_lane1_xe26=0x2 +serdes_driver_current_lane2_xe26=0x2 +serdes_driver_current_lane3_xe26=0x2 +serdes_pre_driver_current_lane0_xe26=0x2 +serdes_pre_driver_current_lane1_xe26=0x2 +serdes_pre_driver_current_lane2_xe26=0x2 +serdes_pre_driver_current_lane3_xe26=0x2 +serdes_preemphasis_lane0_xe26=0xbb10 +serdes_preemphasis_lane1_xe26=0xbb10 +serdes_preemphasis_lane2_xe26=0xbf00 +serdes_preemphasis_lane3_xe26=0xbb10 + +# xe27 (40G) +portmap_28=85:40 +xgxs_rx_lane_map_28=0x213 +xgxs_tx_lane_map_28=0x1203 +phy_xaui_rx_polarity_flip_28=0xc +phy_xaui_tx_polarity_flip_28=0xe +serdes_driver_current_lane0_xe27=0x4 +serdes_driver_current_lane1_xe27=0x5 +serdes_driver_current_lane2_xe27=0x4 +serdes_driver_current_lane3_xe27=0x5 +serdes_pre_driver_current_lane0_xe27=0x4 +serdes_pre_driver_current_lane1_xe27=0x5 +serdes_pre_driver_current_lane2_xe27=0x4 +serdes_pre_driver_current_lane3_xe27=0x5 +serdes_preemphasis_lane0_xe27=0xc2f0 +serdes_preemphasis_lane1_xe27=0xc6e0 +serdes_preemphasis_lane2_xe27=0xc6e0 +serdes_preemphasis_lane3_xe27=0xc6e0 + +# xe28 (40G) +portmap_29=93:40 +xgxs_rx_lane_map_29=0x1320 +xgxs_tx_lane_map_29=0x2031 +phy_xaui_rx_polarity_flip_29=0x1 +phy_xaui_tx_polarity_flip_29=0x2 +serdes_driver_current_lane0_xe28=0x4 +serdes_driver_current_lane1_xe28=0x4 +serdes_driver_current_lane2_xe28=0x4 +serdes_driver_current_lane3_xe28=0x4 +serdes_pre_driver_current_lane0_xe28=0x4 +serdes_pre_driver_current_lane1_xe28=0x4 +serdes_pre_driver_current_lane2_xe28=0x4 +serdes_pre_driver_current_lane3_xe28=0x4 +serdes_preemphasis_lane0_xe28=0xc2f0 +serdes_preemphasis_lane1_xe28=0xc2f0 +serdes_preemphasis_lane2_xe28=0xc2f0 +serdes_preemphasis_lane3_xe28=0xc2f0 + +# xe29 (40G) +portmap_30=89:40 +xgxs_rx_lane_map_30=0x1320 +xgxs_tx_lane_map_30=0x3021 +phy_xaui_rx_polarity_flip_30=0x2 +phy_xaui_tx_polarity_flip_30=0xb +serdes_driver_current_lane0_xe29=0x4 +serdes_driver_current_lane1_xe29=0x4 +serdes_driver_current_lane2_xe29=0x4 +serdes_driver_current_lane3_xe29=0x4 +serdes_pre_driver_current_lane0_xe29=0x4 +serdes_pre_driver_current_lane1_xe29=0x4 +serdes_pre_driver_current_lane2_xe29=0x4 +serdes_pre_driver_current_lane3_xe29=0x4 +serdes_preemphasis_lane0_xe29=0xcad0 +serdes_preemphasis_lane1_xe29=0xc6e0 +serdes_preemphasis_lane2_xe29=0xc6e0 +serdes_preemphasis_lane3_xe29=0xc6e0 + +# xe30 (40G) +portmap_31=101:40 +xgxs_rx_lane_map_31=0x1320 +xgxs_tx_lane_map_31=0x1203 +phy_xaui_rx_polarity_flip_31=0x1 +phy_xaui_tx_polarity_flip_31=0x6 +serdes_driver_current_lane0_xe30=0x6 +serdes_driver_current_lane1_xe30=0x6 +serdes_driver_current_lane2_xe30=0x6 +serdes_driver_current_lane3_xe30=0x7 +serdes_pre_driver_current_lane0_xe30=0x6 +serdes_pre_driver_current_lane1_xe30=0x6 +serdes_pre_driver_current_lane2_xe30=0x6 +serdes_pre_driver_current_lane3_xe30=0x7 +serdes_preemphasis_lane0_xe30=0xcec0 +serdes_preemphasis_lane1_xe30=0xcec0 +serdes_preemphasis_lane2_xe30=0xcad0 +serdes_preemphasis_lane3_xe30=0xc6e0 + +# xe31 (40G) +portmap_32=97:40 +xgxs_rx_lane_map_32=0x213 +xgxs_tx_lane_map_32=0x2031 +phy_xaui_rx_polarity_flip_32=0xc +phy_xaui_tx_polarity_flip_32=0x3 +serdes_driver_current_lane0_xe31=0x5 +serdes_driver_current_lane1_xe31=0x5 +serdes_driver_current_lane2_xe31=0x5 +serdes_driver_current_lane3_xe31=0x5 +serdes_pre_driver_current_lane0_xe31=0x5 +serdes_pre_driver_current_lane1_xe31=0x5 +serdes_pre_driver_current_lane2_xe31=0x5 +serdes_pre_driver_current_lane3_xe31=0x5 +serdes_preemphasis_lane0_xe31=0xcad0 +serdes_preemphasis_lane1_xe31=0xcad0 +serdes_preemphasis_lane2_xe31=0xcad0 +serdes_preemphasis_lane3_xe31=0xcad0 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers.json.j2 new file mode 100644 index 000000000000..b67cf577ab75 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers.json.j2 @@ -0,0 +1,3 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} + diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers_defaults_def.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers_defaults_def.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers_defaults_def.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers_defaults_t0.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers_defaults_t0.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers_defaults_t1.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/buffers_defaults_t1.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/pg_profile_lookup.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/pg_profile_lookup.ini new file mode 100644 index 000000000000..9f2eacb6fc42 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 56368 18432 55120 -3 2496 + 25000 5m 56368 18432 55120 -3 2496 + 40000 5m 56368 18432 55120 -3 2496 + 50000 5m 56368 18432 55120 -3 2496 + 100000 5m 56368 18432 55120 -3 2496 + 10000 40m 56368 18432 55120 -3 2496 + 25000 40m 56368 18432 55120 -3 2496 + 40000 40m 56368 18432 55120 -3 2496 + 50000 40m 56368 18432 55120 -3 2496 + 100000 40m 56368 18432 55120 -3 2496 + 10000 300m 56368 18432 55120 -3 2496 + 25000 300m 56368 18432 55120 -3 2496 + 40000 300m 56368 18432 55120 -3 2496 + 50000 300m 56368 18432 55120 -3 2496 + 100000 300m 56368 18432 55120 -3 2496 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/port_config.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/port_config.ini new file mode 100644 index 000000000000..95cf5eec9e4e --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias index speed +Ethernet0 25,26,27,28 fortyGigE0/0 0 40000 +Ethernet4 29,30,31,32 fortyGigE0/4 1 40000 +Ethernet8 33,34,35,36 fortyGigE0/8 2 40000 +Ethernet12 37,38,39,40 fortyGigE0/12 3 40000 +Ethernet16 45,46,47,48 fortyGigE0/16 4 40000 +Ethernet20 41,42,43,44 fortyGigE0/20 5 40000 +Ethernet24 1,2,3,4 fortyGigE0/24 6 40000 +Ethernet28 5,6,7,8 fortyGigE0/28 7 40000 +Ethernet32 13,14,15,16 fortyGigE0/32 8 40000 +Ethernet36 9,10,11,12 fortyGigE0/36 9 40000 +Ethernet40 17,18,19,20 fortyGigE0/40 10 40000 +Ethernet44 21,22,23,24 fortyGigE0/44 11 40000 +Ethernet48 53,54,55,56 fortyGigE0/48 12 40000 +Ethernet52 49,50,51,52 fortyGigE0/52 13 40000 +Ethernet56 57,58,59,60 fortyGigE0/56 14 40000 +Ethernet60 61,62,63,64 fortyGigE0/60 15 40000 +Ethernet64 69,70,71,72 fortyGigE0/64 16 40000 +Ethernet68 65,66,67,68 fortyGigE0/68 17 40000 +Ethernet72 73,74,75,76 fortyGigE0/72 18 40000 +Ethernet76 77,78,79,80 fortyGigE0/76 19 40000 +Ethernet80 109,110,111,112 fortyGigE0/80 20 40000 +Ethernet84 105,106,107,108 fortyGigE0/84 21 40000 +Ethernet88 113,114,115,116 fortyGigE0/88 22 40000 +Ethernet92 117,118,119,120 fortyGigE0/92 23 40000 +Ethernet96 125,126,127,128 fortyGigE0/96 24 40000 +Ethernet100 121,122,123,124 fortyGigE0/100 25 40000 +Ethernet104 81,82,83,84 fortyGigE0/104 26 40000 +Ethernet108 85,86,87,88 fortyGigE0/108 27 40000 +Ethernet112 93,94,95,96 fortyGigE0/112 28 40000 +Ethernet116 89,90,91,92 fortyGigE0/116 29 40000 +Ethernet120 101,102,103,104 fortyGigE0/120 30 40000 +Ethernet124 97,98,99,100 fortyGigE0/124 31 40000 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/qos.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/sai.profile new file mode 100644 index 000000000000..52e2e289af60 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/sai.profile @@ -0,0 +1,2 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm +SAI_NUM_ECMP_MEMBERS=32 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/td2-s6000-32x40G.config.bcm b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/td2-s6000-32x40G.config.bcm new file mode 100644 index 000000000000..4c94db7107c7 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/td2-s6000-32x40G.config.bcm @@ -0,0 +1,646 @@ +# Old LPM only configuration +# l2_mem_entries=163840 +# l3_mem_entries=90112 +# l3_alpm_enable=0 +# ipv6_lpm_128b_enable=0 +# +# ALPM enable +l3_alpm_enable=2 +ipv6_lpm_128b_enable=1 +l2_mem_entries=32768 +l3_mem_entries=16384 + +# From old config file +os=unix +higig2_hdr_mode=1 + +# Parity +parity_correction=1 +parity_enable=1 +stat_if_parity_enable=0 + +# +bcm_num_cos=8 +bcm_stat_interval=2000000 +l2xmsg_hostbuf_size=8192 +l2xmsg_mode=1 +lls_num_l2uc=12 +max_vp_lags=0 +miim_intr_enable=0 +mmu_lossless=0 +module_64ports=0 +schan_intr_enable=0 +stable_size=0x2000000 +tdma_timeout_usec=5000000 + +pbmp_oversubscribe=0x000007fffffffffffffffffffffffffe +pbmp_xport_xe=0x000007fffffffffffffffffffffffffe + +# Ports configuration +# xe0 (40G) +portmap_1=25:40 +xgxs_rx_lane_map_1=0x213 +xgxs_tx_lane_map_1=0x2031 +phy_xaui_rx_polarity_flip_1=0xe +phy_xaui_tx_polarity_flip_1=0x2 +serdes_driver_current_lane0_xe0=0x5 +serdes_driver_current_lane1_xe0=0x5 +serdes_driver_current_lane2_xe0=0x5 +serdes_driver_current_lane3_xe0=0x5 +serdes_pre_driver_current_lane0_xe0=0x5 +serdes_pre_driver_current_lane1_xe0=0x5 +serdes_pre_driver_current_lane2_xe0=0x5 +serdes_pre_driver_current_lane3_xe0=0x5 +serdes_preemphasis_lane0_xe0=0xcad0 +serdes_preemphasis_lane1_xe0=0xc6e0 +serdes_preemphasis_lane2_xe0=0xc6e0 +serdes_preemphasis_lane3_xe0=0xd2b0 + +# xe1 (40G) +portmap_2=29:40 +xgxs_rx_lane_map_2=0x213 +xgxs_tx_lane_map_2=0x213 +phy_xaui_rx_polarity_flip_2=0xc +phy_xaui_tx_polarity_flip_2=0x9 +serdes_driver_current_lane0_xe1=0x6 +serdes_driver_current_lane1_xe1=0x7 +serdes_driver_current_lane2_xe1=0x6 +serdes_driver_current_lane3_xe1=0x6 +serdes_pre_driver_current_lane0_xe1=0x6 +serdes_pre_driver_current_lane1_xe1=0x7 +serdes_pre_driver_current_lane2_xe1=0x6 +serdes_pre_driver_current_lane3_xe1=0x6 +serdes_preemphasis_lane0_xe1=0xc2f0 +serdes_preemphasis_lane1_xe1=0xd2b0 +serdes_preemphasis_lane2_xe1=0xc6e0 +serdes_preemphasis_lane3_xe1=0xc2f0 + +# xe2 (40G) +portmap_3=33:40 +xgxs_rx_lane_map_3=0x213 +xgxs_tx_lane_map_3=0x132 +phy_xaui_rx_polarity_flip_3=0xe +phy_xaui_tx_polarity_flip_3=0x2 +serdes_driver_current_lane0_xe2=0x4 +serdes_driver_current_lane1_xe2=0x4 +serdes_driver_current_lane2_xe2=0x4 +serdes_driver_current_lane3_xe2=0x4 +serdes_pre_driver_current_lane0_xe2=0x4 +serdes_pre_driver_current_lane1_xe2=0x4 +serdes_pre_driver_current_lane2_xe2=0x4 +serdes_pre_driver_current_lane3_xe2=0x4 +serdes_preemphasis_lane0_xe2=0xc6e0 +serdes_preemphasis_lane1_xe2=0xc6e0 +serdes_preemphasis_lane2_xe2=0xc6e0 +serdes_preemphasis_lane3_xe2=0xc6e0 + +# xe3 (40G) +portmap_4=37:40 +xgxs_rx_lane_map_4=0x213 +xgxs_tx_lane_map_4=0x1203 +phy_xaui_rx_polarity_flip_4=0x3 +phy_xaui_tx_polarity_flip_4=0xe +serdes_driver_current_lane0_xe3=0x4 +serdes_driver_current_lane1_xe3=0x4 +serdes_driver_current_lane2_xe3=0x4 +serdes_driver_current_lane3_xe3=0x4 +serdes_pre_driver_current_lane0_xe3=0x4 +serdes_pre_driver_current_lane1_xe3=0x4 +serdes_pre_driver_current_lane2_xe3=0x4 +serdes_pre_driver_current_lane3_xe3=0x4 +serdes_preemphasis_lane0_xe3=0xcad0 +serdes_preemphasis_lane1_xe3=0xcad0 +serdes_preemphasis_lane2_xe3=0xc2f0 +serdes_preemphasis_lane3_xe3=0xc2f0 + +# xe4 (40G) +portmap_5=45:40 +xgxs_rx_lane_map_5=0x213 +xgxs_tx_lane_map_5=0x213 +phy_xaui_rx_polarity_flip_5=0xe +phy_xaui_tx_polarity_flip_5=0x8 +serdes_driver_current_lane0_xe4=0x4 +serdes_driver_current_lane1_xe4=0x4 +serdes_driver_current_lane2_xe4=0x4 +serdes_driver_current_lane3_xe4=0x4 +serdes_pre_driver_current_lane0_xe4=0x4 +serdes_pre_driver_current_lane1_xe4=0x4 +serdes_pre_driver_current_lane2_xe4=0x4 +serdes_pre_driver_current_lane3_xe4=0x4 +serdes_preemphasis_lane0_xe4=0xc2f0 +serdes_preemphasis_lane1_xe4=0xc2f0 +serdes_preemphasis_lane2_xe4=0xc2f0 +serdes_preemphasis_lane3_xe4=0xc2f0 + +# xe5 (40G) +portmap_6=41:40 +xgxs_rx_lane_map_6=0x213 +xgxs_tx_lane_map_6=0x3021 +phy_xaui_rx_polarity_flip_6=0x3 +phy_xaui_tx_polarity_flip_6=0xb +serdes_driver_current_lane0_xe5=0x4 +serdes_driver_current_lane1_xe5=0x4 +serdes_driver_current_lane2_xe5=0x4 +serdes_driver_current_lane3_xe5=0x4 +serdes_pre_driver_current_lane0_xe5=0x4 +serdes_pre_driver_current_lane1_xe5=0x4 +serdes_pre_driver_current_lane2_xe5=0x4 +serdes_pre_driver_current_lane3_xe5=0x4 +serdes_preemphasis_lane0_xe5=0xc6e0 +serdes_preemphasis_lane1_xe5=0xc2f0 +serdes_preemphasis_lane2_xe5=0xc2f0 +serdes_preemphasis_lane3_xe5=0xcad0 + +# xe6 (40G) +portmap_7=1:40 +xgxs_rx_lane_map_7=0x213 +xgxs_tx_lane_map_7=0x2031 +phy_xaui_rx_polarity_flip_7=0xe +phy_xaui_tx_polarity_flip_7=0xd +serdes_driver_current_lane0_xe6=0x5 +serdes_driver_current_lane1_xe6=0x5 +serdes_driver_current_lane2_xe6=0x5 +serdes_driver_current_lane3_xe6=0x5 +serdes_pre_driver_current_lane0_xe6=0x5 +serdes_pre_driver_current_lane1_xe6=0x5 +serdes_pre_driver_current_lane2_xe6=0x5 +serdes_pre_driver_current_lane3_xe6=0x5 +serdes_preemphasis_lane0_xe6=0xc6e0 +serdes_preemphasis_lane1_xe6=0xcad0 +serdes_preemphasis_lane2_xe6=0xc6e0 +serdes_preemphasis_lane3_xe6=0xcad0 + +# xe7 (40G) +portmap_8=5:40 +xgxs_rx_lane_map_8=0x213 +xgxs_tx_lane_map_8=0x1203 +phy_xaui_rx_polarity_flip_8=0xc +phy_xaui_tx_polarity_flip_8=0x1 +serdes_driver_current_lane0_xe7=0x4 +serdes_driver_current_lane1_xe7=0x4 +serdes_driver_current_lane2_xe7=0x4 +serdes_driver_current_lane3_xe7=0x4 +serdes_pre_driver_current_lane0_xe7=0x4 +serdes_pre_driver_current_lane1_xe7=0x4 +serdes_pre_driver_current_lane2_xe7=0x4 +serdes_pre_driver_current_lane3_xe7=0x4 +serdes_preemphasis_lane0_xe7=0xc6e0 +serdes_preemphasis_lane1_xe7=0xc6e0 +serdes_preemphasis_lane2_xe7=0xc6e0 +serdes_preemphasis_lane3_xe7=0xc6e0 + +# xe8 (40G) +portmap_9=13:40 +xgxs_rx_lane_map_9=0x213 +xgxs_tx_lane_map_9=0x132 +phy_xaui_rx_polarity_flip_9=0xe +phy_xaui_tx_polarity_flip_9=0x0 +serdes_driver_current_lane0_xe8=0x2 +serdes_driver_current_lane1_xe8=0x3 +serdes_driver_current_lane2_xe8=0x2 +serdes_driver_current_lane3_xe8=0x2 +serdes_pre_driver_current_lane0_xe8=0x2 +serdes_pre_driver_current_lane1_xe8=0x3 +serdes_pre_driver_current_lane2_xe8=0x2 +serdes_pre_driver_current_lane3_xe8=0x2 +serdes_preemphasis_lane0_xe8=0xb270 +serdes_preemphasis_lane1_xe8=0xbb10 +serdes_preemphasis_lane2_xe8=0xb720 +serdes_preemphasis_lane3_xe8=0xb720 + +# xe9 (40G) +portmap_10=9:40 +xgxs_rx_lane_map_10=0x3120 +xgxs_tx_lane_map_10=0x3021 +phy_xaui_rx_polarity_flip_10=0x0 +phy_xaui_tx_polarity_flip_10=0x4 +serdes_driver_current_lane0_xe9=0x3 +serdes_driver_current_lane1_xe9=0x3 +serdes_driver_current_lane2_xe9=0x3 +serdes_driver_current_lane3_xe9=0x3 +serdes_pre_driver_current_lane0_xe9=0x3 +serdes_pre_driver_current_lane1_xe9=0x3 +serdes_pre_driver_current_lane2_xe9=0x3 +serdes_pre_driver_current_lane3_xe9=0x3 +serdes_preemphasis_lane0_xe9=0xc2f0 +serdes_preemphasis_lane1_xe9=0xc6e0 +serdes_preemphasis_lane2_xe9=0xbf00 +serdes_preemphasis_lane3_xe9=0xc2f0 + +# xe10 (40G) +portmap_11=17:40 +xgxs_rx_lane_map_11=0x213 +xgxs_tx_lane_map_11=0x132 +phy_xaui_rx_polarity_flip_11=0xe +phy_xaui_tx_polarity_flip_11=0x0 +serdes_driver_current_lane0_xe10=0x2 +serdes_driver_current_lane1_xe10=0x2 +serdes_driver_current_lane2_xe10=0x2 +serdes_driver_current_lane3_xe10=0x2 +serdes_pre_driver_current_lane0_xe10=0x2 +serdes_pre_driver_current_lane1_xe10=0x2 +serdes_pre_driver_current_lane2_xe10=0x2 +serdes_pre_driver_current_lane3_xe10=0x2 +serdes_preemphasis_lane0_xe10=0xb330 +serdes_preemphasis_lane1_xe10=0xbb10 +serdes_preemphasis_lane2_xe10=0xbb10 +serdes_preemphasis_lane3_xe10=0xbb10 + +# xe11 (40G) +portmap_12=21:40 +xgxs_rx_lane_map_12=0x123 +xgxs_tx_lane_map_12=0x1203 +phy_xaui_rx_polarity_flip_12=0xc +phy_xaui_tx_polarity_flip_12=0xe +serdes_driver_current_lane0_xe11=0x2 +serdes_driver_current_lane1_xe11=0x2 +serdes_driver_current_lane2_xe11=0x2 +serdes_driver_current_lane3_xe11=0x2 +serdes_pre_driver_current_lane0_xe11=0x2 +serdes_pre_driver_current_lane1_xe11=0x2 +serdes_pre_driver_current_lane2_xe11=0x2 +serdes_pre_driver_current_lane3_xe11=0x2 +serdes_preemphasis_lane0_xe11=0xb330 +serdes_preemphasis_lane1_xe11=0xb330 +serdes_preemphasis_lane2_xe11=0xb330 +serdes_preemphasis_lane3_xe11=0xb330 + +# xe12 (40G) +portmap_13=53:40 +xgxs_rx_lane_map_13=0x213 +xgxs_tx_lane_map_13=0x231 +phy_xaui_rx_polarity_flip_13=0x1 +phy_xaui_tx_polarity_flip_13=0x0 +serdes_driver_current_lane0_xe12=0x2 +serdes_driver_current_lane1_xe12=0x2 +serdes_driver_current_lane2_xe12=0x2 +serdes_driver_current_lane3_xe12=0x2 +serdes_pre_driver_current_lane0_xe12=0x2 +serdes_pre_driver_current_lane1_xe12=0x2 +serdes_pre_driver_current_lane2_xe12=0x2 +serdes_pre_driver_current_lane3_xe12=0x2 +serdes_preemphasis_lane0_xe12=0xaf40 +serdes_preemphasis_lane1_xe12=0xaf40 +serdes_preemphasis_lane2_xe12=0xaf40 +serdes_preemphasis_lane3_xe12=0xaf40 + +# xe13 (40G) +portmap_14=49:40 +xgxs_rx_lane_map_14=0x1302 +xgxs_tx_lane_map_14=0x2031 +phy_xaui_rx_polarity_flip_14=0xb +phy_xaui_tx_polarity_flip_14=0x3 +serdes_driver_current_lane0_xe13=0x2 +serdes_driver_current_lane1_xe13=0x2 +serdes_driver_current_lane2_xe13=0x2 +serdes_driver_current_lane3_xe13=0x2 +serdes_pre_driver_current_lane0_xe13=0x2 +serdes_pre_driver_current_lane1_xe13=0x2 +serdes_pre_driver_current_lane2_xe13=0x2 +serdes_pre_driver_current_lane3_xe13=0x2 +serdes_preemphasis_lane0_xe13=0xa760 +serdes_preemphasis_lane1_xe13=0xa760 +serdes_preemphasis_lane2_xe13=0xa760 +serdes_preemphasis_lane3_xe13=0xa760 + +# xe14 (40G) +portmap_15=57:40 +xgxs_rx_lane_map_15=0x213 +xgxs_tx_lane_map_15=0x2031 +phy_xaui_rx_polarity_flip_15=0x1 +phy_xaui_tx_polarity_flip_15=0x0 +serdes_driver_current_lane0_xe14=0x1 +serdes_driver_current_lane1_xe14=0x1 +serdes_driver_current_lane2_xe14=0x1 +serdes_driver_current_lane3_xe14=0x1 +serdes_pre_driver_current_lane0_xe14=0x1 +serdes_pre_driver_current_lane1_xe14=0x1 +serdes_pre_driver_current_lane2_xe14=0x1 +serdes_pre_driver_current_lane3_xe14=0x1 +serdes_preemphasis_lane0_xe14=0xa760 +serdes_preemphasis_lane1_xe14=0xa760 +serdes_preemphasis_lane2_xe14=0xa760 +serdes_preemphasis_lane3_xe14=0xa760 + +# xe15 (40G) +portmap_16=61:40 +xgxs_rx_lane_map_16=0x132 +xgxs_tx_lane_map_16=0x213 +phy_xaui_rx_polarity_flip_16=0x0 +phy_xaui_tx_polarity_flip_16=0x0 +serdes_driver_current_lane0_xe15=0x2 +serdes_driver_current_lane1_xe15=0x2 +serdes_driver_current_lane2_xe15=0x2 +serdes_driver_current_lane3_xe15=0x2 +serdes_pre_driver_current_lane0_xe15=0x2 +serdes_pre_driver_current_lane1_xe15=0x2 +serdes_pre_driver_current_lane2_xe15=0x2 +serdes_pre_driver_current_lane3_xe15=0x2 +serdes_preemphasis_lane0_xe15=0xa760 +serdes_preemphasis_lane1_xe15=0xa760 +serdes_preemphasis_lane2_xe15=0xa760 +serdes_preemphasis_lane3_xe15=0xa760 + +# xe16 (40G) +portmap_17=69:40 +xgxs_rx_lane_map_17=0x213 +xgxs_tx_lane_map_17=0x2130 +phy_xaui_rx_polarity_flip_17=0x1 +phy_xaui_tx_polarity_flip_17=0xf +serdes_driver_current_lane0_xe16=0x1 +serdes_driver_current_lane1_xe16=0x1 +serdes_driver_current_lane2_xe16=0x1 +serdes_driver_current_lane3_xe16=0x1 +serdes_pre_driver_current_lane0_xe16=0x1 +serdes_pre_driver_current_lane1_xe16=0x1 +serdes_pre_driver_current_lane2_xe16=0x1 +serdes_pre_driver_current_lane3_xe16=0x1 +serdes_preemphasis_lane0_xe16=0xa760 +serdes_preemphasis_lane1_xe16=0xa760 +serdes_preemphasis_lane2_xe16=0xa760 +serdes_preemphasis_lane3_xe16=0xa760 + +# xe17 (40G) +portmap_18=65:40 +xgxs_rx_lane_map_18=0x132 +xgxs_tx_lane_map_18=0x2031 +phy_xaui_rx_polarity_flip_18=0x3 +phy_xaui_tx_polarity_flip_18=0x9 +serdes_driver_current_lane0_xe17=0x1 +serdes_driver_current_lane1_xe17=0x1 +serdes_driver_current_lane2_xe17=0x1 +serdes_driver_current_lane3_xe17=0x1 +serdes_pre_driver_current_lane0_xe17=0x1 +serdes_pre_driver_current_lane1_xe17=0x1 +serdes_pre_driver_current_lane2_xe17=0x1 +serdes_pre_driver_current_lane3_xe17=0x1 +serdes_preemphasis_lane0_xe17=0xa370 +serdes_preemphasis_lane1_xe17=0xa370 +serdes_preemphasis_lane2_xe17=0xa370 +serdes_preemphasis_lane3_xe17=0xa370 + +# xe18 (40G) +portmap_19=73:40 +xgxs_rx_lane_map_19=0x213 +xgxs_tx_lane_map_19=0x2031 +phy_xaui_rx_polarity_flip_19=0x1 +phy_xaui_tx_polarity_flip_19=0x0 +serdes_driver_current_lane0_xe18=0x2 +serdes_driver_current_lane1_xe18=0x2 +serdes_driver_current_lane2_xe18=0x2 +serdes_driver_current_lane3_xe18=0x2 +serdes_pre_driver_current_lane0_xe18=0x2 +serdes_pre_driver_current_lane1_xe18=0x2 +serdes_pre_driver_current_lane2_xe18=0x2 +serdes_pre_driver_current_lane3_xe18=0x2 +serdes_preemphasis_lane0_xe18=0xa760 +serdes_preemphasis_lane1_xe18=0xa760 +serdes_preemphasis_lane2_xe18=0xa760 +serdes_preemphasis_lane3_xe18=0xa760 + +# xe19 (40G) +portmap_20=77:40 +xgxs_rx_lane_map_20=0x123 +xgxs_tx_lane_map_20=0x1203 +phy_xaui_rx_polarity_flip_20=0x3 +phy_xaui_tx_polarity_flip_20=0xe +serdes_driver_current_lane0_xe19=0x2 +serdes_driver_current_lane1_xe19=0x2 +serdes_driver_current_lane2_xe19=0x2 +serdes_driver_current_lane3_xe19=0x2 +serdes_pre_driver_current_lane0_xe19=0x2 +serdes_pre_driver_current_lane1_xe19=0x2 +serdes_pre_driver_current_lane2_xe19=0x2 +serdes_pre_driver_current_lane3_xe19=0x2 +serdes_preemphasis_lane0_xe19=0xaf40 +serdes_preemphasis_lane1_xe19=0xaf40 +serdes_preemphasis_lane2_xe19=0xaf40 +serdes_preemphasis_lane3_xe19=0xaf40 + +# xe20 (40G) +portmap_21=109:40 +xgxs_rx_lane_map_21=0x132 +xgxs_tx_lane_map_21=0x132 +phy_xaui_rx_polarity_flip_21=0x8 +phy_xaui_tx_polarity_flip_21=0x0 +serdes_driver_current_lane0_xe20=0x1 +serdes_driver_current_lane1_xe20=0x1 +serdes_driver_current_lane2_xe20=0x1 +serdes_driver_current_lane3_xe20=0x2 +serdes_pre_driver_current_lane0_xe20=0x1 +serdes_pre_driver_current_lane1_xe20=0x1 +serdes_pre_driver_current_lane2_xe20=0x1 +serdes_pre_driver_current_lane3_xe20=0x2 +serdes_preemphasis_lane0_xe20=0xb330 +serdes_preemphasis_lane1_xe20=0xb330 +serdes_preemphasis_lane2_xe20=0xb330 +serdes_preemphasis_lane3_xe20=0xbff0 + +# xe21 (40G) +portmap_22=105:40 +xgxs_rx_lane_map_22=0x1320 +xgxs_tx_lane_map_22=0x3021 +phy_xaui_rx_polarity_flip_22=0xd +phy_xaui_tx_polarity_flip_22=0xb +serdes_driver_current_lane0_xe21=0x1 +serdes_driver_current_lane1_xe21=0x1 +serdes_driver_current_lane2_xe21=0x1 +serdes_driver_current_lane3_xe21=0x1 +serdes_pre_driver_current_lane0_xe21=0x1 +serdes_pre_driver_current_lane1_xe21=0x1 +serdes_pre_driver_current_lane2_xe21=0x1 +serdes_pre_driver_current_lane3_xe21=0x1 +serdes_preemphasis_lane0_xe21=0xb330 +serdes_preemphasis_lane1_xe21=0xb330 +serdes_preemphasis_lane2_xe21=0xb330 +serdes_preemphasis_lane3_xe21=0xb330 + +# xe22 (40G) +portmap_23=113:40 +xgxs_rx_lane_map_23=0x132 +xgxs_tx_lane_map_23=0x132 +phy_xaui_rx_polarity_flip_23=0x8 +phy_xaui_tx_polarity_flip_23=0x0 +serdes_driver_current_lane0_xe22=0x1 +serdes_driver_current_lane1_xe22=0x1 +serdes_driver_current_lane2_xe22=0x1 +serdes_driver_current_lane3_xe22=0x1 +serdes_pre_driver_current_lane0_xe22=0x1 +serdes_pre_driver_current_lane1_xe22=0x1 +serdes_pre_driver_current_lane2_xe22=0x1 +serdes_pre_driver_current_lane3_xe22=0x1 +serdes_preemphasis_lane0_xe22=0xbb10 +serdes_preemphasis_lane1_xe22=0xbb10 +serdes_preemphasis_lane2_xe22=0xbb10 +serdes_preemphasis_lane3_xe22=0xc2f0 + +# xe23 (40G) +portmap_24=117:40 +xgxs_rx_lane_map_24=0x231 +xgxs_tx_lane_map_24=0x1203 +phy_xaui_rx_polarity_flip_24=0x3 +phy_xaui_tx_polarity_flip_24=0xe +serdes_driver_current_lane0_xe23=0x3 +serdes_driver_current_lane1_xe23=0x5 +serdes_driver_current_lane2_xe23=0x3 +serdes_driver_current_lane3_xe23=0x3 +serdes_pre_driver_current_lane0_xe23=0x3 +serdes_pre_driver_current_lane1_xe23=0x5 +serdes_pre_driver_current_lane2_xe23=0x3 +serdes_pre_driver_current_lane3_xe23=0x3 +serdes_preemphasis_lane0_xe23=0xc6e0 +serdes_preemphasis_lane1_xe23=0xc6e0 +serdes_preemphasis_lane2_xe23=0xc6e0 +serdes_preemphasis_lane3_xe23=0xc6e0 + +# xe24 (40G) +portmap_25=125:40 +xgxs_rx_lane_map_25=0x132 +xgxs_tx_lane_map_25=0x132 +phy_xaui_rx_polarity_flip_25=0x8 +phy_xaui_tx_polarity_flip_25=0x0 +serdes_driver_current_lane0_xe24=0x4 +serdes_driver_current_lane1_xe24=0x4 +serdes_driver_current_lane2_xe24=0x4 +serdes_driver_current_lane3_xe24=0x4 +serdes_pre_driver_current_lane0_xe24=0x4 +serdes_pre_driver_current_lane1_xe24=0x4 +serdes_pre_driver_current_lane2_xe24=0x4 +serdes_pre_driver_current_lane3_xe24=0x4 +serdes_preemphasis_lane0_xe24=0xc6e0 +serdes_preemphasis_lane1_xe24=0xc6e0 +serdes_preemphasis_lane2_xe24=0xc6e0 +serdes_preemphasis_lane3_xe24=0xcec0 + +# xe25 (40G) +portmap_26=121:40 +xgxs_rx_lane_map_26=0x1320 +xgxs_tx_lane_map_26=0x3021 +phy_xaui_rx_polarity_flip_26=0xd +phy_xaui_tx_polarity_flip_26=0xb +serdes_driver_current_lane0_xe25=0x4 +serdes_driver_current_lane1_xe25=0x4 +serdes_driver_current_lane2_xe25=0x4 +serdes_driver_current_lane3_xe25=0x4 +serdes_pre_driver_current_lane0_xe25=0x4 +serdes_pre_driver_current_lane1_xe25=0x4 +serdes_pre_driver_current_lane2_xe25=0x4 +serdes_pre_driver_current_lane3_xe25=0x4 +serdes_preemphasis_lane0_xe25=0xc6e0 +serdes_preemphasis_lane1_xe25=0xc6e0 +serdes_preemphasis_lane2_xe25=0xc6e0 +serdes_preemphasis_lane3_xe25=0xc6e0 + +# xe26 (40G) +portmap_27=81:40 +xgxs_rx_lane_map_27=0x1320 +xgxs_tx_lane_map_27=0x2031 +phy_xaui_rx_polarity_flip_27=0x1 +phy_xaui_tx_polarity_flip_27=0x2 +serdes_driver_current_lane0_xe26=0x2 +serdes_driver_current_lane1_xe26=0x2 +serdes_driver_current_lane2_xe26=0x2 +serdes_driver_current_lane3_xe26=0x2 +serdes_pre_driver_current_lane0_xe26=0x2 +serdes_pre_driver_current_lane1_xe26=0x2 +serdes_pre_driver_current_lane2_xe26=0x2 +serdes_pre_driver_current_lane3_xe26=0x2 +serdes_preemphasis_lane0_xe26=0xbb10 +serdes_preemphasis_lane1_xe26=0xbb10 +serdes_preemphasis_lane2_xe26=0xbf00 +serdes_preemphasis_lane3_xe26=0xbb10 + +# xe27 (40G) +portmap_28=85:40 +xgxs_rx_lane_map_28=0x213 +xgxs_tx_lane_map_28=0x1203 +phy_xaui_rx_polarity_flip_28=0xc +phy_xaui_tx_polarity_flip_28=0xe +serdes_driver_current_lane0_xe27=0x4 +serdes_driver_current_lane1_xe27=0x5 +serdes_driver_current_lane2_xe27=0x4 +serdes_driver_current_lane3_xe27=0x5 +serdes_pre_driver_current_lane0_xe27=0x4 +serdes_pre_driver_current_lane1_xe27=0x5 +serdes_pre_driver_current_lane2_xe27=0x4 +serdes_pre_driver_current_lane3_xe27=0x5 +serdes_preemphasis_lane0_xe27=0xc2f0 +serdes_preemphasis_lane1_xe27=0xc6e0 +serdes_preemphasis_lane2_xe27=0xc6e0 +serdes_preemphasis_lane3_xe27=0xc6e0 + +# xe28 (40G) +portmap_29=93:40 +xgxs_rx_lane_map_29=0x1320 +xgxs_tx_lane_map_29=0x2031 +phy_xaui_rx_polarity_flip_29=0x1 +phy_xaui_tx_polarity_flip_29=0x2 +serdes_driver_current_lane0_xe28=0x4 +serdes_driver_current_lane1_xe28=0x4 +serdes_driver_current_lane2_xe28=0x4 +serdes_driver_current_lane3_xe28=0x4 +serdes_pre_driver_current_lane0_xe28=0x4 +serdes_pre_driver_current_lane1_xe28=0x4 +serdes_pre_driver_current_lane2_xe28=0x4 +serdes_pre_driver_current_lane3_xe28=0x4 +serdes_preemphasis_lane0_xe28=0xc2f0 +serdes_preemphasis_lane1_xe28=0xc2f0 +serdes_preemphasis_lane2_xe28=0xc2f0 +serdes_preemphasis_lane3_xe28=0xc2f0 + +# xe29 (40G) +portmap_30=89:40 +xgxs_rx_lane_map_30=0x1320 +xgxs_tx_lane_map_30=0x3021 +phy_xaui_rx_polarity_flip_30=0x2 +phy_xaui_tx_polarity_flip_30=0xb +serdes_driver_current_lane0_xe29=0x4 +serdes_driver_current_lane1_xe29=0x4 +serdes_driver_current_lane2_xe29=0x4 +serdes_driver_current_lane3_xe29=0x4 +serdes_pre_driver_current_lane0_xe29=0x4 +serdes_pre_driver_current_lane1_xe29=0x4 +serdes_pre_driver_current_lane2_xe29=0x4 +serdes_pre_driver_current_lane3_xe29=0x4 +serdes_preemphasis_lane0_xe29=0xcad0 +serdes_preemphasis_lane1_xe29=0xc6e0 +serdes_preemphasis_lane2_xe29=0xc6e0 +serdes_preemphasis_lane3_xe29=0xc6e0 + +# xe30 (40G) +portmap_31=101:40 +xgxs_rx_lane_map_31=0x1320 +xgxs_tx_lane_map_31=0x1203 +phy_xaui_rx_polarity_flip_31=0x1 +phy_xaui_tx_polarity_flip_31=0x6 +serdes_driver_current_lane0_xe30=0x6 +serdes_driver_current_lane1_xe30=0x6 +serdes_driver_current_lane2_xe30=0x6 +serdes_driver_current_lane3_xe30=0x7 +serdes_pre_driver_current_lane0_xe30=0x6 +serdes_pre_driver_current_lane1_xe30=0x6 +serdes_pre_driver_current_lane2_xe30=0x6 +serdes_pre_driver_current_lane3_xe30=0x7 +serdes_preemphasis_lane0_xe30=0xcec0 +serdes_preemphasis_lane1_xe30=0xcec0 +serdes_preemphasis_lane2_xe30=0xcad0 +serdes_preemphasis_lane3_xe30=0xc6e0 + +# xe31 (40G) +portmap_32=97:40 +xgxs_rx_lane_map_32=0x213 +xgxs_tx_lane_map_32=0x2031 +phy_xaui_rx_polarity_flip_32=0xc +phy_xaui_tx_polarity_flip_32=0x3 +serdes_driver_current_lane0_xe31=0x5 +serdes_driver_current_lane1_xe31=0x5 +serdes_driver_current_lane2_xe31=0x5 +serdes_driver_current_lane3_xe31=0x5 +serdes_pre_driver_current_lane0_xe31=0x5 +serdes_pre_driver_current_lane1_xe31=0x5 +serdes_pre_driver_current_lane2_xe31=0x5 +serdes_pre_driver_current_lane3_xe31=0x5 +serdes_preemphasis_lane0_xe31=0xcad0 +serdes_preemphasis_lane1_xe31=0xcad0 +serdes_preemphasis_lane2_xe31=0xcad0 +serdes_preemphasis_lane3_xe31=0xcad0 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers.json.j2 new file mode 100644 index 000000000000..b67cf577ab75 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers.json.j2 @@ -0,0 +1,3 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} + diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers_defaults_def.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers_defaults_def.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers_defaults_def.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers_defaults_t0.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers_defaults_t0.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers_defaults_t1.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/buffers_defaults_t1.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/pg_profile_lookup.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/pg_profile_lookup.ini new file mode 100644 index 000000000000..9f2eacb6fc42 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 56368 18432 55120 -3 2496 + 25000 5m 56368 18432 55120 -3 2496 + 40000 5m 56368 18432 55120 -3 2496 + 50000 5m 56368 18432 55120 -3 2496 + 100000 5m 56368 18432 55120 -3 2496 + 10000 40m 56368 18432 55120 -3 2496 + 25000 40m 56368 18432 55120 -3 2496 + 40000 40m 56368 18432 55120 -3 2496 + 50000 40m 56368 18432 55120 -3 2496 + 100000 40m 56368 18432 55120 -3 2496 + 10000 300m 56368 18432 55120 -3 2496 + 25000 300m 56368 18432 55120 -3 2496 + 40000 300m 56368 18432 55120 -3 2496 + 50000 300m 56368 18432 55120 -3 2496 + 100000 300m 56368 18432 55120 -3 2496 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/port_config.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/port_config.ini new file mode 100644 index 000000000000..95cf5eec9e4e --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias index speed +Ethernet0 25,26,27,28 fortyGigE0/0 0 40000 +Ethernet4 29,30,31,32 fortyGigE0/4 1 40000 +Ethernet8 33,34,35,36 fortyGigE0/8 2 40000 +Ethernet12 37,38,39,40 fortyGigE0/12 3 40000 +Ethernet16 45,46,47,48 fortyGigE0/16 4 40000 +Ethernet20 41,42,43,44 fortyGigE0/20 5 40000 +Ethernet24 1,2,3,4 fortyGigE0/24 6 40000 +Ethernet28 5,6,7,8 fortyGigE0/28 7 40000 +Ethernet32 13,14,15,16 fortyGigE0/32 8 40000 +Ethernet36 9,10,11,12 fortyGigE0/36 9 40000 +Ethernet40 17,18,19,20 fortyGigE0/40 10 40000 +Ethernet44 21,22,23,24 fortyGigE0/44 11 40000 +Ethernet48 53,54,55,56 fortyGigE0/48 12 40000 +Ethernet52 49,50,51,52 fortyGigE0/52 13 40000 +Ethernet56 57,58,59,60 fortyGigE0/56 14 40000 +Ethernet60 61,62,63,64 fortyGigE0/60 15 40000 +Ethernet64 69,70,71,72 fortyGigE0/64 16 40000 +Ethernet68 65,66,67,68 fortyGigE0/68 17 40000 +Ethernet72 73,74,75,76 fortyGigE0/72 18 40000 +Ethernet76 77,78,79,80 fortyGigE0/76 19 40000 +Ethernet80 109,110,111,112 fortyGigE0/80 20 40000 +Ethernet84 105,106,107,108 fortyGigE0/84 21 40000 +Ethernet88 113,114,115,116 fortyGigE0/88 22 40000 +Ethernet92 117,118,119,120 fortyGigE0/92 23 40000 +Ethernet96 125,126,127,128 fortyGigE0/96 24 40000 +Ethernet100 121,122,123,124 fortyGigE0/100 25 40000 +Ethernet104 81,82,83,84 fortyGigE0/104 26 40000 +Ethernet108 85,86,87,88 fortyGigE0/108 27 40000 +Ethernet112 93,94,95,96 fortyGigE0/112 28 40000 +Ethernet116 89,90,91,92 fortyGigE0/116 29 40000 +Ethernet120 101,102,103,104 fortyGigE0/120 30 40000 +Ethernet124 97,98,99,100 fortyGigE0/124 31 40000 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/qos.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/sai.profile new file mode 100644 index 000000000000..52e2e289af60 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/sai.profile @@ -0,0 +1,2 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm +SAI_NUM_ECMP_MEMBERS=32 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/td2-s6000-32x40G.config.bcm b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/td2-s6000-32x40G.config.bcm new file mode 100644 index 000000000000..4c94db7107c7 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/td2-s6000-32x40G.config.bcm @@ -0,0 +1,646 @@ +# Old LPM only configuration +# l2_mem_entries=163840 +# l3_mem_entries=90112 +# l3_alpm_enable=0 +# ipv6_lpm_128b_enable=0 +# +# ALPM enable +l3_alpm_enable=2 +ipv6_lpm_128b_enable=1 +l2_mem_entries=32768 +l3_mem_entries=16384 + +# From old config file +os=unix +higig2_hdr_mode=1 + +# Parity +parity_correction=1 +parity_enable=1 +stat_if_parity_enable=0 + +# +bcm_num_cos=8 +bcm_stat_interval=2000000 +l2xmsg_hostbuf_size=8192 +l2xmsg_mode=1 +lls_num_l2uc=12 +max_vp_lags=0 +miim_intr_enable=0 +mmu_lossless=0 +module_64ports=0 +schan_intr_enable=0 +stable_size=0x2000000 +tdma_timeout_usec=5000000 + +pbmp_oversubscribe=0x000007fffffffffffffffffffffffffe +pbmp_xport_xe=0x000007fffffffffffffffffffffffffe + +# Ports configuration +# xe0 (40G) +portmap_1=25:40 +xgxs_rx_lane_map_1=0x213 +xgxs_tx_lane_map_1=0x2031 +phy_xaui_rx_polarity_flip_1=0xe +phy_xaui_tx_polarity_flip_1=0x2 +serdes_driver_current_lane0_xe0=0x5 +serdes_driver_current_lane1_xe0=0x5 +serdes_driver_current_lane2_xe0=0x5 +serdes_driver_current_lane3_xe0=0x5 +serdes_pre_driver_current_lane0_xe0=0x5 +serdes_pre_driver_current_lane1_xe0=0x5 +serdes_pre_driver_current_lane2_xe0=0x5 +serdes_pre_driver_current_lane3_xe0=0x5 +serdes_preemphasis_lane0_xe0=0xcad0 +serdes_preemphasis_lane1_xe0=0xc6e0 +serdes_preemphasis_lane2_xe0=0xc6e0 +serdes_preemphasis_lane3_xe0=0xd2b0 + +# xe1 (40G) +portmap_2=29:40 +xgxs_rx_lane_map_2=0x213 +xgxs_tx_lane_map_2=0x213 +phy_xaui_rx_polarity_flip_2=0xc +phy_xaui_tx_polarity_flip_2=0x9 +serdes_driver_current_lane0_xe1=0x6 +serdes_driver_current_lane1_xe1=0x7 +serdes_driver_current_lane2_xe1=0x6 +serdes_driver_current_lane3_xe1=0x6 +serdes_pre_driver_current_lane0_xe1=0x6 +serdes_pre_driver_current_lane1_xe1=0x7 +serdes_pre_driver_current_lane2_xe1=0x6 +serdes_pre_driver_current_lane3_xe1=0x6 +serdes_preemphasis_lane0_xe1=0xc2f0 +serdes_preemphasis_lane1_xe1=0xd2b0 +serdes_preemphasis_lane2_xe1=0xc6e0 +serdes_preemphasis_lane3_xe1=0xc2f0 + +# xe2 (40G) +portmap_3=33:40 +xgxs_rx_lane_map_3=0x213 +xgxs_tx_lane_map_3=0x132 +phy_xaui_rx_polarity_flip_3=0xe +phy_xaui_tx_polarity_flip_3=0x2 +serdes_driver_current_lane0_xe2=0x4 +serdes_driver_current_lane1_xe2=0x4 +serdes_driver_current_lane2_xe2=0x4 +serdes_driver_current_lane3_xe2=0x4 +serdes_pre_driver_current_lane0_xe2=0x4 +serdes_pre_driver_current_lane1_xe2=0x4 +serdes_pre_driver_current_lane2_xe2=0x4 +serdes_pre_driver_current_lane3_xe2=0x4 +serdes_preemphasis_lane0_xe2=0xc6e0 +serdes_preemphasis_lane1_xe2=0xc6e0 +serdes_preemphasis_lane2_xe2=0xc6e0 +serdes_preemphasis_lane3_xe2=0xc6e0 + +# xe3 (40G) +portmap_4=37:40 +xgxs_rx_lane_map_4=0x213 +xgxs_tx_lane_map_4=0x1203 +phy_xaui_rx_polarity_flip_4=0x3 +phy_xaui_tx_polarity_flip_4=0xe +serdes_driver_current_lane0_xe3=0x4 +serdes_driver_current_lane1_xe3=0x4 +serdes_driver_current_lane2_xe3=0x4 +serdes_driver_current_lane3_xe3=0x4 +serdes_pre_driver_current_lane0_xe3=0x4 +serdes_pre_driver_current_lane1_xe3=0x4 +serdes_pre_driver_current_lane2_xe3=0x4 +serdes_pre_driver_current_lane3_xe3=0x4 +serdes_preemphasis_lane0_xe3=0xcad0 +serdes_preemphasis_lane1_xe3=0xcad0 +serdes_preemphasis_lane2_xe3=0xc2f0 +serdes_preemphasis_lane3_xe3=0xc2f0 + +# xe4 (40G) +portmap_5=45:40 +xgxs_rx_lane_map_5=0x213 +xgxs_tx_lane_map_5=0x213 +phy_xaui_rx_polarity_flip_5=0xe +phy_xaui_tx_polarity_flip_5=0x8 +serdes_driver_current_lane0_xe4=0x4 +serdes_driver_current_lane1_xe4=0x4 +serdes_driver_current_lane2_xe4=0x4 +serdes_driver_current_lane3_xe4=0x4 +serdes_pre_driver_current_lane0_xe4=0x4 +serdes_pre_driver_current_lane1_xe4=0x4 +serdes_pre_driver_current_lane2_xe4=0x4 +serdes_pre_driver_current_lane3_xe4=0x4 +serdes_preemphasis_lane0_xe4=0xc2f0 +serdes_preemphasis_lane1_xe4=0xc2f0 +serdes_preemphasis_lane2_xe4=0xc2f0 +serdes_preemphasis_lane3_xe4=0xc2f0 + +# xe5 (40G) +portmap_6=41:40 +xgxs_rx_lane_map_6=0x213 +xgxs_tx_lane_map_6=0x3021 +phy_xaui_rx_polarity_flip_6=0x3 +phy_xaui_tx_polarity_flip_6=0xb +serdes_driver_current_lane0_xe5=0x4 +serdes_driver_current_lane1_xe5=0x4 +serdes_driver_current_lane2_xe5=0x4 +serdes_driver_current_lane3_xe5=0x4 +serdes_pre_driver_current_lane0_xe5=0x4 +serdes_pre_driver_current_lane1_xe5=0x4 +serdes_pre_driver_current_lane2_xe5=0x4 +serdes_pre_driver_current_lane3_xe5=0x4 +serdes_preemphasis_lane0_xe5=0xc6e0 +serdes_preemphasis_lane1_xe5=0xc2f0 +serdes_preemphasis_lane2_xe5=0xc2f0 +serdes_preemphasis_lane3_xe5=0xcad0 + +# xe6 (40G) +portmap_7=1:40 +xgxs_rx_lane_map_7=0x213 +xgxs_tx_lane_map_7=0x2031 +phy_xaui_rx_polarity_flip_7=0xe +phy_xaui_tx_polarity_flip_7=0xd +serdes_driver_current_lane0_xe6=0x5 +serdes_driver_current_lane1_xe6=0x5 +serdes_driver_current_lane2_xe6=0x5 +serdes_driver_current_lane3_xe6=0x5 +serdes_pre_driver_current_lane0_xe6=0x5 +serdes_pre_driver_current_lane1_xe6=0x5 +serdes_pre_driver_current_lane2_xe6=0x5 +serdes_pre_driver_current_lane3_xe6=0x5 +serdes_preemphasis_lane0_xe6=0xc6e0 +serdes_preemphasis_lane1_xe6=0xcad0 +serdes_preemphasis_lane2_xe6=0xc6e0 +serdes_preemphasis_lane3_xe6=0xcad0 + +# xe7 (40G) +portmap_8=5:40 +xgxs_rx_lane_map_8=0x213 +xgxs_tx_lane_map_8=0x1203 +phy_xaui_rx_polarity_flip_8=0xc +phy_xaui_tx_polarity_flip_8=0x1 +serdes_driver_current_lane0_xe7=0x4 +serdes_driver_current_lane1_xe7=0x4 +serdes_driver_current_lane2_xe7=0x4 +serdes_driver_current_lane3_xe7=0x4 +serdes_pre_driver_current_lane0_xe7=0x4 +serdes_pre_driver_current_lane1_xe7=0x4 +serdes_pre_driver_current_lane2_xe7=0x4 +serdes_pre_driver_current_lane3_xe7=0x4 +serdes_preemphasis_lane0_xe7=0xc6e0 +serdes_preemphasis_lane1_xe7=0xc6e0 +serdes_preemphasis_lane2_xe7=0xc6e0 +serdes_preemphasis_lane3_xe7=0xc6e0 + +# xe8 (40G) +portmap_9=13:40 +xgxs_rx_lane_map_9=0x213 +xgxs_tx_lane_map_9=0x132 +phy_xaui_rx_polarity_flip_9=0xe +phy_xaui_tx_polarity_flip_9=0x0 +serdes_driver_current_lane0_xe8=0x2 +serdes_driver_current_lane1_xe8=0x3 +serdes_driver_current_lane2_xe8=0x2 +serdes_driver_current_lane3_xe8=0x2 +serdes_pre_driver_current_lane0_xe8=0x2 +serdes_pre_driver_current_lane1_xe8=0x3 +serdes_pre_driver_current_lane2_xe8=0x2 +serdes_pre_driver_current_lane3_xe8=0x2 +serdes_preemphasis_lane0_xe8=0xb270 +serdes_preemphasis_lane1_xe8=0xbb10 +serdes_preemphasis_lane2_xe8=0xb720 +serdes_preemphasis_lane3_xe8=0xb720 + +# xe9 (40G) +portmap_10=9:40 +xgxs_rx_lane_map_10=0x3120 +xgxs_tx_lane_map_10=0x3021 +phy_xaui_rx_polarity_flip_10=0x0 +phy_xaui_tx_polarity_flip_10=0x4 +serdes_driver_current_lane0_xe9=0x3 +serdes_driver_current_lane1_xe9=0x3 +serdes_driver_current_lane2_xe9=0x3 +serdes_driver_current_lane3_xe9=0x3 +serdes_pre_driver_current_lane0_xe9=0x3 +serdes_pre_driver_current_lane1_xe9=0x3 +serdes_pre_driver_current_lane2_xe9=0x3 +serdes_pre_driver_current_lane3_xe9=0x3 +serdes_preemphasis_lane0_xe9=0xc2f0 +serdes_preemphasis_lane1_xe9=0xc6e0 +serdes_preemphasis_lane2_xe9=0xbf00 +serdes_preemphasis_lane3_xe9=0xc2f0 + +# xe10 (40G) +portmap_11=17:40 +xgxs_rx_lane_map_11=0x213 +xgxs_tx_lane_map_11=0x132 +phy_xaui_rx_polarity_flip_11=0xe +phy_xaui_tx_polarity_flip_11=0x0 +serdes_driver_current_lane0_xe10=0x2 +serdes_driver_current_lane1_xe10=0x2 +serdes_driver_current_lane2_xe10=0x2 +serdes_driver_current_lane3_xe10=0x2 +serdes_pre_driver_current_lane0_xe10=0x2 +serdes_pre_driver_current_lane1_xe10=0x2 +serdes_pre_driver_current_lane2_xe10=0x2 +serdes_pre_driver_current_lane3_xe10=0x2 +serdes_preemphasis_lane0_xe10=0xb330 +serdes_preemphasis_lane1_xe10=0xbb10 +serdes_preemphasis_lane2_xe10=0xbb10 +serdes_preemphasis_lane3_xe10=0xbb10 + +# xe11 (40G) +portmap_12=21:40 +xgxs_rx_lane_map_12=0x123 +xgxs_tx_lane_map_12=0x1203 +phy_xaui_rx_polarity_flip_12=0xc +phy_xaui_tx_polarity_flip_12=0xe +serdes_driver_current_lane0_xe11=0x2 +serdes_driver_current_lane1_xe11=0x2 +serdes_driver_current_lane2_xe11=0x2 +serdes_driver_current_lane3_xe11=0x2 +serdes_pre_driver_current_lane0_xe11=0x2 +serdes_pre_driver_current_lane1_xe11=0x2 +serdes_pre_driver_current_lane2_xe11=0x2 +serdes_pre_driver_current_lane3_xe11=0x2 +serdes_preemphasis_lane0_xe11=0xb330 +serdes_preemphasis_lane1_xe11=0xb330 +serdes_preemphasis_lane2_xe11=0xb330 +serdes_preemphasis_lane3_xe11=0xb330 + +# xe12 (40G) +portmap_13=53:40 +xgxs_rx_lane_map_13=0x213 +xgxs_tx_lane_map_13=0x231 +phy_xaui_rx_polarity_flip_13=0x1 +phy_xaui_tx_polarity_flip_13=0x0 +serdes_driver_current_lane0_xe12=0x2 +serdes_driver_current_lane1_xe12=0x2 +serdes_driver_current_lane2_xe12=0x2 +serdes_driver_current_lane3_xe12=0x2 +serdes_pre_driver_current_lane0_xe12=0x2 +serdes_pre_driver_current_lane1_xe12=0x2 +serdes_pre_driver_current_lane2_xe12=0x2 +serdes_pre_driver_current_lane3_xe12=0x2 +serdes_preemphasis_lane0_xe12=0xaf40 +serdes_preemphasis_lane1_xe12=0xaf40 +serdes_preemphasis_lane2_xe12=0xaf40 +serdes_preemphasis_lane3_xe12=0xaf40 + +# xe13 (40G) +portmap_14=49:40 +xgxs_rx_lane_map_14=0x1302 +xgxs_tx_lane_map_14=0x2031 +phy_xaui_rx_polarity_flip_14=0xb +phy_xaui_tx_polarity_flip_14=0x3 +serdes_driver_current_lane0_xe13=0x2 +serdes_driver_current_lane1_xe13=0x2 +serdes_driver_current_lane2_xe13=0x2 +serdes_driver_current_lane3_xe13=0x2 +serdes_pre_driver_current_lane0_xe13=0x2 +serdes_pre_driver_current_lane1_xe13=0x2 +serdes_pre_driver_current_lane2_xe13=0x2 +serdes_pre_driver_current_lane3_xe13=0x2 +serdes_preemphasis_lane0_xe13=0xa760 +serdes_preemphasis_lane1_xe13=0xa760 +serdes_preemphasis_lane2_xe13=0xa760 +serdes_preemphasis_lane3_xe13=0xa760 + +# xe14 (40G) +portmap_15=57:40 +xgxs_rx_lane_map_15=0x213 +xgxs_tx_lane_map_15=0x2031 +phy_xaui_rx_polarity_flip_15=0x1 +phy_xaui_tx_polarity_flip_15=0x0 +serdes_driver_current_lane0_xe14=0x1 +serdes_driver_current_lane1_xe14=0x1 +serdes_driver_current_lane2_xe14=0x1 +serdes_driver_current_lane3_xe14=0x1 +serdes_pre_driver_current_lane0_xe14=0x1 +serdes_pre_driver_current_lane1_xe14=0x1 +serdes_pre_driver_current_lane2_xe14=0x1 +serdes_pre_driver_current_lane3_xe14=0x1 +serdes_preemphasis_lane0_xe14=0xa760 +serdes_preemphasis_lane1_xe14=0xa760 +serdes_preemphasis_lane2_xe14=0xa760 +serdes_preemphasis_lane3_xe14=0xa760 + +# xe15 (40G) +portmap_16=61:40 +xgxs_rx_lane_map_16=0x132 +xgxs_tx_lane_map_16=0x213 +phy_xaui_rx_polarity_flip_16=0x0 +phy_xaui_tx_polarity_flip_16=0x0 +serdes_driver_current_lane0_xe15=0x2 +serdes_driver_current_lane1_xe15=0x2 +serdes_driver_current_lane2_xe15=0x2 +serdes_driver_current_lane3_xe15=0x2 +serdes_pre_driver_current_lane0_xe15=0x2 +serdes_pre_driver_current_lane1_xe15=0x2 +serdes_pre_driver_current_lane2_xe15=0x2 +serdes_pre_driver_current_lane3_xe15=0x2 +serdes_preemphasis_lane0_xe15=0xa760 +serdes_preemphasis_lane1_xe15=0xa760 +serdes_preemphasis_lane2_xe15=0xa760 +serdes_preemphasis_lane3_xe15=0xa760 + +# xe16 (40G) +portmap_17=69:40 +xgxs_rx_lane_map_17=0x213 +xgxs_tx_lane_map_17=0x2130 +phy_xaui_rx_polarity_flip_17=0x1 +phy_xaui_tx_polarity_flip_17=0xf +serdes_driver_current_lane0_xe16=0x1 +serdes_driver_current_lane1_xe16=0x1 +serdes_driver_current_lane2_xe16=0x1 +serdes_driver_current_lane3_xe16=0x1 +serdes_pre_driver_current_lane0_xe16=0x1 +serdes_pre_driver_current_lane1_xe16=0x1 +serdes_pre_driver_current_lane2_xe16=0x1 +serdes_pre_driver_current_lane3_xe16=0x1 +serdes_preemphasis_lane0_xe16=0xa760 +serdes_preemphasis_lane1_xe16=0xa760 +serdes_preemphasis_lane2_xe16=0xa760 +serdes_preemphasis_lane3_xe16=0xa760 + +# xe17 (40G) +portmap_18=65:40 +xgxs_rx_lane_map_18=0x132 +xgxs_tx_lane_map_18=0x2031 +phy_xaui_rx_polarity_flip_18=0x3 +phy_xaui_tx_polarity_flip_18=0x9 +serdes_driver_current_lane0_xe17=0x1 +serdes_driver_current_lane1_xe17=0x1 +serdes_driver_current_lane2_xe17=0x1 +serdes_driver_current_lane3_xe17=0x1 +serdes_pre_driver_current_lane0_xe17=0x1 +serdes_pre_driver_current_lane1_xe17=0x1 +serdes_pre_driver_current_lane2_xe17=0x1 +serdes_pre_driver_current_lane3_xe17=0x1 +serdes_preemphasis_lane0_xe17=0xa370 +serdes_preemphasis_lane1_xe17=0xa370 +serdes_preemphasis_lane2_xe17=0xa370 +serdes_preemphasis_lane3_xe17=0xa370 + +# xe18 (40G) +portmap_19=73:40 +xgxs_rx_lane_map_19=0x213 +xgxs_tx_lane_map_19=0x2031 +phy_xaui_rx_polarity_flip_19=0x1 +phy_xaui_tx_polarity_flip_19=0x0 +serdes_driver_current_lane0_xe18=0x2 +serdes_driver_current_lane1_xe18=0x2 +serdes_driver_current_lane2_xe18=0x2 +serdes_driver_current_lane3_xe18=0x2 +serdes_pre_driver_current_lane0_xe18=0x2 +serdes_pre_driver_current_lane1_xe18=0x2 +serdes_pre_driver_current_lane2_xe18=0x2 +serdes_pre_driver_current_lane3_xe18=0x2 +serdes_preemphasis_lane0_xe18=0xa760 +serdes_preemphasis_lane1_xe18=0xa760 +serdes_preemphasis_lane2_xe18=0xa760 +serdes_preemphasis_lane3_xe18=0xa760 + +# xe19 (40G) +portmap_20=77:40 +xgxs_rx_lane_map_20=0x123 +xgxs_tx_lane_map_20=0x1203 +phy_xaui_rx_polarity_flip_20=0x3 +phy_xaui_tx_polarity_flip_20=0xe +serdes_driver_current_lane0_xe19=0x2 +serdes_driver_current_lane1_xe19=0x2 +serdes_driver_current_lane2_xe19=0x2 +serdes_driver_current_lane3_xe19=0x2 +serdes_pre_driver_current_lane0_xe19=0x2 +serdes_pre_driver_current_lane1_xe19=0x2 +serdes_pre_driver_current_lane2_xe19=0x2 +serdes_pre_driver_current_lane3_xe19=0x2 +serdes_preemphasis_lane0_xe19=0xaf40 +serdes_preemphasis_lane1_xe19=0xaf40 +serdes_preemphasis_lane2_xe19=0xaf40 +serdes_preemphasis_lane3_xe19=0xaf40 + +# xe20 (40G) +portmap_21=109:40 +xgxs_rx_lane_map_21=0x132 +xgxs_tx_lane_map_21=0x132 +phy_xaui_rx_polarity_flip_21=0x8 +phy_xaui_tx_polarity_flip_21=0x0 +serdes_driver_current_lane0_xe20=0x1 +serdes_driver_current_lane1_xe20=0x1 +serdes_driver_current_lane2_xe20=0x1 +serdes_driver_current_lane3_xe20=0x2 +serdes_pre_driver_current_lane0_xe20=0x1 +serdes_pre_driver_current_lane1_xe20=0x1 +serdes_pre_driver_current_lane2_xe20=0x1 +serdes_pre_driver_current_lane3_xe20=0x2 +serdes_preemphasis_lane0_xe20=0xb330 +serdes_preemphasis_lane1_xe20=0xb330 +serdes_preemphasis_lane2_xe20=0xb330 +serdes_preemphasis_lane3_xe20=0xbff0 + +# xe21 (40G) +portmap_22=105:40 +xgxs_rx_lane_map_22=0x1320 +xgxs_tx_lane_map_22=0x3021 +phy_xaui_rx_polarity_flip_22=0xd +phy_xaui_tx_polarity_flip_22=0xb +serdes_driver_current_lane0_xe21=0x1 +serdes_driver_current_lane1_xe21=0x1 +serdes_driver_current_lane2_xe21=0x1 +serdes_driver_current_lane3_xe21=0x1 +serdes_pre_driver_current_lane0_xe21=0x1 +serdes_pre_driver_current_lane1_xe21=0x1 +serdes_pre_driver_current_lane2_xe21=0x1 +serdes_pre_driver_current_lane3_xe21=0x1 +serdes_preemphasis_lane0_xe21=0xb330 +serdes_preemphasis_lane1_xe21=0xb330 +serdes_preemphasis_lane2_xe21=0xb330 +serdes_preemphasis_lane3_xe21=0xb330 + +# xe22 (40G) +portmap_23=113:40 +xgxs_rx_lane_map_23=0x132 +xgxs_tx_lane_map_23=0x132 +phy_xaui_rx_polarity_flip_23=0x8 +phy_xaui_tx_polarity_flip_23=0x0 +serdes_driver_current_lane0_xe22=0x1 +serdes_driver_current_lane1_xe22=0x1 +serdes_driver_current_lane2_xe22=0x1 +serdes_driver_current_lane3_xe22=0x1 +serdes_pre_driver_current_lane0_xe22=0x1 +serdes_pre_driver_current_lane1_xe22=0x1 +serdes_pre_driver_current_lane2_xe22=0x1 +serdes_pre_driver_current_lane3_xe22=0x1 +serdes_preemphasis_lane0_xe22=0xbb10 +serdes_preemphasis_lane1_xe22=0xbb10 +serdes_preemphasis_lane2_xe22=0xbb10 +serdes_preemphasis_lane3_xe22=0xc2f0 + +# xe23 (40G) +portmap_24=117:40 +xgxs_rx_lane_map_24=0x231 +xgxs_tx_lane_map_24=0x1203 +phy_xaui_rx_polarity_flip_24=0x3 +phy_xaui_tx_polarity_flip_24=0xe +serdes_driver_current_lane0_xe23=0x3 +serdes_driver_current_lane1_xe23=0x5 +serdes_driver_current_lane2_xe23=0x3 +serdes_driver_current_lane3_xe23=0x3 +serdes_pre_driver_current_lane0_xe23=0x3 +serdes_pre_driver_current_lane1_xe23=0x5 +serdes_pre_driver_current_lane2_xe23=0x3 +serdes_pre_driver_current_lane3_xe23=0x3 +serdes_preemphasis_lane0_xe23=0xc6e0 +serdes_preemphasis_lane1_xe23=0xc6e0 +serdes_preemphasis_lane2_xe23=0xc6e0 +serdes_preemphasis_lane3_xe23=0xc6e0 + +# xe24 (40G) +portmap_25=125:40 +xgxs_rx_lane_map_25=0x132 +xgxs_tx_lane_map_25=0x132 +phy_xaui_rx_polarity_flip_25=0x8 +phy_xaui_tx_polarity_flip_25=0x0 +serdes_driver_current_lane0_xe24=0x4 +serdes_driver_current_lane1_xe24=0x4 +serdes_driver_current_lane2_xe24=0x4 +serdes_driver_current_lane3_xe24=0x4 +serdes_pre_driver_current_lane0_xe24=0x4 +serdes_pre_driver_current_lane1_xe24=0x4 +serdes_pre_driver_current_lane2_xe24=0x4 +serdes_pre_driver_current_lane3_xe24=0x4 +serdes_preemphasis_lane0_xe24=0xc6e0 +serdes_preemphasis_lane1_xe24=0xc6e0 +serdes_preemphasis_lane2_xe24=0xc6e0 +serdes_preemphasis_lane3_xe24=0xcec0 + +# xe25 (40G) +portmap_26=121:40 +xgxs_rx_lane_map_26=0x1320 +xgxs_tx_lane_map_26=0x3021 +phy_xaui_rx_polarity_flip_26=0xd +phy_xaui_tx_polarity_flip_26=0xb +serdes_driver_current_lane0_xe25=0x4 +serdes_driver_current_lane1_xe25=0x4 +serdes_driver_current_lane2_xe25=0x4 +serdes_driver_current_lane3_xe25=0x4 +serdes_pre_driver_current_lane0_xe25=0x4 +serdes_pre_driver_current_lane1_xe25=0x4 +serdes_pre_driver_current_lane2_xe25=0x4 +serdes_pre_driver_current_lane3_xe25=0x4 +serdes_preemphasis_lane0_xe25=0xc6e0 +serdes_preemphasis_lane1_xe25=0xc6e0 +serdes_preemphasis_lane2_xe25=0xc6e0 +serdes_preemphasis_lane3_xe25=0xc6e0 + +# xe26 (40G) +portmap_27=81:40 +xgxs_rx_lane_map_27=0x1320 +xgxs_tx_lane_map_27=0x2031 +phy_xaui_rx_polarity_flip_27=0x1 +phy_xaui_tx_polarity_flip_27=0x2 +serdes_driver_current_lane0_xe26=0x2 +serdes_driver_current_lane1_xe26=0x2 +serdes_driver_current_lane2_xe26=0x2 +serdes_driver_current_lane3_xe26=0x2 +serdes_pre_driver_current_lane0_xe26=0x2 +serdes_pre_driver_current_lane1_xe26=0x2 +serdes_pre_driver_current_lane2_xe26=0x2 +serdes_pre_driver_current_lane3_xe26=0x2 +serdes_preemphasis_lane0_xe26=0xbb10 +serdes_preemphasis_lane1_xe26=0xbb10 +serdes_preemphasis_lane2_xe26=0xbf00 +serdes_preemphasis_lane3_xe26=0xbb10 + +# xe27 (40G) +portmap_28=85:40 +xgxs_rx_lane_map_28=0x213 +xgxs_tx_lane_map_28=0x1203 +phy_xaui_rx_polarity_flip_28=0xc +phy_xaui_tx_polarity_flip_28=0xe +serdes_driver_current_lane0_xe27=0x4 +serdes_driver_current_lane1_xe27=0x5 +serdes_driver_current_lane2_xe27=0x4 +serdes_driver_current_lane3_xe27=0x5 +serdes_pre_driver_current_lane0_xe27=0x4 +serdes_pre_driver_current_lane1_xe27=0x5 +serdes_pre_driver_current_lane2_xe27=0x4 +serdes_pre_driver_current_lane3_xe27=0x5 +serdes_preemphasis_lane0_xe27=0xc2f0 +serdes_preemphasis_lane1_xe27=0xc6e0 +serdes_preemphasis_lane2_xe27=0xc6e0 +serdes_preemphasis_lane3_xe27=0xc6e0 + +# xe28 (40G) +portmap_29=93:40 +xgxs_rx_lane_map_29=0x1320 +xgxs_tx_lane_map_29=0x2031 +phy_xaui_rx_polarity_flip_29=0x1 +phy_xaui_tx_polarity_flip_29=0x2 +serdes_driver_current_lane0_xe28=0x4 +serdes_driver_current_lane1_xe28=0x4 +serdes_driver_current_lane2_xe28=0x4 +serdes_driver_current_lane3_xe28=0x4 +serdes_pre_driver_current_lane0_xe28=0x4 +serdes_pre_driver_current_lane1_xe28=0x4 +serdes_pre_driver_current_lane2_xe28=0x4 +serdes_pre_driver_current_lane3_xe28=0x4 +serdes_preemphasis_lane0_xe28=0xc2f0 +serdes_preemphasis_lane1_xe28=0xc2f0 +serdes_preemphasis_lane2_xe28=0xc2f0 +serdes_preemphasis_lane3_xe28=0xc2f0 + +# xe29 (40G) +portmap_30=89:40 +xgxs_rx_lane_map_30=0x1320 +xgxs_tx_lane_map_30=0x3021 +phy_xaui_rx_polarity_flip_30=0x2 +phy_xaui_tx_polarity_flip_30=0xb +serdes_driver_current_lane0_xe29=0x4 +serdes_driver_current_lane1_xe29=0x4 +serdes_driver_current_lane2_xe29=0x4 +serdes_driver_current_lane3_xe29=0x4 +serdes_pre_driver_current_lane0_xe29=0x4 +serdes_pre_driver_current_lane1_xe29=0x4 +serdes_pre_driver_current_lane2_xe29=0x4 +serdes_pre_driver_current_lane3_xe29=0x4 +serdes_preemphasis_lane0_xe29=0xcad0 +serdes_preemphasis_lane1_xe29=0xc6e0 +serdes_preemphasis_lane2_xe29=0xc6e0 +serdes_preemphasis_lane3_xe29=0xc6e0 + +# xe30 (40G) +portmap_31=101:40 +xgxs_rx_lane_map_31=0x1320 +xgxs_tx_lane_map_31=0x1203 +phy_xaui_rx_polarity_flip_31=0x1 +phy_xaui_tx_polarity_flip_31=0x6 +serdes_driver_current_lane0_xe30=0x6 +serdes_driver_current_lane1_xe30=0x6 +serdes_driver_current_lane2_xe30=0x6 +serdes_driver_current_lane3_xe30=0x7 +serdes_pre_driver_current_lane0_xe30=0x6 +serdes_pre_driver_current_lane1_xe30=0x6 +serdes_pre_driver_current_lane2_xe30=0x6 +serdes_pre_driver_current_lane3_xe30=0x7 +serdes_preemphasis_lane0_xe30=0xcec0 +serdes_preemphasis_lane1_xe30=0xcec0 +serdes_preemphasis_lane2_xe30=0xcad0 +serdes_preemphasis_lane3_xe30=0xc6e0 + +# xe31 (40G) +portmap_32=97:40 +xgxs_rx_lane_map_32=0x213 +xgxs_tx_lane_map_32=0x2031 +phy_xaui_rx_polarity_flip_32=0xc +phy_xaui_tx_polarity_flip_32=0x3 +serdes_driver_current_lane0_xe31=0x5 +serdes_driver_current_lane1_xe31=0x5 +serdes_driver_current_lane2_xe31=0x5 +serdes_driver_current_lane3_xe31=0x5 +serdes_pre_driver_current_lane0_xe31=0x5 +serdes_pre_driver_current_lane1_xe31=0x5 +serdes_pre_driver_current_lane2_xe31=0x5 +serdes_pre_driver_current_lane3_xe31=0x5 +serdes_preemphasis_lane0_xe31=0xcad0 +serdes_preemphasis_lane1_xe31=0xcad0 +serdes_preemphasis_lane2_xe31=0xcad0 +serdes_preemphasis_lane3_xe31=0xcad0 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers.json.j2 new file mode 100644 index 000000000000..b67cf577ab75 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers.json.j2 @@ -0,0 +1,3 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} + diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers_defaults_def.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers_defaults_def.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers_defaults_def.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers_defaults_t0.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers_defaults_t0.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers_defaults_t1.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/buffers_defaults_t1.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/pg_profile_lookup.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/pg_profile_lookup.ini new file mode 100644 index 000000000000..9f2eacb6fc42 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 56368 18432 55120 -3 2496 + 25000 5m 56368 18432 55120 -3 2496 + 40000 5m 56368 18432 55120 -3 2496 + 50000 5m 56368 18432 55120 -3 2496 + 100000 5m 56368 18432 55120 -3 2496 + 10000 40m 56368 18432 55120 -3 2496 + 25000 40m 56368 18432 55120 -3 2496 + 40000 40m 56368 18432 55120 -3 2496 + 50000 40m 56368 18432 55120 -3 2496 + 100000 40m 56368 18432 55120 -3 2496 + 10000 300m 56368 18432 55120 -3 2496 + 25000 300m 56368 18432 55120 -3 2496 + 40000 300m 56368 18432 55120 -3 2496 + 50000 300m 56368 18432 55120 -3 2496 + 100000 300m 56368 18432 55120 -3 2496 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/port_config.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/port_config.ini new file mode 100644 index 000000000000..95cf5eec9e4e --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias index speed +Ethernet0 25,26,27,28 fortyGigE0/0 0 40000 +Ethernet4 29,30,31,32 fortyGigE0/4 1 40000 +Ethernet8 33,34,35,36 fortyGigE0/8 2 40000 +Ethernet12 37,38,39,40 fortyGigE0/12 3 40000 +Ethernet16 45,46,47,48 fortyGigE0/16 4 40000 +Ethernet20 41,42,43,44 fortyGigE0/20 5 40000 +Ethernet24 1,2,3,4 fortyGigE0/24 6 40000 +Ethernet28 5,6,7,8 fortyGigE0/28 7 40000 +Ethernet32 13,14,15,16 fortyGigE0/32 8 40000 +Ethernet36 9,10,11,12 fortyGigE0/36 9 40000 +Ethernet40 17,18,19,20 fortyGigE0/40 10 40000 +Ethernet44 21,22,23,24 fortyGigE0/44 11 40000 +Ethernet48 53,54,55,56 fortyGigE0/48 12 40000 +Ethernet52 49,50,51,52 fortyGigE0/52 13 40000 +Ethernet56 57,58,59,60 fortyGigE0/56 14 40000 +Ethernet60 61,62,63,64 fortyGigE0/60 15 40000 +Ethernet64 69,70,71,72 fortyGigE0/64 16 40000 +Ethernet68 65,66,67,68 fortyGigE0/68 17 40000 +Ethernet72 73,74,75,76 fortyGigE0/72 18 40000 +Ethernet76 77,78,79,80 fortyGigE0/76 19 40000 +Ethernet80 109,110,111,112 fortyGigE0/80 20 40000 +Ethernet84 105,106,107,108 fortyGigE0/84 21 40000 +Ethernet88 113,114,115,116 fortyGigE0/88 22 40000 +Ethernet92 117,118,119,120 fortyGigE0/92 23 40000 +Ethernet96 125,126,127,128 fortyGigE0/96 24 40000 +Ethernet100 121,122,123,124 fortyGigE0/100 25 40000 +Ethernet104 81,82,83,84 fortyGigE0/104 26 40000 +Ethernet108 85,86,87,88 fortyGigE0/108 27 40000 +Ethernet112 93,94,95,96 fortyGigE0/112 28 40000 +Ethernet116 89,90,91,92 fortyGigE0/116 29 40000 +Ethernet120 101,102,103,104 fortyGigE0/120 30 40000 +Ethernet124 97,98,99,100 fortyGigE0/124 31 40000 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/qos.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/sai.profile new file mode 100644 index 000000000000..52e2e289af60 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/sai.profile @@ -0,0 +1,2 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm +SAI_NUM_ECMP_MEMBERS=32 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/td2-s6000-32x40G.config.bcm b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/td2-s6000-32x40G.config.bcm new file mode 100644 index 000000000000..4c94db7107c7 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/td2-s6000-32x40G.config.bcm @@ -0,0 +1,646 @@ +# Old LPM only configuration +# l2_mem_entries=163840 +# l3_mem_entries=90112 +# l3_alpm_enable=0 +# ipv6_lpm_128b_enable=0 +# +# ALPM enable +l3_alpm_enable=2 +ipv6_lpm_128b_enable=1 +l2_mem_entries=32768 +l3_mem_entries=16384 + +# From old config file +os=unix +higig2_hdr_mode=1 + +# Parity +parity_correction=1 +parity_enable=1 +stat_if_parity_enable=0 + +# +bcm_num_cos=8 +bcm_stat_interval=2000000 +l2xmsg_hostbuf_size=8192 +l2xmsg_mode=1 +lls_num_l2uc=12 +max_vp_lags=0 +miim_intr_enable=0 +mmu_lossless=0 +module_64ports=0 +schan_intr_enable=0 +stable_size=0x2000000 +tdma_timeout_usec=5000000 + +pbmp_oversubscribe=0x000007fffffffffffffffffffffffffe +pbmp_xport_xe=0x000007fffffffffffffffffffffffffe + +# Ports configuration +# xe0 (40G) +portmap_1=25:40 +xgxs_rx_lane_map_1=0x213 +xgxs_tx_lane_map_1=0x2031 +phy_xaui_rx_polarity_flip_1=0xe +phy_xaui_tx_polarity_flip_1=0x2 +serdes_driver_current_lane0_xe0=0x5 +serdes_driver_current_lane1_xe0=0x5 +serdes_driver_current_lane2_xe0=0x5 +serdes_driver_current_lane3_xe0=0x5 +serdes_pre_driver_current_lane0_xe0=0x5 +serdes_pre_driver_current_lane1_xe0=0x5 +serdes_pre_driver_current_lane2_xe0=0x5 +serdes_pre_driver_current_lane3_xe0=0x5 +serdes_preemphasis_lane0_xe0=0xcad0 +serdes_preemphasis_lane1_xe0=0xc6e0 +serdes_preemphasis_lane2_xe0=0xc6e0 +serdes_preemphasis_lane3_xe0=0xd2b0 + +# xe1 (40G) +portmap_2=29:40 +xgxs_rx_lane_map_2=0x213 +xgxs_tx_lane_map_2=0x213 +phy_xaui_rx_polarity_flip_2=0xc +phy_xaui_tx_polarity_flip_2=0x9 +serdes_driver_current_lane0_xe1=0x6 +serdes_driver_current_lane1_xe1=0x7 +serdes_driver_current_lane2_xe1=0x6 +serdes_driver_current_lane3_xe1=0x6 +serdes_pre_driver_current_lane0_xe1=0x6 +serdes_pre_driver_current_lane1_xe1=0x7 +serdes_pre_driver_current_lane2_xe1=0x6 +serdes_pre_driver_current_lane3_xe1=0x6 +serdes_preemphasis_lane0_xe1=0xc2f0 +serdes_preemphasis_lane1_xe1=0xd2b0 +serdes_preemphasis_lane2_xe1=0xc6e0 +serdes_preemphasis_lane3_xe1=0xc2f0 + +# xe2 (40G) +portmap_3=33:40 +xgxs_rx_lane_map_3=0x213 +xgxs_tx_lane_map_3=0x132 +phy_xaui_rx_polarity_flip_3=0xe +phy_xaui_tx_polarity_flip_3=0x2 +serdes_driver_current_lane0_xe2=0x4 +serdes_driver_current_lane1_xe2=0x4 +serdes_driver_current_lane2_xe2=0x4 +serdes_driver_current_lane3_xe2=0x4 +serdes_pre_driver_current_lane0_xe2=0x4 +serdes_pre_driver_current_lane1_xe2=0x4 +serdes_pre_driver_current_lane2_xe2=0x4 +serdes_pre_driver_current_lane3_xe2=0x4 +serdes_preemphasis_lane0_xe2=0xc6e0 +serdes_preemphasis_lane1_xe2=0xc6e0 +serdes_preemphasis_lane2_xe2=0xc6e0 +serdes_preemphasis_lane3_xe2=0xc6e0 + +# xe3 (40G) +portmap_4=37:40 +xgxs_rx_lane_map_4=0x213 +xgxs_tx_lane_map_4=0x1203 +phy_xaui_rx_polarity_flip_4=0x3 +phy_xaui_tx_polarity_flip_4=0xe +serdes_driver_current_lane0_xe3=0x4 +serdes_driver_current_lane1_xe3=0x4 +serdes_driver_current_lane2_xe3=0x4 +serdes_driver_current_lane3_xe3=0x4 +serdes_pre_driver_current_lane0_xe3=0x4 +serdes_pre_driver_current_lane1_xe3=0x4 +serdes_pre_driver_current_lane2_xe3=0x4 +serdes_pre_driver_current_lane3_xe3=0x4 +serdes_preemphasis_lane0_xe3=0xcad0 +serdes_preemphasis_lane1_xe3=0xcad0 +serdes_preemphasis_lane2_xe3=0xc2f0 +serdes_preemphasis_lane3_xe3=0xc2f0 + +# xe4 (40G) +portmap_5=45:40 +xgxs_rx_lane_map_5=0x213 +xgxs_tx_lane_map_5=0x213 +phy_xaui_rx_polarity_flip_5=0xe +phy_xaui_tx_polarity_flip_5=0x8 +serdes_driver_current_lane0_xe4=0x4 +serdes_driver_current_lane1_xe4=0x4 +serdes_driver_current_lane2_xe4=0x4 +serdes_driver_current_lane3_xe4=0x4 +serdes_pre_driver_current_lane0_xe4=0x4 +serdes_pre_driver_current_lane1_xe4=0x4 +serdes_pre_driver_current_lane2_xe4=0x4 +serdes_pre_driver_current_lane3_xe4=0x4 +serdes_preemphasis_lane0_xe4=0xc2f0 +serdes_preemphasis_lane1_xe4=0xc2f0 +serdes_preemphasis_lane2_xe4=0xc2f0 +serdes_preemphasis_lane3_xe4=0xc2f0 + +# xe5 (40G) +portmap_6=41:40 +xgxs_rx_lane_map_6=0x213 +xgxs_tx_lane_map_6=0x3021 +phy_xaui_rx_polarity_flip_6=0x3 +phy_xaui_tx_polarity_flip_6=0xb +serdes_driver_current_lane0_xe5=0x4 +serdes_driver_current_lane1_xe5=0x4 +serdes_driver_current_lane2_xe5=0x4 +serdes_driver_current_lane3_xe5=0x4 +serdes_pre_driver_current_lane0_xe5=0x4 +serdes_pre_driver_current_lane1_xe5=0x4 +serdes_pre_driver_current_lane2_xe5=0x4 +serdes_pre_driver_current_lane3_xe5=0x4 +serdes_preemphasis_lane0_xe5=0xc6e0 +serdes_preemphasis_lane1_xe5=0xc2f0 +serdes_preemphasis_lane2_xe5=0xc2f0 +serdes_preemphasis_lane3_xe5=0xcad0 + +# xe6 (40G) +portmap_7=1:40 +xgxs_rx_lane_map_7=0x213 +xgxs_tx_lane_map_7=0x2031 +phy_xaui_rx_polarity_flip_7=0xe +phy_xaui_tx_polarity_flip_7=0xd +serdes_driver_current_lane0_xe6=0x5 +serdes_driver_current_lane1_xe6=0x5 +serdes_driver_current_lane2_xe6=0x5 +serdes_driver_current_lane3_xe6=0x5 +serdes_pre_driver_current_lane0_xe6=0x5 +serdes_pre_driver_current_lane1_xe6=0x5 +serdes_pre_driver_current_lane2_xe6=0x5 +serdes_pre_driver_current_lane3_xe6=0x5 +serdes_preemphasis_lane0_xe6=0xc6e0 +serdes_preemphasis_lane1_xe6=0xcad0 +serdes_preemphasis_lane2_xe6=0xc6e0 +serdes_preemphasis_lane3_xe6=0xcad0 + +# xe7 (40G) +portmap_8=5:40 +xgxs_rx_lane_map_8=0x213 +xgxs_tx_lane_map_8=0x1203 +phy_xaui_rx_polarity_flip_8=0xc +phy_xaui_tx_polarity_flip_8=0x1 +serdes_driver_current_lane0_xe7=0x4 +serdes_driver_current_lane1_xe7=0x4 +serdes_driver_current_lane2_xe7=0x4 +serdes_driver_current_lane3_xe7=0x4 +serdes_pre_driver_current_lane0_xe7=0x4 +serdes_pre_driver_current_lane1_xe7=0x4 +serdes_pre_driver_current_lane2_xe7=0x4 +serdes_pre_driver_current_lane3_xe7=0x4 +serdes_preemphasis_lane0_xe7=0xc6e0 +serdes_preemphasis_lane1_xe7=0xc6e0 +serdes_preemphasis_lane2_xe7=0xc6e0 +serdes_preemphasis_lane3_xe7=0xc6e0 + +# xe8 (40G) +portmap_9=13:40 +xgxs_rx_lane_map_9=0x213 +xgxs_tx_lane_map_9=0x132 +phy_xaui_rx_polarity_flip_9=0xe +phy_xaui_tx_polarity_flip_9=0x0 +serdes_driver_current_lane0_xe8=0x2 +serdes_driver_current_lane1_xe8=0x3 +serdes_driver_current_lane2_xe8=0x2 +serdes_driver_current_lane3_xe8=0x2 +serdes_pre_driver_current_lane0_xe8=0x2 +serdes_pre_driver_current_lane1_xe8=0x3 +serdes_pre_driver_current_lane2_xe8=0x2 +serdes_pre_driver_current_lane3_xe8=0x2 +serdes_preemphasis_lane0_xe8=0xb270 +serdes_preemphasis_lane1_xe8=0xbb10 +serdes_preemphasis_lane2_xe8=0xb720 +serdes_preemphasis_lane3_xe8=0xb720 + +# xe9 (40G) +portmap_10=9:40 +xgxs_rx_lane_map_10=0x3120 +xgxs_tx_lane_map_10=0x3021 +phy_xaui_rx_polarity_flip_10=0x0 +phy_xaui_tx_polarity_flip_10=0x4 +serdes_driver_current_lane0_xe9=0x3 +serdes_driver_current_lane1_xe9=0x3 +serdes_driver_current_lane2_xe9=0x3 +serdes_driver_current_lane3_xe9=0x3 +serdes_pre_driver_current_lane0_xe9=0x3 +serdes_pre_driver_current_lane1_xe9=0x3 +serdes_pre_driver_current_lane2_xe9=0x3 +serdes_pre_driver_current_lane3_xe9=0x3 +serdes_preemphasis_lane0_xe9=0xc2f0 +serdes_preemphasis_lane1_xe9=0xc6e0 +serdes_preemphasis_lane2_xe9=0xbf00 +serdes_preemphasis_lane3_xe9=0xc2f0 + +# xe10 (40G) +portmap_11=17:40 +xgxs_rx_lane_map_11=0x213 +xgxs_tx_lane_map_11=0x132 +phy_xaui_rx_polarity_flip_11=0xe +phy_xaui_tx_polarity_flip_11=0x0 +serdes_driver_current_lane0_xe10=0x2 +serdes_driver_current_lane1_xe10=0x2 +serdes_driver_current_lane2_xe10=0x2 +serdes_driver_current_lane3_xe10=0x2 +serdes_pre_driver_current_lane0_xe10=0x2 +serdes_pre_driver_current_lane1_xe10=0x2 +serdes_pre_driver_current_lane2_xe10=0x2 +serdes_pre_driver_current_lane3_xe10=0x2 +serdes_preemphasis_lane0_xe10=0xb330 +serdes_preemphasis_lane1_xe10=0xbb10 +serdes_preemphasis_lane2_xe10=0xbb10 +serdes_preemphasis_lane3_xe10=0xbb10 + +# xe11 (40G) +portmap_12=21:40 +xgxs_rx_lane_map_12=0x123 +xgxs_tx_lane_map_12=0x1203 +phy_xaui_rx_polarity_flip_12=0xc +phy_xaui_tx_polarity_flip_12=0xe +serdes_driver_current_lane0_xe11=0x2 +serdes_driver_current_lane1_xe11=0x2 +serdes_driver_current_lane2_xe11=0x2 +serdes_driver_current_lane3_xe11=0x2 +serdes_pre_driver_current_lane0_xe11=0x2 +serdes_pre_driver_current_lane1_xe11=0x2 +serdes_pre_driver_current_lane2_xe11=0x2 +serdes_pre_driver_current_lane3_xe11=0x2 +serdes_preemphasis_lane0_xe11=0xb330 +serdes_preemphasis_lane1_xe11=0xb330 +serdes_preemphasis_lane2_xe11=0xb330 +serdes_preemphasis_lane3_xe11=0xb330 + +# xe12 (40G) +portmap_13=53:40 +xgxs_rx_lane_map_13=0x213 +xgxs_tx_lane_map_13=0x231 +phy_xaui_rx_polarity_flip_13=0x1 +phy_xaui_tx_polarity_flip_13=0x0 +serdes_driver_current_lane0_xe12=0x2 +serdes_driver_current_lane1_xe12=0x2 +serdes_driver_current_lane2_xe12=0x2 +serdes_driver_current_lane3_xe12=0x2 +serdes_pre_driver_current_lane0_xe12=0x2 +serdes_pre_driver_current_lane1_xe12=0x2 +serdes_pre_driver_current_lane2_xe12=0x2 +serdes_pre_driver_current_lane3_xe12=0x2 +serdes_preemphasis_lane0_xe12=0xaf40 +serdes_preemphasis_lane1_xe12=0xaf40 +serdes_preemphasis_lane2_xe12=0xaf40 +serdes_preemphasis_lane3_xe12=0xaf40 + +# xe13 (40G) +portmap_14=49:40 +xgxs_rx_lane_map_14=0x1302 +xgxs_tx_lane_map_14=0x2031 +phy_xaui_rx_polarity_flip_14=0xb +phy_xaui_tx_polarity_flip_14=0x3 +serdes_driver_current_lane0_xe13=0x2 +serdes_driver_current_lane1_xe13=0x2 +serdes_driver_current_lane2_xe13=0x2 +serdes_driver_current_lane3_xe13=0x2 +serdes_pre_driver_current_lane0_xe13=0x2 +serdes_pre_driver_current_lane1_xe13=0x2 +serdes_pre_driver_current_lane2_xe13=0x2 +serdes_pre_driver_current_lane3_xe13=0x2 +serdes_preemphasis_lane0_xe13=0xa760 +serdes_preemphasis_lane1_xe13=0xa760 +serdes_preemphasis_lane2_xe13=0xa760 +serdes_preemphasis_lane3_xe13=0xa760 + +# xe14 (40G) +portmap_15=57:40 +xgxs_rx_lane_map_15=0x213 +xgxs_tx_lane_map_15=0x2031 +phy_xaui_rx_polarity_flip_15=0x1 +phy_xaui_tx_polarity_flip_15=0x0 +serdes_driver_current_lane0_xe14=0x1 +serdes_driver_current_lane1_xe14=0x1 +serdes_driver_current_lane2_xe14=0x1 +serdes_driver_current_lane3_xe14=0x1 +serdes_pre_driver_current_lane0_xe14=0x1 +serdes_pre_driver_current_lane1_xe14=0x1 +serdes_pre_driver_current_lane2_xe14=0x1 +serdes_pre_driver_current_lane3_xe14=0x1 +serdes_preemphasis_lane0_xe14=0xa760 +serdes_preemphasis_lane1_xe14=0xa760 +serdes_preemphasis_lane2_xe14=0xa760 +serdes_preemphasis_lane3_xe14=0xa760 + +# xe15 (40G) +portmap_16=61:40 +xgxs_rx_lane_map_16=0x132 +xgxs_tx_lane_map_16=0x213 +phy_xaui_rx_polarity_flip_16=0x0 +phy_xaui_tx_polarity_flip_16=0x0 +serdes_driver_current_lane0_xe15=0x2 +serdes_driver_current_lane1_xe15=0x2 +serdes_driver_current_lane2_xe15=0x2 +serdes_driver_current_lane3_xe15=0x2 +serdes_pre_driver_current_lane0_xe15=0x2 +serdes_pre_driver_current_lane1_xe15=0x2 +serdes_pre_driver_current_lane2_xe15=0x2 +serdes_pre_driver_current_lane3_xe15=0x2 +serdes_preemphasis_lane0_xe15=0xa760 +serdes_preemphasis_lane1_xe15=0xa760 +serdes_preemphasis_lane2_xe15=0xa760 +serdes_preemphasis_lane3_xe15=0xa760 + +# xe16 (40G) +portmap_17=69:40 +xgxs_rx_lane_map_17=0x213 +xgxs_tx_lane_map_17=0x2130 +phy_xaui_rx_polarity_flip_17=0x1 +phy_xaui_tx_polarity_flip_17=0xf +serdes_driver_current_lane0_xe16=0x1 +serdes_driver_current_lane1_xe16=0x1 +serdes_driver_current_lane2_xe16=0x1 +serdes_driver_current_lane3_xe16=0x1 +serdes_pre_driver_current_lane0_xe16=0x1 +serdes_pre_driver_current_lane1_xe16=0x1 +serdes_pre_driver_current_lane2_xe16=0x1 +serdes_pre_driver_current_lane3_xe16=0x1 +serdes_preemphasis_lane0_xe16=0xa760 +serdes_preemphasis_lane1_xe16=0xa760 +serdes_preemphasis_lane2_xe16=0xa760 +serdes_preemphasis_lane3_xe16=0xa760 + +# xe17 (40G) +portmap_18=65:40 +xgxs_rx_lane_map_18=0x132 +xgxs_tx_lane_map_18=0x2031 +phy_xaui_rx_polarity_flip_18=0x3 +phy_xaui_tx_polarity_flip_18=0x9 +serdes_driver_current_lane0_xe17=0x1 +serdes_driver_current_lane1_xe17=0x1 +serdes_driver_current_lane2_xe17=0x1 +serdes_driver_current_lane3_xe17=0x1 +serdes_pre_driver_current_lane0_xe17=0x1 +serdes_pre_driver_current_lane1_xe17=0x1 +serdes_pre_driver_current_lane2_xe17=0x1 +serdes_pre_driver_current_lane3_xe17=0x1 +serdes_preemphasis_lane0_xe17=0xa370 +serdes_preemphasis_lane1_xe17=0xa370 +serdes_preemphasis_lane2_xe17=0xa370 +serdes_preemphasis_lane3_xe17=0xa370 + +# xe18 (40G) +portmap_19=73:40 +xgxs_rx_lane_map_19=0x213 +xgxs_tx_lane_map_19=0x2031 +phy_xaui_rx_polarity_flip_19=0x1 +phy_xaui_tx_polarity_flip_19=0x0 +serdes_driver_current_lane0_xe18=0x2 +serdes_driver_current_lane1_xe18=0x2 +serdes_driver_current_lane2_xe18=0x2 +serdes_driver_current_lane3_xe18=0x2 +serdes_pre_driver_current_lane0_xe18=0x2 +serdes_pre_driver_current_lane1_xe18=0x2 +serdes_pre_driver_current_lane2_xe18=0x2 +serdes_pre_driver_current_lane3_xe18=0x2 +serdes_preemphasis_lane0_xe18=0xa760 +serdes_preemphasis_lane1_xe18=0xa760 +serdes_preemphasis_lane2_xe18=0xa760 +serdes_preemphasis_lane3_xe18=0xa760 + +# xe19 (40G) +portmap_20=77:40 +xgxs_rx_lane_map_20=0x123 +xgxs_tx_lane_map_20=0x1203 +phy_xaui_rx_polarity_flip_20=0x3 +phy_xaui_tx_polarity_flip_20=0xe +serdes_driver_current_lane0_xe19=0x2 +serdes_driver_current_lane1_xe19=0x2 +serdes_driver_current_lane2_xe19=0x2 +serdes_driver_current_lane3_xe19=0x2 +serdes_pre_driver_current_lane0_xe19=0x2 +serdes_pre_driver_current_lane1_xe19=0x2 +serdes_pre_driver_current_lane2_xe19=0x2 +serdes_pre_driver_current_lane3_xe19=0x2 +serdes_preemphasis_lane0_xe19=0xaf40 +serdes_preemphasis_lane1_xe19=0xaf40 +serdes_preemphasis_lane2_xe19=0xaf40 +serdes_preemphasis_lane3_xe19=0xaf40 + +# xe20 (40G) +portmap_21=109:40 +xgxs_rx_lane_map_21=0x132 +xgxs_tx_lane_map_21=0x132 +phy_xaui_rx_polarity_flip_21=0x8 +phy_xaui_tx_polarity_flip_21=0x0 +serdes_driver_current_lane0_xe20=0x1 +serdes_driver_current_lane1_xe20=0x1 +serdes_driver_current_lane2_xe20=0x1 +serdes_driver_current_lane3_xe20=0x2 +serdes_pre_driver_current_lane0_xe20=0x1 +serdes_pre_driver_current_lane1_xe20=0x1 +serdes_pre_driver_current_lane2_xe20=0x1 +serdes_pre_driver_current_lane3_xe20=0x2 +serdes_preemphasis_lane0_xe20=0xb330 +serdes_preemphasis_lane1_xe20=0xb330 +serdes_preemphasis_lane2_xe20=0xb330 +serdes_preemphasis_lane3_xe20=0xbff0 + +# xe21 (40G) +portmap_22=105:40 +xgxs_rx_lane_map_22=0x1320 +xgxs_tx_lane_map_22=0x3021 +phy_xaui_rx_polarity_flip_22=0xd +phy_xaui_tx_polarity_flip_22=0xb +serdes_driver_current_lane0_xe21=0x1 +serdes_driver_current_lane1_xe21=0x1 +serdes_driver_current_lane2_xe21=0x1 +serdes_driver_current_lane3_xe21=0x1 +serdes_pre_driver_current_lane0_xe21=0x1 +serdes_pre_driver_current_lane1_xe21=0x1 +serdes_pre_driver_current_lane2_xe21=0x1 +serdes_pre_driver_current_lane3_xe21=0x1 +serdes_preemphasis_lane0_xe21=0xb330 +serdes_preemphasis_lane1_xe21=0xb330 +serdes_preemphasis_lane2_xe21=0xb330 +serdes_preemphasis_lane3_xe21=0xb330 + +# xe22 (40G) +portmap_23=113:40 +xgxs_rx_lane_map_23=0x132 +xgxs_tx_lane_map_23=0x132 +phy_xaui_rx_polarity_flip_23=0x8 +phy_xaui_tx_polarity_flip_23=0x0 +serdes_driver_current_lane0_xe22=0x1 +serdes_driver_current_lane1_xe22=0x1 +serdes_driver_current_lane2_xe22=0x1 +serdes_driver_current_lane3_xe22=0x1 +serdes_pre_driver_current_lane0_xe22=0x1 +serdes_pre_driver_current_lane1_xe22=0x1 +serdes_pre_driver_current_lane2_xe22=0x1 +serdes_pre_driver_current_lane3_xe22=0x1 +serdes_preemphasis_lane0_xe22=0xbb10 +serdes_preemphasis_lane1_xe22=0xbb10 +serdes_preemphasis_lane2_xe22=0xbb10 +serdes_preemphasis_lane3_xe22=0xc2f0 + +# xe23 (40G) +portmap_24=117:40 +xgxs_rx_lane_map_24=0x231 +xgxs_tx_lane_map_24=0x1203 +phy_xaui_rx_polarity_flip_24=0x3 +phy_xaui_tx_polarity_flip_24=0xe +serdes_driver_current_lane0_xe23=0x3 +serdes_driver_current_lane1_xe23=0x5 +serdes_driver_current_lane2_xe23=0x3 +serdes_driver_current_lane3_xe23=0x3 +serdes_pre_driver_current_lane0_xe23=0x3 +serdes_pre_driver_current_lane1_xe23=0x5 +serdes_pre_driver_current_lane2_xe23=0x3 +serdes_pre_driver_current_lane3_xe23=0x3 +serdes_preemphasis_lane0_xe23=0xc6e0 +serdes_preemphasis_lane1_xe23=0xc6e0 +serdes_preemphasis_lane2_xe23=0xc6e0 +serdes_preemphasis_lane3_xe23=0xc6e0 + +# xe24 (40G) +portmap_25=125:40 +xgxs_rx_lane_map_25=0x132 +xgxs_tx_lane_map_25=0x132 +phy_xaui_rx_polarity_flip_25=0x8 +phy_xaui_tx_polarity_flip_25=0x0 +serdes_driver_current_lane0_xe24=0x4 +serdes_driver_current_lane1_xe24=0x4 +serdes_driver_current_lane2_xe24=0x4 +serdes_driver_current_lane3_xe24=0x4 +serdes_pre_driver_current_lane0_xe24=0x4 +serdes_pre_driver_current_lane1_xe24=0x4 +serdes_pre_driver_current_lane2_xe24=0x4 +serdes_pre_driver_current_lane3_xe24=0x4 +serdes_preemphasis_lane0_xe24=0xc6e0 +serdes_preemphasis_lane1_xe24=0xc6e0 +serdes_preemphasis_lane2_xe24=0xc6e0 +serdes_preemphasis_lane3_xe24=0xcec0 + +# xe25 (40G) +portmap_26=121:40 +xgxs_rx_lane_map_26=0x1320 +xgxs_tx_lane_map_26=0x3021 +phy_xaui_rx_polarity_flip_26=0xd +phy_xaui_tx_polarity_flip_26=0xb +serdes_driver_current_lane0_xe25=0x4 +serdes_driver_current_lane1_xe25=0x4 +serdes_driver_current_lane2_xe25=0x4 +serdes_driver_current_lane3_xe25=0x4 +serdes_pre_driver_current_lane0_xe25=0x4 +serdes_pre_driver_current_lane1_xe25=0x4 +serdes_pre_driver_current_lane2_xe25=0x4 +serdes_pre_driver_current_lane3_xe25=0x4 +serdes_preemphasis_lane0_xe25=0xc6e0 +serdes_preemphasis_lane1_xe25=0xc6e0 +serdes_preemphasis_lane2_xe25=0xc6e0 +serdes_preemphasis_lane3_xe25=0xc6e0 + +# xe26 (40G) +portmap_27=81:40 +xgxs_rx_lane_map_27=0x1320 +xgxs_tx_lane_map_27=0x2031 +phy_xaui_rx_polarity_flip_27=0x1 +phy_xaui_tx_polarity_flip_27=0x2 +serdes_driver_current_lane0_xe26=0x2 +serdes_driver_current_lane1_xe26=0x2 +serdes_driver_current_lane2_xe26=0x2 +serdes_driver_current_lane3_xe26=0x2 +serdes_pre_driver_current_lane0_xe26=0x2 +serdes_pre_driver_current_lane1_xe26=0x2 +serdes_pre_driver_current_lane2_xe26=0x2 +serdes_pre_driver_current_lane3_xe26=0x2 +serdes_preemphasis_lane0_xe26=0xbb10 +serdes_preemphasis_lane1_xe26=0xbb10 +serdes_preemphasis_lane2_xe26=0xbf00 +serdes_preemphasis_lane3_xe26=0xbb10 + +# xe27 (40G) +portmap_28=85:40 +xgxs_rx_lane_map_28=0x213 +xgxs_tx_lane_map_28=0x1203 +phy_xaui_rx_polarity_flip_28=0xc +phy_xaui_tx_polarity_flip_28=0xe +serdes_driver_current_lane0_xe27=0x4 +serdes_driver_current_lane1_xe27=0x5 +serdes_driver_current_lane2_xe27=0x4 +serdes_driver_current_lane3_xe27=0x5 +serdes_pre_driver_current_lane0_xe27=0x4 +serdes_pre_driver_current_lane1_xe27=0x5 +serdes_pre_driver_current_lane2_xe27=0x4 +serdes_pre_driver_current_lane3_xe27=0x5 +serdes_preemphasis_lane0_xe27=0xc2f0 +serdes_preemphasis_lane1_xe27=0xc6e0 +serdes_preemphasis_lane2_xe27=0xc6e0 +serdes_preemphasis_lane3_xe27=0xc6e0 + +# xe28 (40G) +portmap_29=93:40 +xgxs_rx_lane_map_29=0x1320 +xgxs_tx_lane_map_29=0x2031 +phy_xaui_rx_polarity_flip_29=0x1 +phy_xaui_tx_polarity_flip_29=0x2 +serdes_driver_current_lane0_xe28=0x4 +serdes_driver_current_lane1_xe28=0x4 +serdes_driver_current_lane2_xe28=0x4 +serdes_driver_current_lane3_xe28=0x4 +serdes_pre_driver_current_lane0_xe28=0x4 +serdes_pre_driver_current_lane1_xe28=0x4 +serdes_pre_driver_current_lane2_xe28=0x4 +serdes_pre_driver_current_lane3_xe28=0x4 +serdes_preemphasis_lane0_xe28=0xc2f0 +serdes_preemphasis_lane1_xe28=0xc2f0 +serdes_preemphasis_lane2_xe28=0xc2f0 +serdes_preemphasis_lane3_xe28=0xc2f0 + +# xe29 (40G) +portmap_30=89:40 +xgxs_rx_lane_map_30=0x1320 +xgxs_tx_lane_map_30=0x3021 +phy_xaui_rx_polarity_flip_30=0x2 +phy_xaui_tx_polarity_flip_30=0xb +serdes_driver_current_lane0_xe29=0x4 +serdes_driver_current_lane1_xe29=0x4 +serdes_driver_current_lane2_xe29=0x4 +serdes_driver_current_lane3_xe29=0x4 +serdes_pre_driver_current_lane0_xe29=0x4 +serdes_pre_driver_current_lane1_xe29=0x4 +serdes_pre_driver_current_lane2_xe29=0x4 +serdes_pre_driver_current_lane3_xe29=0x4 +serdes_preemphasis_lane0_xe29=0xcad0 +serdes_preemphasis_lane1_xe29=0xc6e0 +serdes_preemphasis_lane2_xe29=0xc6e0 +serdes_preemphasis_lane3_xe29=0xc6e0 + +# xe30 (40G) +portmap_31=101:40 +xgxs_rx_lane_map_31=0x1320 +xgxs_tx_lane_map_31=0x1203 +phy_xaui_rx_polarity_flip_31=0x1 +phy_xaui_tx_polarity_flip_31=0x6 +serdes_driver_current_lane0_xe30=0x6 +serdes_driver_current_lane1_xe30=0x6 +serdes_driver_current_lane2_xe30=0x6 +serdes_driver_current_lane3_xe30=0x7 +serdes_pre_driver_current_lane0_xe30=0x6 +serdes_pre_driver_current_lane1_xe30=0x6 +serdes_pre_driver_current_lane2_xe30=0x6 +serdes_pre_driver_current_lane3_xe30=0x7 +serdes_preemphasis_lane0_xe30=0xcec0 +serdes_preemphasis_lane1_xe30=0xcec0 +serdes_preemphasis_lane2_xe30=0xcad0 +serdes_preemphasis_lane3_xe30=0xc6e0 + +# xe31 (40G) +portmap_32=97:40 +xgxs_rx_lane_map_32=0x213 +xgxs_tx_lane_map_32=0x2031 +phy_xaui_rx_polarity_flip_32=0xc +phy_xaui_tx_polarity_flip_32=0x3 +serdes_driver_current_lane0_xe31=0x5 +serdes_driver_current_lane1_xe31=0x5 +serdes_driver_current_lane2_xe31=0x5 +serdes_driver_current_lane3_xe31=0x5 +serdes_pre_driver_current_lane0_xe31=0x5 +serdes_pre_driver_current_lane1_xe31=0x5 +serdes_pre_driver_current_lane2_xe31=0x5 +serdes_pre_driver_current_lane3_xe31=0x5 +serdes_preemphasis_lane0_xe31=0xcad0 +serdes_preemphasis_lane1_xe31=0xcad0 +serdes_preemphasis_lane2_xe31=0xcad0 +serdes_preemphasis_lane3_xe31=0xcad0 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers.json.j2 new file mode 100644 index 000000000000..b67cf577ab75 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers.json.j2 @@ -0,0 +1,3 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} + diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers_defaults_def.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers_defaults_def.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers_defaults_def.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers_defaults_t0.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers_defaults_t0.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers_defaults_t1.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/buffers_defaults_t1.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/pg_profile_lookup.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/pg_profile_lookup.ini new file mode 100644 index 000000000000..9f2eacb6fc42 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 56368 18432 55120 -3 2496 + 25000 5m 56368 18432 55120 -3 2496 + 40000 5m 56368 18432 55120 -3 2496 + 50000 5m 56368 18432 55120 -3 2496 + 100000 5m 56368 18432 55120 -3 2496 + 10000 40m 56368 18432 55120 -3 2496 + 25000 40m 56368 18432 55120 -3 2496 + 40000 40m 56368 18432 55120 -3 2496 + 50000 40m 56368 18432 55120 -3 2496 + 100000 40m 56368 18432 55120 -3 2496 + 10000 300m 56368 18432 55120 -3 2496 + 25000 300m 56368 18432 55120 -3 2496 + 40000 300m 56368 18432 55120 -3 2496 + 50000 300m 56368 18432 55120 -3 2496 + 100000 300m 56368 18432 55120 -3 2496 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/port_config.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/port_config.ini new file mode 100644 index 000000000000..95cf5eec9e4e --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias index speed +Ethernet0 25,26,27,28 fortyGigE0/0 0 40000 +Ethernet4 29,30,31,32 fortyGigE0/4 1 40000 +Ethernet8 33,34,35,36 fortyGigE0/8 2 40000 +Ethernet12 37,38,39,40 fortyGigE0/12 3 40000 +Ethernet16 45,46,47,48 fortyGigE0/16 4 40000 +Ethernet20 41,42,43,44 fortyGigE0/20 5 40000 +Ethernet24 1,2,3,4 fortyGigE0/24 6 40000 +Ethernet28 5,6,7,8 fortyGigE0/28 7 40000 +Ethernet32 13,14,15,16 fortyGigE0/32 8 40000 +Ethernet36 9,10,11,12 fortyGigE0/36 9 40000 +Ethernet40 17,18,19,20 fortyGigE0/40 10 40000 +Ethernet44 21,22,23,24 fortyGigE0/44 11 40000 +Ethernet48 53,54,55,56 fortyGigE0/48 12 40000 +Ethernet52 49,50,51,52 fortyGigE0/52 13 40000 +Ethernet56 57,58,59,60 fortyGigE0/56 14 40000 +Ethernet60 61,62,63,64 fortyGigE0/60 15 40000 +Ethernet64 69,70,71,72 fortyGigE0/64 16 40000 +Ethernet68 65,66,67,68 fortyGigE0/68 17 40000 +Ethernet72 73,74,75,76 fortyGigE0/72 18 40000 +Ethernet76 77,78,79,80 fortyGigE0/76 19 40000 +Ethernet80 109,110,111,112 fortyGigE0/80 20 40000 +Ethernet84 105,106,107,108 fortyGigE0/84 21 40000 +Ethernet88 113,114,115,116 fortyGigE0/88 22 40000 +Ethernet92 117,118,119,120 fortyGigE0/92 23 40000 +Ethernet96 125,126,127,128 fortyGigE0/96 24 40000 +Ethernet100 121,122,123,124 fortyGigE0/100 25 40000 +Ethernet104 81,82,83,84 fortyGigE0/104 26 40000 +Ethernet108 85,86,87,88 fortyGigE0/108 27 40000 +Ethernet112 93,94,95,96 fortyGigE0/112 28 40000 +Ethernet116 89,90,91,92 fortyGigE0/116 29 40000 +Ethernet120 101,102,103,104 fortyGigE0/120 30 40000 +Ethernet124 97,98,99,100 fortyGigE0/124 31 40000 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/qos.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/sai.profile new file mode 100644 index 000000000000..52e2e289af60 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/sai.profile @@ -0,0 +1,2 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm +SAI_NUM_ECMP_MEMBERS=32 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/td2-s6000-32x40G.config.bcm b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/td2-s6000-32x40G.config.bcm new file mode 100644 index 000000000000..4c94db7107c7 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/td2-s6000-32x40G.config.bcm @@ -0,0 +1,646 @@ +# Old LPM only configuration +# l2_mem_entries=163840 +# l3_mem_entries=90112 +# l3_alpm_enable=0 +# ipv6_lpm_128b_enable=0 +# +# ALPM enable +l3_alpm_enable=2 +ipv6_lpm_128b_enable=1 +l2_mem_entries=32768 +l3_mem_entries=16384 + +# From old config file +os=unix +higig2_hdr_mode=1 + +# Parity +parity_correction=1 +parity_enable=1 +stat_if_parity_enable=0 + +# +bcm_num_cos=8 +bcm_stat_interval=2000000 +l2xmsg_hostbuf_size=8192 +l2xmsg_mode=1 +lls_num_l2uc=12 +max_vp_lags=0 +miim_intr_enable=0 +mmu_lossless=0 +module_64ports=0 +schan_intr_enable=0 +stable_size=0x2000000 +tdma_timeout_usec=5000000 + +pbmp_oversubscribe=0x000007fffffffffffffffffffffffffe +pbmp_xport_xe=0x000007fffffffffffffffffffffffffe + +# Ports configuration +# xe0 (40G) +portmap_1=25:40 +xgxs_rx_lane_map_1=0x213 +xgxs_tx_lane_map_1=0x2031 +phy_xaui_rx_polarity_flip_1=0xe +phy_xaui_tx_polarity_flip_1=0x2 +serdes_driver_current_lane0_xe0=0x5 +serdes_driver_current_lane1_xe0=0x5 +serdes_driver_current_lane2_xe0=0x5 +serdes_driver_current_lane3_xe0=0x5 +serdes_pre_driver_current_lane0_xe0=0x5 +serdes_pre_driver_current_lane1_xe0=0x5 +serdes_pre_driver_current_lane2_xe0=0x5 +serdes_pre_driver_current_lane3_xe0=0x5 +serdes_preemphasis_lane0_xe0=0xcad0 +serdes_preemphasis_lane1_xe0=0xc6e0 +serdes_preemphasis_lane2_xe0=0xc6e0 +serdes_preemphasis_lane3_xe0=0xd2b0 + +# xe1 (40G) +portmap_2=29:40 +xgxs_rx_lane_map_2=0x213 +xgxs_tx_lane_map_2=0x213 +phy_xaui_rx_polarity_flip_2=0xc +phy_xaui_tx_polarity_flip_2=0x9 +serdes_driver_current_lane0_xe1=0x6 +serdes_driver_current_lane1_xe1=0x7 +serdes_driver_current_lane2_xe1=0x6 +serdes_driver_current_lane3_xe1=0x6 +serdes_pre_driver_current_lane0_xe1=0x6 +serdes_pre_driver_current_lane1_xe1=0x7 +serdes_pre_driver_current_lane2_xe1=0x6 +serdes_pre_driver_current_lane3_xe1=0x6 +serdes_preemphasis_lane0_xe1=0xc2f0 +serdes_preemphasis_lane1_xe1=0xd2b0 +serdes_preemphasis_lane2_xe1=0xc6e0 +serdes_preemphasis_lane3_xe1=0xc2f0 + +# xe2 (40G) +portmap_3=33:40 +xgxs_rx_lane_map_3=0x213 +xgxs_tx_lane_map_3=0x132 +phy_xaui_rx_polarity_flip_3=0xe +phy_xaui_tx_polarity_flip_3=0x2 +serdes_driver_current_lane0_xe2=0x4 +serdes_driver_current_lane1_xe2=0x4 +serdes_driver_current_lane2_xe2=0x4 +serdes_driver_current_lane3_xe2=0x4 +serdes_pre_driver_current_lane0_xe2=0x4 +serdes_pre_driver_current_lane1_xe2=0x4 +serdes_pre_driver_current_lane2_xe2=0x4 +serdes_pre_driver_current_lane3_xe2=0x4 +serdes_preemphasis_lane0_xe2=0xc6e0 +serdes_preemphasis_lane1_xe2=0xc6e0 +serdes_preemphasis_lane2_xe2=0xc6e0 +serdes_preemphasis_lane3_xe2=0xc6e0 + +# xe3 (40G) +portmap_4=37:40 +xgxs_rx_lane_map_4=0x213 +xgxs_tx_lane_map_4=0x1203 +phy_xaui_rx_polarity_flip_4=0x3 +phy_xaui_tx_polarity_flip_4=0xe +serdes_driver_current_lane0_xe3=0x4 +serdes_driver_current_lane1_xe3=0x4 +serdes_driver_current_lane2_xe3=0x4 +serdes_driver_current_lane3_xe3=0x4 +serdes_pre_driver_current_lane0_xe3=0x4 +serdes_pre_driver_current_lane1_xe3=0x4 +serdes_pre_driver_current_lane2_xe3=0x4 +serdes_pre_driver_current_lane3_xe3=0x4 +serdes_preemphasis_lane0_xe3=0xcad0 +serdes_preemphasis_lane1_xe3=0xcad0 +serdes_preemphasis_lane2_xe3=0xc2f0 +serdes_preemphasis_lane3_xe3=0xc2f0 + +# xe4 (40G) +portmap_5=45:40 +xgxs_rx_lane_map_5=0x213 +xgxs_tx_lane_map_5=0x213 +phy_xaui_rx_polarity_flip_5=0xe +phy_xaui_tx_polarity_flip_5=0x8 +serdes_driver_current_lane0_xe4=0x4 +serdes_driver_current_lane1_xe4=0x4 +serdes_driver_current_lane2_xe4=0x4 +serdes_driver_current_lane3_xe4=0x4 +serdes_pre_driver_current_lane0_xe4=0x4 +serdes_pre_driver_current_lane1_xe4=0x4 +serdes_pre_driver_current_lane2_xe4=0x4 +serdes_pre_driver_current_lane3_xe4=0x4 +serdes_preemphasis_lane0_xe4=0xc2f0 +serdes_preemphasis_lane1_xe4=0xc2f0 +serdes_preemphasis_lane2_xe4=0xc2f0 +serdes_preemphasis_lane3_xe4=0xc2f0 + +# xe5 (40G) +portmap_6=41:40 +xgxs_rx_lane_map_6=0x213 +xgxs_tx_lane_map_6=0x3021 +phy_xaui_rx_polarity_flip_6=0x3 +phy_xaui_tx_polarity_flip_6=0xb +serdes_driver_current_lane0_xe5=0x4 +serdes_driver_current_lane1_xe5=0x4 +serdes_driver_current_lane2_xe5=0x4 +serdes_driver_current_lane3_xe5=0x4 +serdes_pre_driver_current_lane0_xe5=0x4 +serdes_pre_driver_current_lane1_xe5=0x4 +serdes_pre_driver_current_lane2_xe5=0x4 +serdes_pre_driver_current_lane3_xe5=0x4 +serdes_preemphasis_lane0_xe5=0xc6e0 +serdes_preemphasis_lane1_xe5=0xc2f0 +serdes_preemphasis_lane2_xe5=0xc2f0 +serdes_preemphasis_lane3_xe5=0xcad0 + +# xe6 (40G) +portmap_7=1:40 +xgxs_rx_lane_map_7=0x213 +xgxs_tx_lane_map_7=0x2031 +phy_xaui_rx_polarity_flip_7=0xe +phy_xaui_tx_polarity_flip_7=0xd +serdes_driver_current_lane0_xe6=0x5 +serdes_driver_current_lane1_xe6=0x5 +serdes_driver_current_lane2_xe6=0x5 +serdes_driver_current_lane3_xe6=0x5 +serdes_pre_driver_current_lane0_xe6=0x5 +serdes_pre_driver_current_lane1_xe6=0x5 +serdes_pre_driver_current_lane2_xe6=0x5 +serdes_pre_driver_current_lane3_xe6=0x5 +serdes_preemphasis_lane0_xe6=0xc6e0 +serdes_preemphasis_lane1_xe6=0xcad0 +serdes_preemphasis_lane2_xe6=0xc6e0 +serdes_preemphasis_lane3_xe6=0xcad0 + +# xe7 (40G) +portmap_8=5:40 +xgxs_rx_lane_map_8=0x213 +xgxs_tx_lane_map_8=0x1203 +phy_xaui_rx_polarity_flip_8=0xc +phy_xaui_tx_polarity_flip_8=0x1 +serdes_driver_current_lane0_xe7=0x4 +serdes_driver_current_lane1_xe7=0x4 +serdes_driver_current_lane2_xe7=0x4 +serdes_driver_current_lane3_xe7=0x4 +serdes_pre_driver_current_lane0_xe7=0x4 +serdes_pre_driver_current_lane1_xe7=0x4 +serdes_pre_driver_current_lane2_xe7=0x4 +serdes_pre_driver_current_lane3_xe7=0x4 +serdes_preemphasis_lane0_xe7=0xc6e0 +serdes_preemphasis_lane1_xe7=0xc6e0 +serdes_preemphasis_lane2_xe7=0xc6e0 +serdes_preemphasis_lane3_xe7=0xc6e0 + +# xe8 (40G) +portmap_9=13:40 +xgxs_rx_lane_map_9=0x213 +xgxs_tx_lane_map_9=0x132 +phy_xaui_rx_polarity_flip_9=0xe +phy_xaui_tx_polarity_flip_9=0x0 +serdes_driver_current_lane0_xe8=0x2 +serdes_driver_current_lane1_xe8=0x3 +serdes_driver_current_lane2_xe8=0x2 +serdes_driver_current_lane3_xe8=0x2 +serdes_pre_driver_current_lane0_xe8=0x2 +serdes_pre_driver_current_lane1_xe8=0x3 +serdes_pre_driver_current_lane2_xe8=0x2 +serdes_pre_driver_current_lane3_xe8=0x2 +serdes_preemphasis_lane0_xe8=0xb270 +serdes_preemphasis_lane1_xe8=0xbb10 +serdes_preemphasis_lane2_xe8=0xb720 +serdes_preemphasis_lane3_xe8=0xb720 + +# xe9 (40G) +portmap_10=9:40 +xgxs_rx_lane_map_10=0x3120 +xgxs_tx_lane_map_10=0x3021 +phy_xaui_rx_polarity_flip_10=0x0 +phy_xaui_tx_polarity_flip_10=0x4 +serdes_driver_current_lane0_xe9=0x3 +serdes_driver_current_lane1_xe9=0x3 +serdes_driver_current_lane2_xe9=0x3 +serdes_driver_current_lane3_xe9=0x3 +serdes_pre_driver_current_lane0_xe9=0x3 +serdes_pre_driver_current_lane1_xe9=0x3 +serdes_pre_driver_current_lane2_xe9=0x3 +serdes_pre_driver_current_lane3_xe9=0x3 +serdes_preemphasis_lane0_xe9=0xc2f0 +serdes_preemphasis_lane1_xe9=0xc6e0 +serdes_preemphasis_lane2_xe9=0xbf00 +serdes_preemphasis_lane3_xe9=0xc2f0 + +# xe10 (40G) +portmap_11=17:40 +xgxs_rx_lane_map_11=0x213 +xgxs_tx_lane_map_11=0x132 +phy_xaui_rx_polarity_flip_11=0xe +phy_xaui_tx_polarity_flip_11=0x0 +serdes_driver_current_lane0_xe10=0x2 +serdes_driver_current_lane1_xe10=0x2 +serdes_driver_current_lane2_xe10=0x2 +serdes_driver_current_lane3_xe10=0x2 +serdes_pre_driver_current_lane0_xe10=0x2 +serdes_pre_driver_current_lane1_xe10=0x2 +serdes_pre_driver_current_lane2_xe10=0x2 +serdes_pre_driver_current_lane3_xe10=0x2 +serdes_preemphasis_lane0_xe10=0xb330 +serdes_preemphasis_lane1_xe10=0xbb10 +serdes_preemphasis_lane2_xe10=0xbb10 +serdes_preemphasis_lane3_xe10=0xbb10 + +# xe11 (40G) +portmap_12=21:40 +xgxs_rx_lane_map_12=0x123 +xgxs_tx_lane_map_12=0x1203 +phy_xaui_rx_polarity_flip_12=0xc +phy_xaui_tx_polarity_flip_12=0xe +serdes_driver_current_lane0_xe11=0x2 +serdes_driver_current_lane1_xe11=0x2 +serdes_driver_current_lane2_xe11=0x2 +serdes_driver_current_lane3_xe11=0x2 +serdes_pre_driver_current_lane0_xe11=0x2 +serdes_pre_driver_current_lane1_xe11=0x2 +serdes_pre_driver_current_lane2_xe11=0x2 +serdes_pre_driver_current_lane3_xe11=0x2 +serdes_preemphasis_lane0_xe11=0xb330 +serdes_preemphasis_lane1_xe11=0xb330 +serdes_preemphasis_lane2_xe11=0xb330 +serdes_preemphasis_lane3_xe11=0xb330 + +# xe12 (40G) +portmap_13=53:40 +xgxs_rx_lane_map_13=0x213 +xgxs_tx_lane_map_13=0x231 +phy_xaui_rx_polarity_flip_13=0x1 +phy_xaui_tx_polarity_flip_13=0x0 +serdes_driver_current_lane0_xe12=0x2 +serdes_driver_current_lane1_xe12=0x2 +serdes_driver_current_lane2_xe12=0x2 +serdes_driver_current_lane3_xe12=0x2 +serdes_pre_driver_current_lane0_xe12=0x2 +serdes_pre_driver_current_lane1_xe12=0x2 +serdes_pre_driver_current_lane2_xe12=0x2 +serdes_pre_driver_current_lane3_xe12=0x2 +serdes_preemphasis_lane0_xe12=0xaf40 +serdes_preemphasis_lane1_xe12=0xaf40 +serdes_preemphasis_lane2_xe12=0xaf40 +serdes_preemphasis_lane3_xe12=0xaf40 + +# xe13 (40G) +portmap_14=49:40 +xgxs_rx_lane_map_14=0x1302 +xgxs_tx_lane_map_14=0x2031 +phy_xaui_rx_polarity_flip_14=0xb +phy_xaui_tx_polarity_flip_14=0x3 +serdes_driver_current_lane0_xe13=0x2 +serdes_driver_current_lane1_xe13=0x2 +serdes_driver_current_lane2_xe13=0x2 +serdes_driver_current_lane3_xe13=0x2 +serdes_pre_driver_current_lane0_xe13=0x2 +serdes_pre_driver_current_lane1_xe13=0x2 +serdes_pre_driver_current_lane2_xe13=0x2 +serdes_pre_driver_current_lane3_xe13=0x2 +serdes_preemphasis_lane0_xe13=0xa760 +serdes_preemphasis_lane1_xe13=0xa760 +serdes_preemphasis_lane2_xe13=0xa760 +serdes_preemphasis_lane3_xe13=0xa760 + +# xe14 (40G) +portmap_15=57:40 +xgxs_rx_lane_map_15=0x213 +xgxs_tx_lane_map_15=0x2031 +phy_xaui_rx_polarity_flip_15=0x1 +phy_xaui_tx_polarity_flip_15=0x0 +serdes_driver_current_lane0_xe14=0x1 +serdes_driver_current_lane1_xe14=0x1 +serdes_driver_current_lane2_xe14=0x1 +serdes_driver_current_lane3_xe14=0x1 +serdes_pre_driver_current_lane0_xe14=0x1 +serdes_pre_driver_current_lane1_xe14=0x1 +serdes_pre_driver_current_lane2_xe14=0x1 +serdes_pre_driver_current_lane3_xe14=0x1 +serdes_preemphasis_lane0_xe14=0xa760 +serdes_preemphasis_lane1_xe14=0xa760 +serdes_preemphasis_lane2_xe14=0xa760 +serdes_preemphasis_lane3_xe14=0xa760 + +# xe15 (40G) +portmap_16=61:40 +xgxs_rx_lane_map_16=0x132 +xgxs_tx_lane_map_16=0x213 +phy_xaui_rx_polarity_flip_16=0x0 +phy_xaui_tx_polarity_flip_16=0x0 +serdes_driver_current_lane0_xe15=0x2 +serdes_driver_current_lane1_xe15=0x2 +serdes_driver_current_lane2_xe15=0x2 +serdes_driver_current_lane3_xe15=0x2 +serdes_pre_driver_current_lane0_xe15=0x2 +serdes_pre_driver_current_lane1_xe15=0x2 +serdes_pre_driver_current_lane2_xe15=0x2 +serdes_pre_driver_current_lane3_xe15=0x2 +serdes_preemphasis_lane0_xe15=0xa760 +serdes_preemphasis_lane1_xe15=0xa760 +serdes_preemphasis_lane2_xe15=0xa760 +serdes_preemphasis_lane3_xe15=0xa760 + +# xe16 (40G) +portmap_17=69:40 +xgxs_rx_lane_map_17=0x213 +xgxs_tx_lane_map_17=0x2130 +phy_xaui_rx_polarity_flip_17=0x1 +phy_xaui_tx_polarity_flip_17=0xf +serdes_driver_current_lane0_xe16=0x1 +serdes_driver_current_lane1_xe16=0x1 +serdes_driver_current_lane2_xe16=0x1 +serdes_driver_current_lane3_xe16=0x1 +serdes_pre_driver_current_lane0_xe16=0x1 +serdes_pre_driver_current_lane1_xe16=0x1 +serdes_pre_driver_current_lane2_xe16=0x1 +serdes_pre_driver_current_lane3_xe16=0x1 +serdes_preemphasis_lane0_xe16=0xa760 +serdes_preemphasis_lane1_xe16=0xa760 +serdes_preemphasis_lane2_xe16=0xa760 +serdes_preemphasis_lane3_xe16=0xa760 + +# xe17 (40G) +portmap_18=65:40 +xgxs_rx_lane_map_18=0x132 +xgxs_tx_lane_map_18=0x2031 +phy_xaui_rx_polarity_flip_18=0x3 +phy_xaui_tx_polarity_flip_18=0x9 +serdes_driver_current_lane0_xe17=0x1 +serdes_driver_current_lane1_xe17=0x1 +serdes_driver_current_lane2_xe17=0x1 +serdes_driver_current_lane3_xe17=0x1 +serdes_pre_driver_current_lane0_xe17=0x1 +serdes_pre_driver_current_lane1_xe17=0x1 +serdes_pre_driver_current_lane2_xe17=0x1 +serdes_pre_driver_current_lane3_xe17=0x1 +serdes_preemphasis_lane0_xe17=0xa370 +serdes_preemphasis_lane1_xe17=0xa370 +serdes_preemphasis_lane2_xe17=0xa370 +serdes_preemphasis_lane3_xe17=0xa370 + +# xe18 (40G) +portmap_19=73:40 +xgxs_rx_lane_map_19=0x213 +xgxs_tx_lane_map_19=0x2031 +phy_xaui_rx_polarity_flip_19=0x1 +phy_xaui_tx_polarity_flip_19=0x0 +serdes_driver_current_lane0_xe18=0x2 +serdes_driver_current_lane1_xe18=0x2 +serdes_driver_current_lane2_xe18=0x2 +serdes_driver_current_lane3_xe18=0x2 +serdes_pre_driver_current_lane0_xe18=0x2 +serdes_pre_driver_current_lane1_xe18=0x2 +serdes_pre_driver_current_lane2_xe18=0x2 +serdes_pre_driver_current_lane3_xe18=0x2 +serdes_preemphasis_lane0_xe18=0xa760 +serdes_preemphasis_lane1_xe18=0xa760 +serdes_preemphasis_lane2_xe18=0xa760 +serdes_preemphasis_lane3_xe18=0xa760 + +# xe19 (40G) +portmap_20=77:40 +xgxs_rx_lane_map_20=0x123 +xgxs_tx_lane_map_20=0x1203 +phy_xaui_rx_polarity_flip_20=0x3 +phy_xaui_tx_polarity_flip_20=0xe +serdes_driver_current_lane0_xe19=0x2 +serdes_driver_current_lane1_xe19=0x2 +serdes_driver_current_lane2_xe19=0x2 +serdes_driver_current_lane3_xe19=0x2 +serdes_pre_driver_current_lane0_xe19=0x2 +serdes_pre_driver_current_lane1_xe19=0x2 +serdes_pre_driver_current_lane2_xe19=0x2 +serdes_pre_driver_current_lane3_xe19=0x2 +serdes_preemphasis_lane0_xe19=0xaf40 +serdes_preemphasis_lane1_xe19=0xaf40 +serdes_preemphasis_lane2_xe19=0xaf40 +serdes_preemphasis_lane3_xe19=0xaf40 + +# xe20 (40G) +portmap_21=109:40 +xgxs_rx_lane_map_21=0x132 +xgxs_tx_lane_map_21=0x132 +phy_xaui_rx_polarity_flip_21=0x8 +phy_xaui_tx_polarity_flip_21=0x0 +serdes_driver_current_lane0_xe20=0x1 +serdes_driver_current_lane1_xe20=0x1 +serdes_driver_current_lane2_xe20=0x1 +serdes_driver_current_lane3_xe20=0x2 +serdes_pre_driver_current_lane0_xe20=0x1 +serdes_pre_driver_current_lane1_xe20=0x1 +serdes_pre_driver_current_lane2_xe20=0x1 +serdes_pre_driver_current_lane3_xe20=0x2 +serdes_preemphasis_lane0_xe20=0xb330 +serdes_preemphasis_lane1_xe20=0xb330 +serdes_preemphasis_lane2_xe20=0xb330 +serdes_preemphasis_lane3_xe20=0xbff0 + +# xe21 (40G) +portmap_22=105:40 +xgxs_rx_lane_map_22=0x1320 +xgxs_tx_lane_map_22=0x3021 +phy_xaui_rx_polarity_flip_22=0xd +phy_xaui_tx_polarity_flip_22=0xb +serdes_driver_current_lane0_xe21=0x1 +serdes_driver_current_lane1_xe21=0x1 +serdes_driver_current_lane2_xe21=0x1 +serdes_driver_current_lane3_xe21=0x1 +serdes_pre_driver_current_lane0_xe21=0x1 +serdes_pre_driver_current_lane1_xe21=0x1 +serdes_pre_driver_current_lane2_xe21=0x1 +serdes_pre_driver_current_lane3_xe21=0x1 +serdes_preemphasis_lane0_xe21=0xb330 +serdes_preemphasis_lane1_xe21=0xb330 +serdes_preemphasis_lane2_xe21=0xb330 +serdes_preemphasis_lane3_xe21=0xb330 + +# xe22 (40G) +portmap_23=113:40 +xgxs_rx_lane_map_23=0x132 +xgxs_tx_lane_map_23=0x132 +phy_xaui_rx_polarity_flip_23=0x8 +phy_xaui_tx_polarity_flip_23=0x0 +serdes_driver_current_lane0_xe22=0x1 +serdes_driver_current_lane1_xe22=0x1 +serdes_driver_current_lane2_xe22=0x1 +serdes_driver_current_lane3_xe22=0x1 +serdes_pre_driver_current_lane0_xe22=0x1 +serdes_pre_driver_current_lane1_xe22=0x1 +serdes_pre_driver_current_lane2_xe22=0x1 +serdes_pre_driver_current_lane3_xe22=0x1 +serdes_preemphasis_lane0_xe22=0xbb10 +serdes_preemphasis_lane1_xe22=0xbb10 +serdes_preemphasis_lane2_xe22=0xbb10 +serdes_preemphasis_lane3_xe22=0xc2f0 + +# xe23 (40G) +portmap_24=117:40 +xgxs_rx_lane_map_24=0x231 +xgxs_tx_lane_map_24=0x1203 +phy_xaui_rx_polarity_flip_24=0x3 +phy_xaui_tx_polarity_flip_24=0xe +serdes_driver_current_lane0_xe23=0x3 +serdes_driver_current_lane1_xe23=0x5 +serdes_driver_current_lane2_xe23=0x3 +serdes_driver_current_lane3_xe23=0x3 +serdes_pre_driver_current_lane0_xe23=0x3 +serdes_pre_driver_current_lane1_xe23=0x5 +serdes_pre_driver_current_lane2_xe23=0x3 +serdes_pre_driver_current_lane3_xe23=0x3 +serdes_preemphasis_lane0_xe23=0xc6e0 +serdes_preemphasis_lane1_xe23=0xc6e0 +serdes_preemphasis_lane2_xe23=0xc6e0 +serdes_preemphasis_lane3_xe23=0xc6e0 + +# xe24 (40G) +portmap_25=125:40 +xgxs_rx_lane_map_25=0x132 +xgxs_tx_lane_map_25=0x132 +phy_xaui_rx_polarity_flip_25=0x8 +phy_xaui_tx_polarity_flip_25=0x0 +serdes_driver_current_lane0_xe24=0x4 +serdes_driver_current_lane1_xe24=0x4 +serdes_driver_current_lane2_xe24=0x4 +serdes_driver_current_lane3_xe24=0x4 +serdes_pre_driver_current_lane0_xe24=0x4 +serdes_pre_driver_current_lane1_xe24=0x4 +serdes_pre_driver_current_lane2_xe24=0x4 +serdes_pre_driver_current_lane3_xe24=0x4 +serdes_preemphasis_lane0_xe24=0xc6e0 +serdes_preemphasis_lane1_xe24=0xc6e0 +serdes_preemphasis_lane2_xe24=0xc6e0 +serdes_preemphasis_lane3_xe24=0xcec0 + +# xe25 (40G) +portmap_26=121:40 +xgxs_rx_lane_map_26=0x1320 +xgxs_tx_lane_map_26=0x3021 +phy_xaui_rx_polarity_flip_26=0xd +phy_xaui_tx_polarity_flip_26=0xb +serdes_driver_current_lane0_xe25=0x4 +serdes_driver_current_lane1_xe25=0x4 +serdes_driver_current_lane2_xe25=0x4 +serdes_driver_current_lane3_xe25=0x4 +serdes_pre_driver_current_lane0_xe25=0x4 +serdes_pre_driver_current_lane1_xe25=0x4 +serdes_pre_driver_current_lane2_xe25=0x4 +serdes_pre_driver_current_lane3_xe25=0x4 +serdes_preemphasis_lane0_xe25=0xc6e0 +serdes_preemphasis_lane1_xe25=0xc6e0 +serdes_preemphasis_lane2_xe25=0xc6e0 +serdes_preemphasis_lane3_xe25=0xc6e0 + +# xe26 (40G) +portmap_27=81:40 +xgxs_rx_lane_map_27=0x1320 +xgxs_tx_lane_map_27=0x2031 +phy_xaui_rx_polarity_flip_27=0x1 +phy_xaui_tx_polarity_flip_27=0x2 +serdes_driver_current_lane0_xe26=0x2 +serdes_driver_current_lane1_xe26=0x2 +serdes_driver_current_lane2_xe26=0x2 +serdes_driver_current_lane3_xe26=0x2 +serdes_pre_driver_current_lane0_xe26=0x2 +serdes_pre_driver_current_lane1_xe26=0x2 +serdes_pre_driver_current_lane2_xe26=0x2 +serdes_pre_driver_current_lane3_xe26=0x2 +serdes_preemphasis_lane0_xe26=0xbb10 +serdes_preemphasis_lane1_xe26=0xbb10 +serdes_preemphasis_lane2_xe26=0xbf00 +serdes_preemphasis_lane3_xe26=0xbb10 + +# xe27 (40G) +portmap_28=85:40 +xgxs_rx_lane_map_28=0x213 +xgxs_tx_lane_map_28=0x1203 +phy_xaui_rx_polarity_flip_28=0xc +phy_xaui_tx_polarity_flip_28=0xe +serdes_driver_current_lane0_xe27=0x4 +serdes_driver_current_lane1_xe27=0x5 +serdes_driver_current_lane2_xe27=0x4 +serdes_driver_current_lane3_xe27=0x5 +serdes_pre_driver_current_lane0_xe27=0x4 +serdes_pre_driver_current_lane1_xe27=0x5 +serdes_pre_driver_current_lane2_xe27=0x4 +serdes_pre_driver_current_lane3_xe27=0x5 +serdes_preemphasis_lane0_xe27=0xc2f0 +serdes_preemphasis_lane1_xe27=0xc6e0 +serdes_preemphasis_lane2_xe27=0xc6e0 +serdes_preemphasis_lane3_xe27=0xc6e0 + +# xe28 (40G) +portmap_29=93:40 +xgxs_rx_lane_map_29=0x1320 +xgxs_tx_lane_map_29=0x2031 +phy_xaui_rx_polarity_flip_29=0x1 +phy_xaui_tx_polarity_flip_29=0x2 +serdes_driver_current_lane0_xe28=0x4 +serdes_driver_current_lane1_xe28=0x4 +serdes_driver_current_lane2_xe28=0x4 +serdes_driver_current_lane3_xe28=0x4 +serdes_pre_driver_current_lane0_xe28=0x4 +serdes_pre_driver_current_lane1_xe28=0x4 +serdes_pre_driver_current_lane2_xe28=0x4 +serdes_pre_driver_current_lane3_xe28=0x4 +serdes_preemphasis_lane0_xe28=0xc2f0 +serdes_preemphasis_lane1_xe28=0xc2f0 +serdes_preemphasis_lane2_xe28=0xc2f0 +serdes_preemphasis_lane3_xe28=0xc2f0 + +# xe29 (40G) +portmap_30=89:40 +xgxs_rx_lane_map_30=0x1320 +xgxs_tx_lane_map_30=0x3021 +phy_xaui_rx_polarity_flip_30=0x2 +phy_xaui_tx_polarity_flip_30=0xb +serdes_driver_current_lane0_xe29=0x4 +serdes_driver_current_lane1_xe29=0x4 +serdes_driver_current_lane2_xe29=0x4 +serdes_driver_current_lane3_xe29=0x4 +serdes_pre_driver_current_lane0_xe29=0x4 +serdes_pre_driver_current_lane1_xe29=0x4 +serdes_pre_driver_current_lane2_xe29=0x4 +serdes_pre_driver_current_lane3_xe29=0x4 +serdes_preemphasis_lane0_xe29=0xcad0 +serdes_preemphasis_lane1_xe29=0xc6e0 +serdes_preemphasis_lane2_xe29=0xc6e0 +serdes_preemphasis_lane3_xe29=0xc6e0 + +# xe30 (40G) +portmap_31=101:40 +xgxs_rx_lane_map_31=0x1320 +xgxs_tx_lane_map_31=0x1203 +phy_xaui_rx_polarity_flip_31=0x1 +phy_xaui_tx_polarity_flip_31=0x6 +serdes_driver_current_lane0_xe30=0x6 +serdes_driver_current_lane1_xe30=0x6 +serdes_driver_current_lane2_xe30=0x6 +serdes_driver_current_lane3_xe30=0x7 +serdes_pre_driver_current_lane0_xe30=0x6 +serdes_pre_driver_current_lane1_xe30=0x6 +serdes_pre_driver_current_lane2_xe30=0x6 +serdes_pre_driver_current_lane3_xe30=0x7 +serdes_preemphasis_lane0_xe30=0xcec0 +serdes_preemphasis_lane1_xe30=0xcec0 +serdes_preemphasis_lane2_xe30=0xcad0 +serdes_preemphasis_lane3_xe30=0xc6e0 + +# xe31 (40G) +portmap_32=97:40 +xgxs_rx_lane_map_32=0x213 +xgxs_tx_lane_map_32=0x2031 +phy_xaui_rx_polarity_flip_32=0xc +phy_xaui_tx_polarity_flip_32=0x3 +serdes_driver_current_lane0_xe31=0x5 +serdes_driver_current_lane1_xe31=0x5 +serdes_driver_current_lane2_xe31=0x5 +serdes_driver_current_lane3_xe31=0x5 +serdes_pre_driver_current_lane0_xe31=0x5 +serdes_pre_driver_current_lane1_xe31=0x5 +serdes_pre_driver_current_lane2_xe31=0x5 +serdes_pre_driver_current_lane3_xe31=0x5 +serdes_preemphasis_lane0_xe31=0xcad0 +serdes_preemphasis_lane1_xe31=0xcad0 +serdes_preemphasis_lane2_xe31=0xcad0 +serdes_preemphasis_lane3_xe31=0xcad0 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers.json.j2 new file mode 100644 index 000000000000..b67cf577ab75 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers.json.j2 @@ -0,0 +1,3 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} + diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers_defaults_def.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers_defaults_def.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers_defaults_def.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers_defaults_t0.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers_defaults_t0.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers_defaults_t1.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..38e34eb571e8 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/buffers_defaults_t1.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/pg_profile_lookup.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/pg_profile_lookup.ini new file mode 100644 index 000000000000..9f2eacb6fc42 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 56368 18432 55120 -3 2496 + 25000 5m 56368 18432 55120 -3 2496 + 40000 5m 56368 18432 55120 -3 2496 + 50000 5m 56368 18432 55120 -3 2496 + 100000 5m 56368 18432 55120 -3 2496 + 10000 40m 56368 18432 55120 -3 2496 + 25000 40m 56368 18432 55120 -3 2496 + 40000 40m 56368 18432 55120 -3 2496 + 50000 40m 56368 18432 55120 -3 2496 + 100000 40m 56368 18432 55120 -3 2496 + 10000 300m 56368 18432 55120 -3 2496 + 25000 300m 56368 18432 55120 -3 2496 + 40000 300m 56368 18432 55120 -3 2496 + 50000 300m 56368 18432 55120 -3 2496 + 100000 300m 56368 18432 55120 -3 2496 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/port_config.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/port_config.ini new file mode 100644 index 000000000000..95cf5eec9e4e --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias index speed +Ethernet0 25,26,27,28 fortyGigE0/0 0 40000 +Ethernet4 29,30,31,32 fortyGigE0/4 1 40000 +Ethernet8 33,34,35,36 fortyGigE0/8 2 40000 +Ethernet12 37,38,39,40 fortyGigE0/12 3 40000 +Ethernet16 45,46,47,48 fortyGigE0/16 4 40000 +Ethernet20 41,42,43,44 fortyGigE0/20 5 40000 +Ethernet24 1,2,3,4 fortyGigE0/24 6 40000 +Ethernet28 5,6,7,8 fortyGigE0/28 7 40000 +Ethernet32 13,14,15,16 fortyGigE0/32 8 40000 +Ethernet36 9,10,11,12 fortyGigE0/36 9 40000 +Ethernet40 17,18,19,20 fortyGigE0/40 10 40000 +Ethernet44 21,22,23,24 fortyGigE0/44 11 40000 +Ethernet48 53,54,55,56 fortyGigE0/48 12 40000 +Ethernet52 49,50,51,52 fortyGigE0/52 13 40000 +Ethernet56 57,58,59,60 fortyGigE0/56 14 40000 +Ethernet60 61,62,63,64 fortyGigE0/60 15 40000 +Ethernet64 69,70,71,72 fortyGigE0/64 16 40000 +Ethernet68 65,66,67,68 fortyGigE0/68 17 40000 +Ethernet72 73,74,75,76 fortyGigE0/72 18 40000 +Ethernet76 77,78,79,80 fortyGigE0/76 19 40000 +Ethernet80 109,110,111,112 fortyGigE0/80 20 40000 +Ethernet84 105,106,107,108 fortyGigE0/84 21 40000 +Ethernet88 113,114,115,116 fortyGigE0/88 22 40000 +Ethernet92 117,118,119,120 fortyGigE0/92 23 40000 +Ethernet96 125,126,127,128 fortyGigE0/96 24 40000 +Ethernet100 121,122,123,124 fortyGigE0/100 25 40000 +Ethernet104 81,82,83,84 fortyGigE0/104 26 40000 +Ethernet108 85,86,87,88 fortyGigE0/108 27 40000 +Ethernet112 93,94,95,96 fortyGigE0/112 28 40000 +Ethernet116 89,90,91,92 fortyGigE0/116 29 40000 +Ethernet120 101,102,103,104 fortyGigE0/120 30 40000 +Ethernet124 97,98,99,100 fortyGigE0/124 31 40000 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/qos.json.j2 b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/sai.profile new file mode 100644 index 000000000000..52e2e289af60 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/sai.profile @@ -0,0 +1,2 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm +SAI_NUM_ECMP_MEMBERS=32 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/td2-s6000-32x40G.config.bcm b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/td2-s6000-32x40G.config.bcm new file mode 100644 index 000000000000..4c94db7107c7 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/td2-s6000-32x40G.config.bcm @@ -0,0 +1,646 @@ +# Old LPM only configuration +# l2_mem_entries=163840 +# l3_mem_entries=90112 +# l3_alpm_enable=0 +# ipv6_lpm_128b_enable=0 +# +# ALPM enable +l3_alpm_enable=2 +ipv6_lpm_128b_enable=1 +l2_mem_entries=32768 +l3_mem_entries=16384 + +# From old config file +os=unix +higig2_hdr_mode=1 + +# Parity +parity_correction=1 +parity_enable=1 +stat_if_parity_enable=0 + +# +bcm_num_cos=8 +bcm_stat_interval=2000000 +l2xmsg_hostbuf_size=8192 +l2xmsg_mode=1 +lls_num_l2uc=12 +max_vp_lags=0 +miim_intr_enable=0 +mmu_lossless=0 +module_64ports=0 +schan_intr_enable=0 +stable_size=0x2000000 +tdma_timeout_usec=5000000 + +pbmp_oversubscribe=0x000007fffffffffffffffffffffffffe +pbmp_xport_xe=0x000007fffffffffffffffffffffffffe + +# Ports configuration +# xe0 (40G) +portmap_1=25:40 +xgxs_rx_lane_map_1=0x213 +xgxs_tx_lane_map_1=0x2031 +phy_xaui_rx_polarity_flip_1=0xe +phy_xaui_tx_polarity_flip_1=0x2 +serdes_driver_current_lane0_xe0=0x5 +serdes_driver_current_lane1_xe0=0x5 +serdes_driver_current_lane2_xe0=0x5 +serdes_driver_current_lane3_xe0=0x5 +serdes_pre_driver_current_lane0_xe0=0x5 +serdes_pre_driver_current_lane1_xe0=0x5 +serdes_pre_driver_current_lane2_xe0=0x5 +serdes_pre_driver_current_lane3_xe0=0x5 +serdes_preemphasis_lane0_xe0=0xcad0 +serdes_preemphasis_lane1_xe0=0xc6e0 +serdes_preemphasis_lane2_xe0=0xc6e0 +serdes_preemphasis_lane3_xe0=0xd2b0 + +# xe1 (40G) +portmap_2=29:40 +xgxs_rx_lane_map_2=0x213 +xgxs_tx_lane_map_2=0x213 +phy_xaui_rx_polarity_flip_2=0xc +phy_xaui_tx_polarity_flip_2=0x9 +serdes_driver_current_lane0_xe1=0x6 +serdes_driver_current_lane1_xe1=0x7 +serdes_driver_current_lane2_xe1=0x6 +serdes_driver_current_lane3_xe1=0x6 +serdes_pre_driver_current_lane0_xe1=0x6 +serdes_pre_driver_current_lane1_xe1=0x7 +serdes_pre_driver_current_lane2_xe1=0x6 +serdes_pre_driver_current_lane3_xe1=0x6 +serdes_preemphasis_lane0_xe1=0xc2f0 +serdes_preemphasis_lane1_xe1=0xd2b0 +serdes_preemphasis_lane2_xe1=0xc6e0 +serdes_preemphasis_lane3_xe1=0xc2f0 + +# xe2 (40G) +portmap_3=33:40 +xgxs_rx_lane_map_3=0x213 +xgxs_tx_lane_map_3=0x132 +phy_xaui_rx_polarity_flip_3=0xe +phy_xaui_tx_polarity_flip_3=0x2 +serdes_driver_current_lane0_xe2=0x4 +serdes_driver_current_lane1_xe2=0x4 +serdes_driver_current_lane2_xe2=0x4 +serdes_driver_current_lane3_xe2=0x4 +serdes_pre_driver_current_lane0_xe2=0x4 +serdes_pre_driver_current_lane1_xe2=0x4 +serdes_pre_driver_current_lane2_xe2=0x4 +serdes_pre_driver_current_lane3_xe2=0x4 +serdes_preemphasis_lane0_xe2=0xc6e0 +serdes_preemphasis_lane1_xe2=0xc6e0 +serdes_preemphasis_lane2_xe2=0xc6e0 +serdes_preemphasis_lane3_xe2=0xc6e0 + +# xe3 (40G) +portmap_4=37:40 +xgxs_rx_lane_map_4=0x213 +xgxs_tx_lane_map_4=0x1203 +phy_xaui_rx_polarity_flip_4=0x3 +phy_xaui_tx_polarity_flip_4=0xe +serdes_driver_current_lane0_xe3=0x4 +serdes_driver_current_lane1_xe3=0x4 +serdes_driver_current_lane2_xe3=0x4 +serdes_driver_current_lane3_xe3=0x4 +serdes_pre_driver_current_lane0_xe3=0x4 +serdes_pre_driver_current_lane1_xe3=0x4 +serdes_pre_driver_current_lane2_xe3=0x4 +serdes_pre_driver_current_lane3_xe3=0x4 +serdes_preemphasis_lane0_xe3=0xcad0 +serdes_preemphasis_lane1_xe3=0xcad0 +serdes_preemphasis_lane2_xe3=0xc2f0 +serdes_preemphasis_lane3_xe3=0xc2f0 + +# xe4 (40G) +portmap_5=45:40 +xgxs_rx_lane_map_5=0x213 +xgxs_tx_lane_map_5=0x213 +phy_xaui_rx_polarity_flip_5=0xe +phy_xaui_tx_polarity_flip_5=0x8 +serdes_driver_current_lane0_xe4=0x4 +serdes_driver_current_lane1_xe4=0x4 +serdes_driver_current_lane2_xe4=0x4 +serdes_driver_current_lane3_xe4=0x4 +serdes_pre_driver_current_lane0_xe4=0x4 +serdes_pre_driver_current_lane1_xe4=0x4 +serdes_pre_driver_current_lane2_xe4=0x4 +serdes_pre_driver_current_lane3_xe4=0x4 +serdes_preemphasis_lane0_xe4=0xc2f0 +serdes_preemphasis_lane1_xe4=0xc2f0 +serdes_preemphasis_lane2_xe4=0xc2f0 +serdes_preemphasis_lane3_xe4=0xc2f0 + +# xe5 (40G) +portmap_6=41:40 +xgxs_rx_lane_map_6=0x213 +xgxs_tx_lane_map_6=0x3021 +phy_xaui_rx_polarity_flip_6=0x3 +phy_xaui_tx_polarity_flip_6=0xb +serdes_driver_current_lane0_xe5=0x4 +serdes_driver_current_lane1_xe5=0x4 +serdes_driver_current_lane2_xe5=0x4 +serdes_driver_current_lane3_xe5=0x4 +serdes_pre_driver_current_lane0_xe5=0x4 +serdes_pre_driver_current_lane1_xe5=0x4 +serdes_pre_driver_current_lane2_xe5=0x4 +serdes_pre_driver_current_lane3_xe5=0x4 +serdes_preemphasis_lane0_xe5=0xc6e0 +serdes_preemphasis_lane1_xe5=0xc2f0 +serdes_preemphasis_lane2_xe5=0xc2f0 +serdes_preemphasis_lane3_xe5=0xcad0 + +# xe6 (40G) +portmap_7=1:40 +xgxs_rx_lane_map_7=0x213 +xgxs_tx_lane_map_7=0x2031 +phy_xaui_rx_polarity_flip_7=0xe +phy_xaui_tx_polarity_flip_7=0xd +serdes_driver_current_lane0_xe6=0x5 +serdes_driver_current_lane1_xe6=0x5 +serdes_driver_current_lane2_xe6=0x5 +serdes_driver_current_lane3_xe6=0x5 +serdes_pre_driver_current_lane0_xe6=0x5 +serdes_pre_driver_current_lane1_xe6=0x5 +serdes_pre_driver_current_lane2_xe6=0x5 +serdes_pre_driver_current_lane3_xe6=0x5 +serdes_preemphasis_lane0_xe6=0xc6e0 +serdes_preemphasis_lane1_xe6=0xcad0 +serdes_preemphasis_lane2_xe6=0xc6e0 +serdes_preemphasis_lane3_xe6=0xcad0 + +# xe7 (40G) +portmap_8=5:40 +xgxs_rx_lane_map_8=0x213 +xgxs_tx_lane_map_8=0x1203 +phy_xaui_rx_polarity_flip_8=0xc +phy_xaui_tx_polarity_flip_8=0x1 +serdes_driver_current_lane0_xe7=0x4 +serdes_driver_current_lane1_xe7=0x4 +serdes_driver_current_lane2_xe7=0x4 +serdes_driver_current_lane3_xe7=0x4 +serdes_pre_driver_current_lane0_xe7=0x4 +serdes_pre_driver_current_lane1_xe7=0x4 +serdes_pre_driver_current_lane2_xe7=0x4 +serdes_pre_driver_current_lane3_xe7=0x4 +serdes_preemphasis_lane0_xe7=0xc6e0 +serdes_preemphasis_lane1_xe7=0xc6e0 +serdes_preemphasis_lane2_xe7=0xc6e0 +serdes_preemphasis_lane3_xe7=0xc6e0 + +# xe8 (40G) +portmap_9=13:40 +xgxs_rx_lane_map_9=0x213 +xgxs_tx_lane_map_9=0x132 +phy_xaui_rx_polarity_flip_9=0xe +phy_xaui_tx_polarity_flip_9=0x0 +serdes_driver_current_lane0_xe8=0x2 +serdes_driver_current_lane1_xe8=0x3 +serdes_driver_current_lane2_xe8=0x2 +serdes_driver_current_lane3_xe8=0x2 +serdes_pre_driver_current_lane0_xe8=0x2 +serdes_pre_driver_current_lane1_xe8=0x3 +serdes_pre_driver_current_lane2_xe8=0x2 +serdes_pre_driver_current_lane3_xe8=0x2 +serdes_preemphasis_lane0_xe8=0xb270 +serdes_preemphasis_lane1_xe8=0xbb10 +serdes_preemphasis_lane2_xe8=0xb720 +serdes_preemphasis_lane3_xe8=0xb720 + +# xe9 (40G) +portmap_10=9:40 +xgxs_rx_lane_map_10=0x3120 +xgxs_tx_lane_map_10=0x3021 +phy_xaui_rx_polarity_flip_10=0x0 +phy_xaui_tx_polarity_flip_10=0x4 +serdes_driver_current_lane0_xe9=0x3 +serdes_driver_current_lane1_xe9=0x3 +serdes_driver_current_lane2_xe9=0x3 +serdes_driver_current_lane3_xe9=0x3 +serdes_pre_driver_current_lane0_xe9=0x3 +serdes_pre_driver_current_lane1_xe9=0x3 +serdes_pre_driver_current_lane2_xe9=0x3 +serdes_pre_driver_current_lane3_xe9=0x3 +serdes_preemphasis_lane0_xe9=0xc2f0 +serdes_preemphasis_lane1_xe9=0xc6e0 +serdes_preemphasis_lane2_xe9=0xbf00 +serdes_preemphasis_lane3_xe9=0xc2f0 + +# xe10 (40G) +portmap_11=17:40 +xgxs_rx_lane_map_11=0x213 +xgxs_tx_lane_map_11=0x132 +phy_xaui_rx_polarity_flip_11=0xe +phy_xaui_tx_polarity_flip_11=0x0 +serdes_driver_current_lane0_xe10=0x2 +serdes_driver_current_lane1_xe10=0x2 +serdes_driver_current_lane2_xe10=0x2 +serdes_driver_current_lane3_xe10=0x2 +serdes_pre_driver_current_lane0_xe10=0x2 +serdes_pre_driver_current_lane1_xe10=0x2 +serdes_pre_driver_current_lane2_xe10=0x2 +serdes_pre_driver_current_lane3_xe10=0x2 +serdes_preemphasis_lane0_xe10=0xb330 +serdes_preemphasis_lane1_xe10=0xbb10 +serdes_preemphasis_lane2_xe10=0xbb10 +serdes_preemphasis_lane3_xe10=0xbb10 + +# xe11 (40G) +portmap_12=21:40 +xgxs_rx_lane_map_12=0x123 +xgxs_tx_lane_map_12=0x1203 +phy_xaui_rx_polarity_flip_12=0xc +phy_xaui_tx_polarity_flip_12=0xe +serdes_driver_current_lane0_xe11=0x2 +serdes_driver_current_lane1_xe11=0x2 +serdes_driver_current_lane2_xe11=0x2 +serdes_driver_current_lane3_xe11=0x2 +serdes_pre_driver_current_lane0_xe11=0x2 +serdes_pre_driver_current_lane1_xe11=0x2 +serdes_pre_driver_current_lane2_xe11=0x2 +serdes_pre_driver_current_lane3_xe11=0x2 +serdes_preemphasis_lane0_xe11=0xb330 +serdes_preemphasis_lane1_xe11=0xb330 +serdes_preemphasis_lane2_xe11=0xb330 +serdes_preemphasis_lane3_xe11=0xb330 + +# xe12 (40G) +portmap_13=53:40 +xgxs_rx_lane_map_13=0x213 +xgxs_tx_lane_map_13=0x231 +phy_xaui_rx_polarity_flip_13=0x1 +phy_xaui_tx_polarity_flip_13=0x0 +serdes_driver_current_lane0_xe12=0x2 +serdes_driver_current_lane1_xe12=0x2 +serdes_driver_current_lane2_xe12=0x2 +serdes_driver_current_lane3_xe12=0x2 +serdes_pre_driver_current_lane0_xe12=0x2 +serdes_pre_driver_current_lane1_xe12=0x2 +serdes_pre_driver_current_lane2_xe12=0x2 +serdes_pre_driver_current_lane3_xe12=0x2 +serdes_preemphasis_lane0_xe12=0xaf40 +serdes_preemphasis_lane1_xe12=0xaf40 +serdes_preemphasis_lane2_xe12=0xaf40 +serdes_preemphasis_lane3_xe12=0xaf40 + +# xe13 (40G) +portmap_14=49:40 +xgxs_rx_lane_map_14=0x1302 +xgxs_tx_lane_map_14=0x2031 +phy_xaui_rx_polarity_flip_14=0xb +phy_xaui_tx_polarity_flip_14=0x3 +serdes_driver_current_lane0_xe13=0x2 +serdes_driver_current_lane1_xe13=0x2 +serdes_driver_current_lane2_xe13=0x2 +serdes_driver_current_lane3_xe13=0x2 +serdes_pre_driver_current_lane0_xe13=0x2 +serdes_pre_driver_current_lane1_xe13=0x2 +serdes_pre_driver_current_lane2_xe13=0x2 +serdes_pre_driver_current_lane3_xe13=0x2 +serdes_preemphasis_lane0_xe13=0xa760 +serdes_preemphasis_lane1_xe13=0xa760 +serdes_preemphasis_lane2_xe13=0xa760 +serdes_preemphasis_lane3_xe13=0xa760 + +# xe14 (40G) +portmap_15=57:40 +xgxs_rx_lane_map_15=0x213 +xgxs_tx_lane_map_15=0x2031 +phy_xaui_rx_polarity_flip_15=0x1 +phy_xaui_tx_polarity_flip_15=0x0 +serdes_driver_current_lane0_xe14=0x1 +serdes_driver_current_lane1_xe14=0x1 +serdes_driver_current_lane2_xe14=0x1 +serdes_driver_current_lane3_xe14=0x1 +serdes_pre_driver_current_lane0_xe14=0x1 +serdes_pre_driver_current_lane1_xe14=0x1 +serdes_pre_driver_current_lane2_xe14=0x1 +serdes_pre_driver_current_lane3_xe14=0x1 +serdes_preemphasis_lane0_xe14=0xa760 +serdes_preemphasis_lane1_xe14=0xa760 +serdes_preemphasis_lane2_xe14=0xa760 +serdes_preemphasis_lane3_xe14=0xa760 + +# xe15 (40G) +portmap_16=61:40 +xgxs_rx_lane_map_16=0x132 +xgxs_tx_lane_map_16=0x213 +phy_xaui_rx_polarity_flip_16=0x0 +phy_xaui_tx_polarity_flip_16=0x0 +serdes_driver_current_lane0_xe15=0x2 +serdes_driver_current_lane1_xe15=0x2 +serdes_driver_current_lane2_xe15=0x2 +serdes_driver_current_lane3_xe15=0x2 +serdes_pre_driver_current_lane0_xe15=0x2 +serdes_pre_driver_current_lane1_xe15=0x2 +serdes_pre_driver_current_lane2_xe15=0x2 +serdes_pre_driver_current_lane3_xe15=0x2 +serdes_preemphasis_lane0_xe15=0xa760 +serdes_preemphasis_lane1_xe15=0xa760 +serdes_preemphasis_lane2_xe15=0xa760 +serdes_preemphasis_lane3_xe15=0xa760 + +# xe16 (40G) +portmap_17=69:40 +xgxs_rx_lane_map_17=0x213 +xgxs_tx_lane_map_17=0x2130 +phy_xaui_rx_polarity_flip_17=0x1 +phy_xaui_tx_polarity_flip_17=0xf +serdes_driver_current_lane0_xe16=0x1 +serdes_driver_current_lane1_xe16=0x1 +serdes_driver_current_lane2_xe16=0x1 +serdes_driver_current_lane3_xe16=0x1 +serdes_pre_driver_current_lane0_xe16=0x1 +serdes_pre_driver_current_lane1_xe16=0x1 +serdes_pre_driver_current_lane2_xe16=0x1 +serdes_pre_driver_current_lane3_xe16=0x1 +serdes_preemphasis_lane0_xe16=0xa760 +serdes_preemphasis_lane1_xe16=0xa760 +serdes_preemphasis_lane2_xe16=0xa760 +serdes_preemphasis_lane3_xe16=0xa760 + +# xe17 (40G) +portmap_18=65:40 +xgxs_rx_lane_map_18=0x132 +xgxs_tx_lane_map_18=0x2031 +phy_xaui_rx_polarity_flip_18=0x3 +phy_xaui_tx_polarity_flip_18=0x9 +serdes_driver_current_lane0_xe17=0x1 +serdes_driver_current_lane1_xe17=0x1 +serdes_driver_current_lane2_xe17=0x1 +serdes_driver_current_lane3_xe17=0x1 +serdes_pre_driver_current_lane0_xe17=0x1 +serdes_pre_driver_current_lane1_xe17=0x1 +serdes_pre_driver_current_lane2_xe17=0x1 +serdes_pre_driver_current_lane3_xe17=0x1 +serdes_preemphasis_lane0_xe17=0xa370 +serdes_preemphasis_lane1_xe17=0xa370 +serdes_preemphasis_lane2_xe17=0xa370 +serdes_preemphasis_lane3_xe17=0xa370 + +# xe18 (40G) +portmap_19=73:40 +xgxs_rx_lane_map_19=0x213 +xgxs_tx_lane_map_19=0x2031 +phy_xaui_rx_polarity_flip_19=0x1 +phy_xaui_tx_polarity_flip_19=0x0 +serdes_driver_current_lane0_xe18=0x2 +serdes_driver_current_lane1_xe18=0x2 +serdes_driver_current_lane2_xe18=0x2 +serdes_driver_current_lane3_xe18=0x2 +serdes_pre_driver_current_lane0_xe18=0x2 +serdes_pre_driver_current_lane1_xe18=0x2 +serdes_pre_driver_current_lane2_xe18=0x2 +serdes_pre_driver_current_lane3_xe18=0x2 +serdes_preemphasis_lane0_xe18=0xa760 +serdes_preemphasis_lane1_xe18=0xa760 +serdes_preemphasis_lane2_xe18=0xa760 +serdes_preemphasis_lane3_xe18=0xa760 + +# xe19 (40G) +portmap_20=77:40 +xgxs_rx_lane_map_20=0x123 +xgxs_tx_lane_map_20=0x1203 +phy_xaui_rx_polarity_flip_20=0x3 +phy_xaui_tx_polarity_flip_20=0xe +serdes_driver_current_lane0_xe19=0x2 +serdes_driver_current_lane1_xe19=0x2 +serdes_driver_current_lane2_xe19=0x2 +serdes_driver_current_lane3_xe19=0x2 +serdes_pre_driver_current_lane0_xe19=0x2 +serdes_pre_driver_current_lane1_xe19=0x2 +serdes_pre_driver_current_lane2_xe19=0x2 +serdes_pre_driver_current_lane3_xe19=0x2 +serdes_preemphasis_lane0_xe19=0xaf40 +serdes_preemphasis_lane1_xe19=0xaf40 +serdes_preemphasis_lane2_xe19=0xaf40 +serdes_preemphasis_lane3_xe19=0xaf40 + +# xe20 (40G) +portmap_21=109:40 +xgxs_rx_lane_map_21=0x132 +xgxs_tx_lane_map_21=0x132 +phy_xaui_rx_polarity_flip_21=0x8 +phy_xaui_tx_polarity_flip_21=0x0 +serdes_driver_current_lane0_xe20=0x1 +serdes_driver_current_lane1_xe20=0x1 +serdes_driver_current_lane2_xe20=0x1 +serdes_driver_current_lane3_xe20=0x2 +serdes_pre_driver_current_lane0_xe20=0x1 +serdes_pre_driver_current_lane1_xe20=0x1 +serdes_pre_driver_current_lane2_xe20=0x1 +serdes_pre_driver_current_lane3_xe20=0x2 +serdes_preemphasis_lane0_xe20=0xb330 +serdes_preemphasis_lane1_xe20=0xb330 +serdes_preemphasis_lane2_xe20=0xb330 +serdes_preemphasis_lane3_xe20=0xbff0 + +# xe21 (40G) +portmap_22=105:40 +xgxs_rx_lane_map_22=0x1320 +xgxs_tx_lane_map_22=0x3021 +phy_xaui_rx_polarity_flip_22=0xd +phy_xaui_tx_polarity_flip_22=0xb +serdes_driver_current_lane0_xe21=0x1 +serdes_driver_current_lane1_xe21=0x1 +serdes_driver_current_lane2_xe21=0x1 +serdes_driver_current_lane3_xe21=0x1 +serdes_pre_driver_current_lane0_xe21=0x1 +serdes_pre_driver_current_lane1_xe21=0x1 +serdes_pre_driver_current_lane2_xe21=0x1 +serdes_pre_driver_current_lane3_xe21=0x1 +serdes_preemphasis_lane0_xe21=0xb330 +serdes_preemphasis_lane1_xe21=0xb330 +serdes_preemphasis_lane2_xe21=0xb330 +serdes_preemphasis_lane3_xe21=0xb330 + +# xe22 (40G) +portmap_23=113:40 +xgxs_rx_lane_map_23=0x132 +xgxs_tx_lane_map_23=0x132 +phy_xaui_rx_polarity_flip_23=0x8 +phy_xaui_tx_polarity_flip_23=0x0 +serdes_driver_current_lane0_xe22=0x1 +serdes_driver_current_lane1_xe22=0x1 +serdes_driver_current_lane2_xe22=0x1 +serdes_driver_current_lane3_xe22=0x1 +serdes_pre_driver_current_lane0_xe22=0x1 +serdes_pre_driver_current_lane1_xe22=0x1 +serdes_pre_driver_current_lane2_xe22=0x1 +serdes_pre_driver_current_lane3_xe22=0x1 +serdes_preemphasis_lane0_xe22=0xbb10 +serdes_preemphasis_lane1_xe22=0xbb10 +serdes_preemphasis_lane2_xe22=0xbb10 +serdes_preemphasis_lane3_xe22=0xc2f0 + +# xe23 (40G) +portmap_24=117:40 +xgxs_rx_lane_map_24=0x231 +xgxs_tx_lane_map_24=0x1203 +phy_xaui_rx_polarity_flip_24=0x3 +phy_xaui_tx_polarity_flip_24=0xe +serdes_driver_current_lane0_xe23=0x3 +serdes_driver_current_lane1_xe23=0x5 +serdes_driver_current_lane2_xe23=0x3 +serdes_driver_current_lane3_xe23=0x3 +serdes_pre_driver_current_lane0_xe23=0x3 +serdes_pre_driver_current_lane1_xe23=0x5 +serdes_pre_driver_current_lane2_xe23=0x3 +serdes_pre_driver_current_lane3_xe23=0x3 +serdes_preemphasis_lane0_xe23=0xc6e0 +serdes_preemphasis_lane1_xe23=0xc6e0 +serdes_preemphasis_lane2_xe23=0xc6e0 +serdes_preemphasis_lane3_xe23=0xc6e0 + +# xe24 (40G) +portmap_25=125:40 +xgxs_rx_lane_map_25=0x132 +xgxs_tx_lane_map_25=0x132 +phy_xaui_rx_polarity_flip_25=0x8 +phy_xaui_tx_polarity_flip_25=0x0 +serdes_driver_current_lane0_xe24=0x4 +serdes_driver_current_lane1_xe24=0x4 +serdes_driver_current_lane2_xe24=0x4 +serdes_driver_current_lane3_xe24=0x4 +serdes_pre_driver_current_lane0_xe24=0x4 +serdes_pre_driver_current_lane1_xe24=0x4 +serdes_pre_driver_current_lane2_xe24=0x4 +serdes_pre_driver_current_lane3_xe24=0x4 +serdes_preemphasis_lane0_xe24=0xc6e0 +serdes_preemphasis_lane1_xe24=0xc6e0 +serdes_preemphasis_lane2_xe24=0xc6e0 +serdes_preemphasis_lane3_xe24=0xcec0 + +# xe25 (40G) +portmap_26=121:40 +xgxs_rx_lane_map_26=0x1320 +xgxs_tx_lane_map_26=0x3021 +phy_xaui_rx_polarity_flip_26=0xd +phy_xaui_tx_polarity_flip_26=0xb +serdes_driver_current_lane0_xe25=0x4 +serdes_driver_current_lane1_xe25=0x4 +serdes_driver_current_lane2_xe25=0x4 +serdes_driver_current_lane3_xe25=0x4 +serdes_pre_driver_current_lane0_xe25=0x4 +serdes_pre_driver_current_lane1_xe25=0x4 +serdes_pre_driver_current_lane2_xe25=0x4 +serdes_pre_driver_current_lane3_xe25=0x4 +serdes_preemphasis_lane0_xe25=0xc6e0 +serdes_preemphasis_lane1_xe25=0xc6e0 +serdes_preemphasis_lane2_xe25=0xc6e0 +serdes_preemphasis_lane3_xe25=0xc6e0 + +# xe26 (40G) +portmap_27=81:40 +xgxs_rx_lane_map_27=0x1320 +xgxs_tx_lane_map_27=0x2031 +phy_xaui_rx_polarity_flip_27=0x1 +phy_xaui_tx_polarity_flip_27=0x2 +serdes_driver_current_lane0_xe26=0x2 +serdes_driver_current_lane1_xe26=0x2 +serdes_driver_current_lane2_xe26=0x2 +serdes_driver_current_lane3_xe26=0x2 +serdes_pre_driver_current_lane0_xe26=0x2 +serdes_pre_driver_current_lane1_xe26=0x2 +serdes_pre_driver_current_lane2_xe26=0x2 +serdes_pre_driver_current_lane3_xe26=0x2 +serdes_preemphasis_lane0_xe26=0xbb10 +serdes_preemphasis_lane1_xe26=0xbb10 +serdes_preemphasis_lane2_xe26=0xbf00 +serdes_preemphasis_lane3_xe26=0xbb10 + +# xe27 (40G) +portmap_28=85:40 +xgxs_rx_lane_map_28=0x213 +xgxs_tx_lane_map_28=0x1203 +phy_xaui_rx_polarity_flip_28=0xc +phy_xaui_tx_polarity_flip_28=0xe +serdes_driver_current_lane0_xe27=0x4 +serdes_driver_current_lane1_xe27=0x5 +serdes_driver_current_lane2_xe27=0x4 +serdes_driver_current_lane3_xe27=0x5 +serdes_pre_driver_current_lane0_xe27=0x4 +serdes_pre_driver_current_lane1_xe27=0x5 +serdes_pre_driver_current_lane2_xe27=0x4 +serdes_pre_driver_current_lane3_xe27=0x5 +serdes_preemphasis_lane0_xe27=0xc2f0 +serdes_preemphasis_lane1_xe27=0xc6e0 +serdes_preemphasis_lane2_xe27=0xc6e0 +serdes_preemphasis_lane3_xe27=0xc6e0 + +# xe28 (40G) +portmap_29=93:40 +xgxs_rx_lane_map_29=0x1320 +xgxs_tx_lane_map_29=0x2031 +phy_xaui_rx_polarity_flip_29=0x1 +phy_xaui_tx_polarity_flip_29=0x2 +serdes_driver_current_lane0_xe28=0x4 +serdes_driver_current_lane1_xe28=0x4 +serdes_driver_current_lane2_xe28=0x4 +serdes_driver_current_lane3_xe28=0x4 +serdes_pre_driver_current_lane0_xe28=0x4 +serdes_pre_driver_current_lane1_xe28=0x4 +serdes_pre_driver_current_lane2_xe28=0x4 +serdes_pre_driver_current_lane3_xe28=0x4 +serdes_preemphasis_lane0_xe28=0xc2f0 +serdes_preemphasis_lane1_xe28=0xc2f0 +serdes_preemphasis_lane2_xe28=0xc2f0 +serdes_preemphasis_lane3_xe28=0xc2f0 + +# xe29 (40G) +portmap_30=89:40 +xgxs_rx_lane_map_30=0x1320 +xgxs_tx_lane_map_30=0x3021 +phy_xaui_rx_polarity_flip_30=0x2 +phy_xaui_tx_polarity_flip_30=0xb +serdes_driver_current_lane0_xe29=0x4 +serdes_driver_current_lane1_xe29=0x4 +serdes_driver_current_lane2_xe29=0x4 +serdes_driver_current_lane3_xe29=0x4 +serdes_pre_driver_current_lane0_xe29=0x4 +serdes_pre_driver_current_lane1_xe29=0x4 +serdes_pre_driver_current_lane2_xe29=0x4 +serdes_pre_driver_current_lane3_xe29=0x4 +serdes_preemphasis_lane0_xe29=0xcad0 +serdes_preemphasis_lane1_xe29=0xc6e0 +serdes_preemphasis_lane2_xe29=0xc6e0 +serdes_preemphasis_lane3_xe29=0xc6e0 + +# xe30 (40G) +portmap_31=101:40 +xgxs_rx_lane_map_31=0x1320 +xgxs_tx_lane_map_31=0x1203 +phy_xaui_rx_polarity_flip_31=0x1 +phy_xaui_tx_polarity_flip_31=0x6 +serdes_driver_current_lane0_xe30=0x6 +serdes_driver_current_lane1_xe30=0x6 +serdes_driver_current_lane2_xe30=0x6 +serdes_driver_current_lane3_xe30=0x7 +serdes_pre_driver_current_lane0_xe30=0x6 +serdes_pre_driver_current_lane1_xe30=0x6 +serdes_pre_driver_current_lane2_xe30=0x6 +serdes_pre_driver_current_lane3_xe30=0x7 +serdes_preemphasis_lane0_xe30=0xcec0 +serdes_preemphasis_lane1_xe30=0xcec0 +serdes_preemphasis_lane2_xe30=0xcad0 +serdes_preemphasis_lane3_xe30=0xc6e0 + +# xe31 (40G) +portmap_32=97:40 +xgxs_rx_lane_map_32=0x213 +xgxs_tx_lane_map_32=0x2031 +phy_xaui_rx_polarity_flip_32=0xc +phy_xaui_tx_polarity_flip_32=0x3 +serdes_driver_current_lane0_xe31=0x5 +serdes_driver_current_lane1_xe31=0x5 +serdes_driver_current_lane2_xe31=0x5 +serdes_driver_current_lane3_xe31=0x5 +serdes_pre_driver_current_lane0_xe31=0x5 +serdes_pre_driver_current_lane1_xe31=0x5 +serdes_pre_driver_current_lane2_xe31=0x5 +serdes_pre_driver_current_lane3_xe31=0x5 +serdes_preemphasis_lane0_xe31=0xcad0 +serdes_preemphasis_lane1_xe31=0xcad0 +serdes_preemphasis_lane2_xe31=0xcad0 +serdes_preemphasis_lane3_xe31=0xcad0 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/topology.sh b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/topology.sh new file mode 100755 index 000000000000..378f794190d4 --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/topology.sh @@ -0,0 +1,81 @@ +#!/bin/bash +#topolgy script for 6 ASIC PLATFORM +FIRST_FRONTEND_ASIC=0 +LAST_FRONTEND_ASIC=3 +FIRST_BACKEND_ASIC=4 +LAST_BACKEND_ASIC=5 +NUM_INTERFACES_PER_ASIC=32 + +start () { + # Move external links into assigned frontend namespaces + # eth0 - eth15: asic2 + # eth16 - eth31: asic3 + # eth32 - eth47: asic4 + # eth48 - eth63: asic5 + for ASIC in `seq $FIRST_FRONTEND_ASIC $LAST_FRONTEND_ASIC`; do + for NUM in `seq 1 16`; do + ORIG="eth$((16 * $ASIC + $NUM - 1))" + TEMP="ethTemp999" + NEW="eth$(($NUM + 16))" + ip link set dev $ORIG down + ip link set dev $ORIG name $TEMP # rename to prevent conflicts before renaming in new namespace + ip link set dev $TEMP netns asic$ASIC + sudo ip netns exec asic$ASIC ip link set $TEMP name $NEW # rename to final interface name + sudo ip netns exec asic$ASIC ip link set $NEW up + done + done + + # Connect all backend namespaces to frontend namespaces + for BACKEND in `seq $FIRST_BACKEND_ASIC $LAST_BACKEND_ASIC`; do + for FRONTEND in `seq $FIRST_FRONTEND_ASIC $LAST_FRONTEND_ASIC`; do + for LINK in `seq 1 8`; do + BACK_NAME="eth$((8 * $FRONTEND + $LINK))" + FRONT_NAME="eth$((8 * $(($LAST_BACKEND_ASIC - $BACKEND)) + $LINK))" + TEMP_BACK="ethBack999" + TEMP_FRONT="ethFront999" + + ip link add $TEMP_BACK type veth peer name $TEMP_FRONT # temporary name to prevent conflicts between interfaces + ip link set dev $TEMP_BACK netns asic$BACKEND + ip link set dev $TEMP_FRONT netns asic$FRONTEND + + sudo ip netns exec asic$BACKEND ip link set $TEMP_BACK name $BACK_NAME + sudo ip netns exec asic$FRONTEND ip link set $TEMP_FRONT name $FRONT_NAME + + sudo ip netns exec asic$BACKEND ip link set $BACK_NAME up + sudo ip netns exec asic$FRONTEND ip link set $FRONT_NAME up + done + done + done +} + +stop() { + for ASIC in `seq $FIRST_FRONTEND_ASIC $LAST_FRONTEND_ASIC`; do + for NUM in `seq 1 16`; do + TEMP="eth999" + OLD="eth$(($NUM + 16))" + NAME="eth$((16 * $ASIC + $NUM - 1))" + sudo ip netns exec asic$ASIC ip link set dev $OLD down + sudo ip netns exec asic$ASIC ip link set dev $OLD name $TEMP + sudo ip netns exec asic$ASIC ip link set dev $TEMP netns 1 + ip link set dev $TEMP name $NAME + ip link set dev $NAME up + done + done + + for ASIC in `seq $FIRST_BACKEND_ASIC $LAST_BACKEND_ASIC`; do + for NUM in `seq 1 $NUM_INTERFACES_PER_ASIC`; do + sudo ip netns exec asic$ASIC ip link set dev eth$NUM down + sudo ip netns exec asic$ASIC ip link delete dev eth$NUM + done + done +} + +case "$1" in + start|stop) + $1 + ;; + *) + echo "Usage: $0 {start|stop}" + ;; +esac + diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 167a392730e4..a9201b8a346d 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -1,5 +1,31 @@ #!/bin/bash +# single instance containers are still supported (even though it might not look like it) +# if no instance number is passed to this script, $DEV will simply be unset, resulting in docker +# commands being sent to the base container name. E.g. `docker start database$DEV` simply starts +# the container `database` if no instance number is passed since `$DEV` is not defined + + +{%- if docker_container_name == "database" %} +link_namespace() { + # Makes namespace of a docker container available in + # /var/run/netns so it can be managed with iproute2 + + mkdir -p /var/run/netns + PID="$(docker inspect -f {{"'{{.State.Pid}}'"}} "{{docker_container_name}}$DEV")" + + if `ip netns | grep --quiet -w "{{docker_container_name}}$DEV"`; then # namespace exists + if [ $(readlink -f /var/run/netns/$NET_NS$DEV) = $(readlink -f /proc/$PID/ns/net) ]; then # namespace is correctly linked + return 0 + else # if it's incorrectly linked remove it + ip netns delete "{{docker_container_name}}$DEV" + fi + fi + + ln -s /proc/$PID/ns/net /var/run/netns/$NET_NS$DEV +} +{%- endif %} + function getMountPoint() { echo $1 | python -c "import sys, json, os; mnts = [x for x in json.load(sys.stdin)[0]['Mounts'] if x['Destination'] == '/usr/share/sonic/hwsku']; print '' if len(mnts) == 0 else os.path.basename(mnts[0]['Source'])" 2>/dev/null @@ -10,7 +36,7 @@ function updateHostName() HOSTS=/etc/hosts HOSTS_TMP=/etc/hosts.tmp - EXEC="docker exec -i {{docker_container_name}} bash -c" + EXEC="docker exec -i {{docker_container_name}}$DEV bash -c" NEW_HOSTNAME="$1" HOSTNAME=`$EXEC "hostname"` @@ -25,7 +51,7 @@ function updateHostName() # add entry with new hostname $EXEC "echo -e \"127.0.0.1\t$NEW_HOSTNAME\" >> $HOSTS_TMP" - echo "Set hostname in {{docker_container_name}} container" + echo "Set hostname in {{docker_container_name}}$DEV container" $EXEC "hostname '$NEW_HOSTNAME'" $EXEC "cat $HOSTS_TMP > $HOSTS" $EXEC "rm -f $HOSTS_TMP" @@ -139,6 +165,9 @@ function preStartAction() function postStartAction() { {%- if docker_container_name == "database" %} + if [ "$DEV" ]; then + link_namespace $DEV + fi # Wait until redis starts /usr/bin/docker exec database ping_pong_db_insts if [[ ("$BOOT_TYPE" == "warm" || "$BOOT_TYPE" == "fastfast") && -f $WARM_DIR/dump.rdb ]]; then @@ -205,7 +234,7 @@ start() { HOSTNAME=`hostname` fi - DOCKERCHECK=`docker inspect --type container {{docker_container_name}} 2>/dev/null` + DOCKERCHECK=`docker inspect --type container {{docker_container_name}}$DEV 2>/dev/null` if [ "$?" -eq "0" ]; then {%- if docker_container_name == "database" %} DOCKERMOUNT="" @@ -214,39 +243,52 @@ start() { {%- endif %} if [ x"$DOCKERMOUNT" == x"$HWSKU" ]; then {%- if docker_container_name == "database" %} - echo "Starting existing {{docker_container_name}} container" + echo "Starting existing {{docker_container_name}}$DEV container" {%- else %} - echo "Starting existing {{docker_container_name}} container with HWSKU $HWSKU" + echo "Starting existing {{docker_container_name}}$DEV container with HWSKU $HWSKU" {%- endif %} preStartAction - docker start {{docker_container_name}} - CURRENT_HOSTNAME="$(docker exec {{docker_container_name}} hostname)" + docker start {{docker_container_name}}$DEV + postStartAction + CURRENT_HOSTNAME="$(docker exec {{docker_container_name}}$DEV hostname)" if [ x"$HOSTNAME" != x"$CURRENT_HOSTNAME" ]; then updateHostName "$HOSTNAME" fi - postStartAction + updateHostName "$HOSTNAME" exit $? fi # docker created with a different HWSKU, remove and recreate - echo "Removing obsolete {{docker_container_name}} container with HWSKU $DOCKERMOUNT" - docker rm -f {{docker_container_name}} + echo "Removing obsolete {{docker_container_name}}$DEV container with HWSKU $DOCKERMOUNT" + docker rm -f {{docker_container_name}}$DEV fi -{%- if docker_container_name == "database" %} - echo "Creating new {{docker_container_name}} container" + {%- if docker_container_name == "database" %} + echo "Creating new {{docker_container_name}}$DEV container" # if database_config exists in old_config, use it; otherwise use the default one in new image if [ -f /etc/sonic/old_config/database_config.json ]; then echo "Use database_config.json from old system..." mv /etc/sonic/old_config/database_config.json /etc/sonic/ fi -{%- else %} - echo "Creating new {{docker_container_name}} container with HWSKU $HWSKU" -{%- endif %} + {%- else %} + echo "Creating new {{docker_container_name}}$DEV container with HWSKU $HWSKU" + {%- endif %} + + if [ -z "$DEV" ]; then + NET="host" + else + {%- if docker_container_name == "database" %} + NET="bridge" + {%- else %} + NET="container:database$DEV" + {%- endif %} + fi + {%- if sonic_asic_platform == "mellanox" %} # TODO: Mellanox will remove the --tmpfs exception after SDK socket path changed in new SDK version {%- endif %} docker create {{docker_image_run_opt}} \ + --net=$NET \ {%- if install_debug_image == "y" %} -v /src:/src:ro -v /debug:/debug:rw \ {%- endif %} @@ -275,8 +317,7 @@ start() { --tmpfs /tmp \ {%- endif %} --tmpfs /var/tmp \ - --hostname "$HOSTNAME" \ - --name={{docker_container_name}} {{docker_image_name}}:latest || { + --name={{docker_container_name}}$DEV {{docker_image_name}}:latest || { echo "Failed to docker run" >&1 exit 4 } @@ -284,24 +325,35 @@ start() { preStartAction docker start {{docker_container_name}} postStartAction + updateHostName "$HOSTNAME" } wait() { - docker wait {{docker_container_name}} + docker wait {{docker_container_name}}$DEV } stop() { - docker stop {{docker_container_name}} + docker stop {{docker_container_name}}$DEV +{%- if docker_container_name == "database" %} + ip netns delete "$NET_NS$DEV" +{%- endif %} } +OP=$1 +DEV=$2 # namespace/device number to operate on +NET_NS="asic" #name of the network namespace + case "$1" in - start|wait|stop|updateHostName) + start|wait|stop) + $1 + ;; + updateHostName) cmd=$1 - shift + shift 2 $cmd $@ ;; *) - echo "Usage: $0 {start|wait|stop|updateHostName new_hostname}" + echo "Usage: $0 {start namespace(optional)|wait namespace(optional)|stop namespace(optional)|updateHostName namespace(optional) new_hostname}" exit 1 ;; esac diff --git a/files/build_templates/bgp.service.j2 b/files/build_templates/single_instance/bgp.service.j2 similarity index 100% rename from files/build_templates/bgp.service.j2 rename to files/build_templates/single_instance/bgp.service.j2 diff --git a/files/build_templates/database.service.j2 b/files/build_templates/single_instance/database.service.j2 similarity index 100% rename from files/build_templates/database.service.j2 rename to files/build_templates/single_instance/database.service.j2 diff --git a/files/build_templates/swss.service.j2 b/files/build_templates/single_instance/swss.service.j2 similarity index 100% rename from files/build_templates/swss.service.j2 rename to files/build_templates/single_instance/swss.service.j2 diff --git a/files/build_templates/syncd.service.j2 b/files/build_templates/single_instance/syncd.service.j2 similarity index 100% rename from files/build_templates/syncd.service.j2 rename to files/build_templates/single_instance/syncd.service.j2 diff --git a/files/build_templates/teamd.service.j2 b/files/build_templates/single_instance/teamd.service.j2 similarity index 100% rename from files/build_templates/teamd.service.j2 rename to files/build_templates/single_instance/teamd.service.j2 diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index a30cc3db9207..4f9c333873ee 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -247,6 +247,13 @@ sudo cp $IMAGE_CONFIGS/hostname/hostname-config.sh $FILESYSTEM_ROOT/usr/bin/ # Copy miscellaneous scripts sudo cp $IMAGE_CONFIGS/misc/docker-wait-any $FILESYSTEM_ROOT/usr/bin/ +# Copy internal topology configuration scripts +{%- if sonic_asic_platform == "vs" %} +sudo cp $IMAGE_CONFIGS/topology/topology.service $FILESYSTEM_ROOT/etc/systemd/system/ +echo "topology.service" | sudo tee -a $GENERATED_SERVICE_FILE +sudo cp $IMAGE_CONFIGS/topology/topology.sh $FILESYSTEM_ROOT/usr/bin +{%- endif %} + # Copy updategraph script and service file j2 files/build_templates/updategraph.service.j2 | sudo tee $FILESYSTEM_ROOT/etc/systemd/system/updategraph.service sudo cp $IMAGE_CONFIGS/updategraph/updategraph $FILESYSTEM_ROOT/usr/bin/ @@ -395,6 +402,13 @@ sudo cp {{script}} $FILESYSTEM_ROOT/usr/bin/ {% for service in installer_services.split(' ') -%} if [ -f {{service}} ]; then sudo cp {{service}} $FILESYSTEM_ROOT/etc/systemd/system/ + + {% if "@" in service %} + MULTI_INSTANCE="{{service}}" + SINGLE_INSTANCE=${MULTI_INSTANCE/"@"} + sudo cp $SINGLE_INSTANCE $FILESYSTEM_ROOT/etc/systemd/system/ + {% endif %} + echo "{{service}}" | sudo tee -a $GENERATED_SERVICE_FILE fi {% endfor %} diff --git a/files/image_config/topology/topology.service b/files/image_config/topology/topology.service new file mode 100644 index 000000000000..eea4bf65230a --- /dev/null +++ b/files/image_config/topology/topology.service @@ -0,0 +1,16 @@ +[Unit] +Description=Internal topology service +Requires=database.service +After=database.service +PartOf=database.service + +[Service] +Type=oneshot +User=root +RemainAfterExit=yes +ExecStart=/usr/bin/topology.sh start +ExecStop=/usr/bin/topology.sh stop + +[Install] +WantedBy=multi-user.target + diff --git a/files/image_config/topology/topology.sh b/files/image_config/topology/topology.sh new file mode 100755 index 000000000000..7013920ec016 --- /dev/null +++ b/files/image_config/topology/topology.sh @@ -0,0 +1,30 @@ +#!/bin/bash +# This script is invoked by topology.service only +# for multi-asic virtual platform. For multi-asic platform +# multiple Database instances are present +# and HWKSU information is retrieved from first database instance. +# + +start() { + DB_FIRST_INSTANCE="/var/run/redis0/redis.sock" + TOPOLOGY_SCRIPT="topology.sh" + PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform -s $DB_FIRST_INSTANCE` + HWSKU=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hwsku"]' -s $DB_FIRST_INSTANCE` + /usr/share/sonic/device/$PLATFORM/$HWSKU/$TOPOLOGY_SCRIPT start +} +stop() { + DB_FIRST_INSTANCE="/var/run/redis0/redis.sock" + TOPOLOGY_SCRIPT="topology.sh" + PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform -s $DB_FIRST_INSTANCE` + HWSKU=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hwsku"]' -s $DB_FIRST_INSTANCE` + /usr/share/sonic/device/$PLATFORM/$HWSKU/$TOPOLOGY_SCRIPT stop +} + +case "$1" in + start|stop) + $1 + ;; + *) + echo "Usage: $0 {start|stop}" + ;; +esac diff --git a/platform/template/docker-syncd-base.mk b/platform/template/docker-syncd-base.mk index cefcf15ebd62..d0407beee8a0 100644 --- a/platform/template/docker-syncd-base.mk +++ b/platform/template/docker-syncd-base.mk @@ -29,7 +29,7 @@ endif $(DOCKER_SYNCD_BASE)_CONTAINER_NAME = syncd -$(DOCKER_SYNCD_BASE)_RUN_OPT += --net=host --privileged -t +$(DOCKER_SYNCD_BASE)_RUN_OPT += --privileged -t $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf $(DOCKER_SYNCD_BASE)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro diff --git a/platform/vs/README.vsvm.md b/platform/vs/README.vsvm.md index d627859578b4..68f7d0244017 100644 --- a/platform/vs/README.vsvm.md +++ b/platform/vs/README.vsvm.md @@ -6,10 +6,10 @@ HOWTO Use Virtual Switch (VM) sudo apt-get install libvirt-clients qemu-kvm libvirt-bin ``` -2. Create SONiC VM +2. Create SONiC VM for single ASIC HWSKU ``` -$ virsh +$ sudo virsh Welcome to virsh, the virtualization interactive terminal. Type: 'help' for help with commands @@ -22,14 +22,54 @@ Domain sonic created from sonic.xml virsh # ``` -2. Connect SONiC VM via console +2. Create SONiC VM for multi-ASIC HWSKU +Update sonic_multiasic.xml with the external interfaces +required for HWSKU. ``` -$ telnet 127.0.0.1 7000 -``` +$ sudo virsh +Welcome to virsh, the virtualization interactive terminal. -3. Connect SONiC VM via SSH +Type: 'help' for help with commands + 'quit' to quit -``` -$ ssh -p 3040 admin@127.0.0.1 -``` +virsh # +virsh # create sonic_multiasic.xml +Domain sonic created from sonic.xml + +virsh # + +Once booted up, create a file "asic.conf" with the content: +NUM_ASIC= +under /usr/share/sonic/device/x86_64-kvm_x86_64-r0/ +Also, create a "topology.sh" file which will simulate the internal +asic connectivity of the hardware under +/usr/share/sonic/device/x86_64-kvm_x86_64-r0/ +The HWSKU directory will have the required files like port_config.ini +for each ASIC. + +Having done this, a new service "topology.service" will be started +during bootup which will invoke topology.sh script. + +3. Access virtual switch: + + 1. Connect SONiC VM via console + ``` + $ telnet 127.0.0.1 7000 + ``` + + OR + + 2. Connect SONiC VM via SSH + + 1. Connect via console (see 3.1 above) + + 2. Request a new DHCP address + ``` + sudo dhclient -v + ``` + + 3. Connect via SSH + ``` + $ ssh -p 3040 admin@127.0.0.1 + ``` diff --git a/platform/vs/sonic_multiasic.xml b/platform/vs/sonic_multiasic.xml new file mode 100644 index 000000000000..b406bfd40475 --- /dev/null +++ b/platform/vs/sonic_multiasic.xml @@ -0,0 +1,110 @@ + + sonic + 8 + 2 + + /machine + + + hvm + + + + + + + + destroy + restart + restart + + /usr/bin/qemu-system-x86_64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + diff --git a/rules/docker-database.mk b/rules/docker-database.mk index 9ad6b0b36b45..91fd06819a4b 100644 --- a/rules/docker-database.mk +++ b/rules/docker-database.mk @@ -23,7 +23,7 @@ SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_DATABASE_DBG) SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_DATABASE_DBG) $(DOCKER_DATABASE)_CONTAINER_NAME = database -$(DOCKER_DATABASE)_RUN_OPT += --net=host --privileged -t +$(DOCKER_DATABASE)_RUN_OPT += --privileged -t $(DOCKER_DATABASE)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_DATABASE)_BASE_IMAGE_FILES += redis-cli:/usr/bin/redis-cli diff --git a/rules/docker-dhcp-relay.mk b/rules/docker-dhcp-relay.mk index 8deb6ebbfad7..4c044d5e05a0 100644 --- a/rules/docker-dhcp-relay.mk +++ b/rules/docker-dhcp-relay.mk @@ -23,6 +23,6 @@ SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_DHCP_RELAY_DBG) SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_DHCP_RELAY_DBG) $(DOCKER_DHCP_RELAY)_CONTAINER_NAME = dhcp_relay -$(DOCKER_DHCP_RELAY)_RUN_OPT += --net=host --privileged -t +$(DOCKER_DHCP_RELAY)_RUN_OPT += --privileged -t $(DOCKER_DHCP_RELAY)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_DHCP_RELAY)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/docker-fpm-frr.mk b/rules/docker-fpm-frr.mk index e833d360bec2..1d918830ab55 100644 --- a/rules/docker-fpm-frr.mk +++ b/rules/docker-fpm-frr.mk @@ -22,7 +22,7 @@ SONIC_DOCKER_DBG_IMAGES += $(DOCKER_FPM_FRR_DBG) SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_FPM_FRR_DBG) $(DOCKER_FPM_FRR)_CONTAINER_NAME = bgp -$(DOCKER_FPM_FRR)_RUN_OPT += --net=host --privileged -t +$(DOCKER_FPM_FRR)_RUN_OPT += --privileged -t $(DOCKER_FPM_FRR)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_FPM_FRR)_RUN_OPT += -v /etc/sonic/frr:/etc/frr:rw diff --git a/rules/docker-fpm-gobgp.mk b/rules/docker-fpm-gobgp.mk index 12fa37dc1d97..3e1839d47099 100644 --- a/rules/docker-fpm-gobgp.mk +++ b/rules/docker-fpm-gobgp.mk @@ -7,5 +7,5 @@ $(DOCKER_FPM_GOBGP)_LOAD_DOCKERS += $(DOCKER_FPM_QUAGGA) SONIC_DOCKER_IMAGES += $(DOCKER_FPM_GOBGP) $(DOCKER_FPM_GOBGP)_CONTAINER_NAME = bgp -$(DOCKER_FPM_GOBGP)_RUN_OPT += --net=host --privileged -t +$(DOCKER_FPM_GOBGP)_RUN_OPT += --privileged -t $(DOCKER_FPM_GOBGP)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro diff --git a/rules/docker-fpm-quagga.mk b/rules/docker-fpm-quagga.mk index a9c0511ba173..2c78d1917b0e 100644 --- a/rules/docker-fpm-quagga.mk +++ b/rules/docker-fpm-quagga.mk @@ -7,7 +7,7 @@ $(DOCKER_FPM_QUAGGA)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE) SONIC_DOCKER_IMAGES += $(DOCKER_FPM_QUAGGA) $(DOCKER_FPM_QUAGGA)_CONTAINER_NAME = bgp -$(DOCKER_FPM_QUAGGA)_RUN_OPT += --net=host --privileged -t +$(DOCKER_FPM_QUAGGA)_RUN_OPT += --privileged -t $(DOCKER_FPM_QUAGGA)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_FPM_QUAGGA)_BASE_IMAGE_FILES += vtysh:/usr/bin/vtysh diff --git a/rules/docker-lldp-sv2.mk b/rules/docker-lldp-sv2.mk index 8224239c1ced..a39b307d5063 100644 --- a/rules/docker-lldp-sv2.mk +++ b/rules/docker-lldp-sv2.mk @@ -25,7 +25,7 @@ SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_LLDP_SV2_DBG) SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_LLDP_SV2_DBG) $(DOCKER_LLDP_SV2)_CONTAINER_NAME = lldp -$(DOCKER_LLDP_SV2)_RUN_OPT += --net=host --privileged -t +$(DOCKER_LLDP_SV2)_RUN_OPT += --privileged -t $(DOCKER_LLDP_SV2)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_LLDP_SV2)_BASE_IMAGE_FILES += lldpctl:/usr/bin/lldpctl diff --git a/rules/docker-orchagent.mk b/rules/docker-orchagent.mk index 0244138cbfe2..bab1a3a29920 100644 --- a/rules/docker-orchagent.mk +++ b/rules/docker-orchagent.mk @@ -26,7 +26,7 @@ SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_ORCHAGENT_DBG) SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_ORCHAGENT_DBG) $(DOCKER_ORCHAGENT)_CONTAINER_NAME = swss -$(DOCKER_ORCHAGENT)_RUN_OPT += --net=host --privileged -t +$(DOCKER_ORCHAGENT)_RUN_OPT += --privileged -t $(DOCKER_ORCHAGENT)_RUN_OPT += -v /etc/network/interfaces:/etc/network/interfaces:ro $(DOCKER_ORCHAGENT)_RUN_OPT += -v /etc/network/interfaces.d/:/etc/network/interfaces.d/:ro $(DOCKER_ORCHAGENT)_RUN_OPT += -v /host/machine.conf:/host/machine.conf:ro diff --git a/rules/docker-platform-monitor.mk b/rules/docker-platform-monitor.mk index 7a319e4bf120..a37f4d2e9ee7 100644 --- a/rules/docker-platform-monitor.mk +++ b/rules/docker-platform-monitor.mk @@ -33,7 +33,7 @@ SONIC_DOCKER_DBG_IMAGES += $(DOCKER_PLATFORM_MONITOR_DBG) SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_PLATFORM_MONITOR_DBG) $(DOCKER_PLATFORM_MONITOR)_CONTAINER_NAME = pmon -$(DOCKER_PLATFORM_MONITOR)_RUN_OPT += --net=host --privileged -t +$(DOCKER_PLATFORM_MONITOR)_RUN_OPT += --privileged -t $(DOCKER_PLATFORM_MONITOR)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro # Mount Arista python library on Aboot images to be used by plugins diff --git a/rules/docker-router-advertiser.mk b/rules/docker-router-advertiser.mk index 53e0d7600ec9..ec3fcf6e1fa3 100644 --- a/rules/docker-router-advertiser.mk +++ b/rules/docker-router-advertiser.mk @@ -23,6 +23,6 @@ SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_ROUTER_ADVERTISER_DBG) SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_ROUTER_ADVERTISER_DBG) $(DOCKER_ROUTER_ADVERTISER)_CONTAINER_NAME = radv -$(DOCKER_ROUTER_ADVERTISER)_RUN_OPT += --net=host --privileged -t +$(DOCKER_ROUTER_ADVERTISER)_RUN_OPT += --privileged -t $(DOCKER_ROUTER_ADVERTISER)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_ROUTER_ADVERTISER)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/docker-sflow.mk b/rules/docker-sflow.mk index 449ff7c566f2..67724ad7c548 100644 --- a/rules/docker-sflow.mk +++ b/rules/docker-sflow.mk @@ -26,7 +26,7 @@ SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_SFLOW_DBG) endif $(DOCKER_SFLOW)_CONTAINER_NAME = sflow -$(DOCKER_SFLOW)_RUN_OPT += --net=host --privileged -t +$(DOCKER_SFLOW)_RUN_OPT += --privileged -t $(DOCKER_SFLOW)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_SFLOW)_RUN_OPT += -v /host/warmboot:/var/warmboot diff --git a/rules/docker-snmp-sv2.mk b/rules/docker-snmp-sv2.mk index 1f403b7a8c8a..59f99ac78bc7 100644 --- a/rules/docker-snmp-sv2.mk +++ b/rules/docker-snmp-sv2.mk @@ -26,7 +26,7 @@ SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_SNMP_SV2_DBG) SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_SNMP_SV2_DBG) $(DOCKER_SNMP_SV2)_CONTAINER_NAME = snmp -$(DOCKER_SNMP_SV2)_RUN_OPT += --net=host --privileged -t +$(DOCKER_SNMP_SV2)_RUN_OPT += --privileged -t $(DOCKER_SNMP_SV2)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro # mount Arista platform python libraries to support corresponding platforms SNMP power status query $(DOCKER_SNMP_SV2)_RUN_OPT += -v /usr/lib/python3/dist-packages/arista:/usr/lib/python3/dist-packages/arista:ro diff --git a/rules/docker-teamd.mk b/rules/docker-teamd.mk index 598eff97e8f1..ce7b5bbab1f5 100644 --- a/rules/docker-teamd.mk +++ b/rules/docker-teamd.mk @@ -24,7 +24,7 @@ SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_TEAMD_DBG) SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_TEAMD_DBG) $(DOCKER_TEAMD)_CONTAINER_NAME = teamd -$(DOCKER_TEAMD)_RUN_OPT += --net=host --privileged -t +$(DOCKER_TEAMD)_RUN_OPT += --privileged -t $(DOCKER_TEAMD)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_TEAMD)_RUN_OPT += -v /host/warmboot:/var/warmboot diff --git a/rules/docker-telemetry.mk b/rules/docker-telemetry.mk index 361136306337..04f1871f334b 100644 --- a/rules/docker-telemetry.mk +++ b/rules/docker-telemetry.mk @@ -25,7 +25,7 @@ SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_TELEMETRY_DBG) endif $(DOCKER_TELEMETRY)_CONTAINER_NAME = telemetry -$(DOCKER_TELEMETRY)_RUN_OPT += --net=host --privileged -t +$(DOCKER_TELEMETRY)_RUN_OPT += --privileged -t $(DOCKER_TELEMETRY)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_TELEMETRY)_RUN_OPT += --mount type=bind,source="/var/platform/",target="/mnt/platform/" diff --git a/slave.mk b/slave.mk index 62a55597b129..dc15d7ad2577 100644 --- a/slave.mk +++ b/slave.mk @@ -666,15 +666,39 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export docker_container_name="$($(docker:-dbg.gz=.gz)_CONTAINER_NAME)" $(eval $(docker:-dbg.gz=.gz)_RUN_OPT += $($(docker:-dbg.gz=.gz)_$($*_IMAGE_TYPE)_RUN_OPT)) export docker_image_run_opt="$($(docker:-dbg.gz=.gz)_RUN_OPT)" - j2 files/build_templates/docker_image_ctl.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).sh + if [ -f files/build_templates/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 ]; then j2 files/build_templates/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service fi + + if [ -f files/build_templates/multi_instance/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME)@.service.j2 ]; then + j2 files/build_templates/multi_instance/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME)@.service.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME)@.service + + # performs the same check as the elif above, except with make commands so eval behaves properly + $(if $(shell ls files/build_templates/multi_instance/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME)@.service.j2 2>/dev/null),\ + $(eval $(docker:-dbg.gz=.gz)_TEMPLATE = yes) + ) + fi + if [ -f files/build_templates/single_instance/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 ]; then + j2 files/build_templates/single_instance/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service + fi + j2 files/build_templates/docker_image_ctl.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).sh chmod +x $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).sh ) + # Exported variables are used by sonic_debian_extension.sh export installer_start_scripts="$(foreach docker, $($*_DOCKERS),$(addsuffix .sh, $($(docker:-dbg.gz=.gz)_CONTAINER_NAME)))" - export installer_services="$(foreach docker, $($*_DOCKERS),$(addsuffix .service, $($(docker:-dbg.gz=.gz)_CONTAINER_NAME)))" + + # Marks template services with an "@" according to systemd convention + # If the $($docker)_TEMPLATE) variable is set, the service will be treated as a template + $(foreach docker, $($*_DOCKERS),\ + $(if $($(docker:-dbg.gz=.gz)_TEMPLATE),\ + $(eval SERVICES += "$(addsuffix @.service, $($(docker:-dbg.gz=.gz)_CONTAINER_NAME))"),\ + $(eval SERVICES += "$(addsuffix .service, $($(docker:-dbg.gz=.gz)_CONTAINER_NAME))") + ) + ) + export installer_services="$(SERVICES)" + export installer_extra_files="$(foreach docker, $($*_DOCKERS), $(foreach file, $($(docker:-dbg.gz=.gz)_BASE_IMAGE_FILES), $($(docker:-dbg.gz=.gz)_PATH)/base_image_files/$(file)))" j2 -f env files/initramfs-tools/union-mount.j2 onie-image.conf > files/initramfs-tools/union-mount @@ -705,6 +729,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $(foreach docker, $($*_DOCKERS), \ rm -f $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).sh rm -f $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service + rm -f $($(docker:-dbg.gz=.gz)_CONTAINER_NAME)@.service ) $(if $($*_DOCKERS), diff --git a/src/systemd-sonic-generator/systemd-sonic-generator.c b/src/systemd-sonic-generator/systemd-sonic-generator.c index a2723a28ff03..566d37ff0a4c 100644 --- a/src/systemd-sonic-generator/systemd-sonic-generator.c +++ b/src/systemd-sonic-generator/systemd-sonic-generator.c @@ -9,13 +9,17 @@ #include #include -#define MAX_NUM_TARGETS 5 -#define MAX_NUM_INSTALL_LINES 5 +#define MAX_NUM_TARGETS 15 +#define MAX_NUM_INSTALL_LINES 15 #define MAX_NUM_UNITS 128 +#define MAX_BUF_SIZE 512 static const char* UNIT_FILE_PREFIX = "/etc/systemd/system/"; static const char* CONFIG_FILE = "/etc/sonic/generated_services.conf"; - +static const char* MACHINE_CONF_FILE = "/host/machine.conf"; +static int num_asics; +static char** multi_instance_services; +static int num_multi_inst; void strip_trailing_newline(char* str) { /*** @@ -61,7 +65,7 @@ static int get_target_lines(char* unit_file, char* target_lines[]) { if (num_target_lines >= MAX_NUM_INSTALL_LINES) { fprintf(stderr, "Number of lines in [Install] section of %s exceeds MAX_NUM_INSTALL_LINES\n", unit_file); fputs("Extra [Install] lines will be ignored\n", stderr); - return num_target_lines; + break; } target_lines[num_target_lines] = strdup(line); num_target_lines++; @@ -75,7 +79,18 @@ static int get_target_lines(char* unit_file, char* target_lines[]) { return num_target_lines; } -static int get_install_targets_from_line(char* target_string, char* suffix, char* targets[], int existing_targets) { +static bool is_multi_instance_service(char *service_name){ + int i; + for(i=0; i < num_multi_inst; i++){ + if (strstr(service_name, multi_instance_services[i]) != NULL) { + return true; + } + } + return false; + +} + +static int get_install_targets_from_line(char* target_string, char* install_type, char* targets[], int existing_targets) { /*** Helper fuction for get_install_targets @@ -88,26 +103,113 @@ static int get_install_targets_from_line(char* target_string, char* suffix, char int num_targets = 0; while ((token = strtok_r(target_string, " ", &target_string))) { - target = strdup(token); - strip_trailing_newline(target); - - strcpy(final_target, target); - strcat(final_target, suffix); - - free(target); - if (num_targets + existing_targets >= MAX_NUM_TARGETS) { fputs("Number of targets found exceeds MAX_NUM_TARGETS\n", stderr); fputs("Additional targets will be ignored \n", stderr); return num_targets; } + target = strdup(token); + strip_trailing_newline(target); + + if (strstr(target, "%") != NULL) { + char* prefix = strtok(target, "."); + char* suffix = strtok(NULL, "."); + int prefix_len = strlen(prefix); + + strncpy(final_target, prefix, prefix_len - 2); + final_target[prefix_len - 2] = '\0'; + strcat(final_target, "."); + strcat(final_target, suffix); + } + else { + strcpy(final_target, target); + } + strcat(final_target, install_type); + + free(target); + targets[num_targets + existing_targets] = strdup(final_target); num_targets++; } return num_targets; } +static void replace_multi_inst_dep(char *src) { + FILE *fp_src; + FILE *fp_tmp; + char buf[MAX_BUF_SIZE]; + char* line = NULL; + int i; + ssize_t len; + char *token; + char *word; + char *line_copy; + char *service_name; + char *type; + ssize_t nread; + bool section_done = false; + char tmp_file_path[PATH_MAX]; + + /* assumes that the service files has 3 sections, + * in the order: Unit, Service and Install. + * Read service dependency from Unit and Install + * sections, replace if dependent on multi instance + * service. + */ + fp_src = fopen(src, "r"); + snprintf(tmp_file_path, PATH_MAX, "%s.tmp", src); + fp_tmp = fopen(tmp_file_path, "w"); + + while ((nread = getline(&line, &len, fp_src)) != -1 ) { + if (strstr(line, "[Service]") != NULL) { + section_done = true; + fputs(line,fp_tmp); + } else if (strstr(line, "[Install]") != NULL) { + section_done = false; + fputs(line,fp_tmp); + } else if ((strstr(line, "[Unit]") != NULL) || + (strstr(line, "Description") != NULL) || + (section_done == true)){ + fputs(line,fp_tmp); + } else { + line_copy = strdup(line); + token = strtok(line_copy, "="); + while ((word = strtok(NULL, " "))){ + if((strchr(word, '.') == NULL) || + (strchr(word, '@') != NULL)) { + snprintf(buf, MAX_BUF_SIZE,"%s=%s\n",token, word); + fputs(buf,fp_tmp); + } else { + service_name = strdup(word); + service_name = strtok(service_name, "."); + type = strtok(NULL, " "); + if (is_multi_instance_service(word)) { + for(i = 0; i < num_asics; i++){ + snprintf(buf, MAX_BUF_SIZE, "%s=%s@%d.%s\n", + token, service_name, i, type); + fputs(buf,fp_tmp); + } + } else { + snprintf(buf, MAX_BUF_SIZE,"%s=%s.%s\n",token, service_name, type); + fputs(buf, fp_tmp); + } + free(service_name); + } + } + free(line_copy); + } + } + fclose(fp_src); + fclose(fp_tmp); + free(line); + /* remove the .service file, rename the .service.tmp file + * as .service. + */ + remove(src); + rename(tmp_file_path, src); +} + static int get_install_targets(char* unit_file, char* targets[]) { /*** Returns install targets for a unit file @@ -124,10 +226,21 @@ static int get_install_targets(char* unit_file, char* targets[]) { char* line = NULL; bool first; char* target_suffix; + char *instance_name; + char *dot_ptr; strcpy(file_path, UNIT_FILE_PREFIX); strcat(file_path, unit_file); + instance_name = strdup(unit_file); + dot_ptr = strchr(instance_name, '.'); + *dot_ptr = '\0'; + + if((num_asics > 1) && (!is_multi_instance_service(instance_name))) { + replace_multi_inst_dep(file_path); + } + free(instance_name); + num_target_lines = get_target_lines(file_path, target_lines); if (num_target_lines < 0) { fprintf(stderr, "Error parsing targets for %s\n", unit_file); @@ -170,6 +283,7 @@ static int get_unit_files(char* unit_files[]) { char *line = NULL; size_t len = 0; ssize_t read; + char *pos; fp = fopen(CONFIG_FILE, "r"); @@ -179,13 +293,30 @@ static int get_unit_files(char* unit_files[]) { } int num_unit_files = 0; + num_multi_inst = 0; + + multi_instance_services = malloc(MAX_NUM_UNITS * sizeof(char *)); while ((read = getline(&line, &len, fp)) != -1) { if (num_unit_files >= MAX_NUM_UNITS) { fprintf(stderr, "Maximum number of units exceeded, ignoring extras\n"); - return num_unit_files; + break; } strip_trailing_newline(line); + + /* Get the multi-instance services */ + pos = strchr(line, '@'); + if (pos != NULL) { + multi_instance_services[num_multi_inst] = malloc(strlen(line)*sizeof(char)); + strncpy(multi_instance_services[num_multi_inst], line, pos-line); + num_multi_inst++; + } + + /* topology service to be started only for multiasic VS platform */ + if ((strcmp(line, "topology.service") == 0) && + (num_asics == 1)) { + continue; + } unit_files[num_unit_files] = strdup(line); num_unit_files++; } @@ -198,28 +329,70 @@ static int get_unit_files(char* unit_files[]) { } -static int install_unit_file(char* unit_file, char* target, char* install_dir) { +static char* insert_instance_number(char* unit_file, int instance) { /*** - Creates a symlink for a unit file installation + Adds an instance number to a systemd template name - For a given unit file and target directory, - create the appropriate symlink in the target directory - to enable the unit and have it started by Systemd + E.g. given unit_file='example@.service', instance=3, + returns a pointer to 'example@1.service' ***/ - char final_install_dir[PATH_MAX]; + char* prefix; + char* suffix; + char* instance_string; + char* instance_name; + char* temp_unit_file; + + instance_string = malloc(2 * sizeof(char)); + snprintf(instance_string, 2, "%d", instance); + + instance_name = malloc(strlen(unit_file) + 2); + + if (instance_name == NULL) { + fprintf(stderr, "Error creating instance %d of %s\n", instance, unit_file); + return NULL; + } + + temp_unit_file = strdup(unit_file); + prefix = strtok(temp_unit_file, "@"); + suffix = strtok(NULL, "@"); + + strcpy(instance_name, prefix); + strcat(instance_name, "@"); + strcat(instance_name, instance_string); + strcat(instance_name, suffix); + + free(instance_string); + free(temp_unit_file); + + return instance_name; +} + + +static int create_symlink(char* unit, char* target, char* install_dir, int instance) { + struct stat st; char src_path[PATH_MAX]; char dest_path[PATH_MAX]; - struct stat st; + char final_install_dir[PATH_MAX]; + char* unit_instance; int r; - assert(unit_file); - assert(target); + strcpy(src_path, UNIT_FILE_PREFIX); + strcat(src_path, unit); + + if (instance < 0) { + unit_instance = strdup(unit); + } + else { + unit_instance = insert_instance_number(unit, instance); + } strcpy(final_install_dir, install_dir); strcat(final_install_dir, target); + strcpy(dest_path, final_install_dir); + strcat(dest_path, "/"); + strcat(dest_path, unit_instance); - strcpy(src_path, UNIT_FILE_PREFIX); - strcat(src_path, unit_file); + free(unit_instance); if (stat(final_install_dir, &st) == -1) { // If doesn't exist, create @@ -242,7 +415,7 @@ static int install_unit_file(char* unit_file, char* target, char* install_dir) { fprintf(stderr, "Unable to create target directory %s\n", final_install_dir); return -1; } - } + } else if (S_ISDIR(st.st_mode)) { // If directory, verify correct permissions r = chmod(final_install_dir, 0755); @@ -251,11 +424,6 @@ static int install_unit_file(char* unit_file, char* target, char* install_dir) { return -1; } } - - - strcpy(dest_path, final_install_dir); - strcat(dest_path, "/"); - strcat(dest_path, unit_file); r = symlink(src_path, dest_path); @@ -267,6 +435,123 @@ static int install_unit_file(char* unit_file, char* target, char* install_dir) { } return 0; + +} + + +static int install_unit_file(char* unit_file, char* target, char* install_dir) { + /*** + Creates a symlink for a unit file installation + + For a given unit file and target directory, + create the appropriate symlink in the target directory + to enable the unit and have it started by Systemd + + If a multi ASIC platform is detected, enables multi-instance + services as well + ***/ + char* target_instance; + char* prefix; + char* suffix; + int r; + + assert(unit_file); + assert(target); + + + if ((num_asics > 1) && strstr(unit_file, "@") != NULL) { + + for (int i = 0; i < num_asics; i++) { + + if (strstr(target, "@") != NULL) { + target_instance = insert_instance_number(target, i); + } + else { + target_instance = strdup(target); + } + + r = create_symlink(unit_file, target_instance, install_dir, i); + if (r < 0) + fprintf(stderr, "Error installing %s for target %s\n", unit_file, target_instance); + + free(target_instance); + + } + } + else { + r = create_symlink(unit_file, target, install_dir, -1); + if (r < 0) + fprintf(stderr, "Error installing %s for target %s\n", unit_file, target); + } + + return 0; +} + + +static int get_num_of_asic() { + /*** + Determines if the current platform is single or multi-ASIC + ***/ + FILE *fp; + FILE *env_fp; + char *line = NULL; + char* token; + char* platform; + size_t len = 0; + ssize_t nread; + bool ans; + char asic_file[512]; + char* str_num_asic; + int num_asic = 1; + + fp = fopen(MACHINE_CONF_FILE, "r"); + + if (fp == NULL) { + fprintf(stderr, "Failed to open %s\n", MACHINE_CONF_FILE); + exit(EXIT_FAILURE); + } + + while ((nread = getline(&line, &len, fp)) != -1) { + if ((strstr(line, "onie_platform") != NULL) || + (strstr(line, "aboot_platform") != NULL)) { + token = strtok(line, "="); + platform = strtok(NULL, "="); + strip_trailing_newline(platform); + break; + } + } + + fclose(fp); + if(platform != NULL) { + snprintf(asic_file, 512, "/usr/share/sonic/device/%s/asic.conf", platform); + fp = fopen(asic_file, "r"); + if (fp != NULL) { + while ((nread = getline(&line, &len, fp)) != -1) { + if (strstr(line, "NUM_ASIC") != NULL) { + token = strtok(line, "="); + str_num_asic = strtok(NULL, "="); + strip_trailing_newline(str_num_asic); + if (str_num_asic != NULL){ + sscanf(str_num_asic, "%d",&num_asic); + } + break; + } + } + fclose(fp); + free(line); + } + } + + /*set environment variable NUM_ASIC */ + env_fp = fopen("/etc/environment", "a"); + if (env_fp == NULL) { + fprintf(stderr, "Failed to open environment file\n"); + exit(EXIT_FAILURE); + } + fprintf(env_fp, "NUM_ASIC=%d\n", num_asic); + fclose(env_fp); + return num_asic; + } @@ -274,14 +559,20 @@ int main(int argc, char **argv) { char* unit_files[MAX_NUM_UNITS]; char install_dir[PATH_MAX]; char* targets[MAX_NUM_TARGETS]; + char* unit_instance; + char* prefix; + char* suffix; int num_unit_files; int num_targets; + int r; if (argc <= 1) { fputs("Installation directory required as argument\n", stderr); return 1; } + num_asics = get_num_of_asic(); + strcpy(install_dir, argv[1]); strcat(install_dir, "/"); @@ -289,21 +580,38 @@ int main(int argc, char **argv) { // For each unit file, get the installation targets and install the unit for (int i = 0; i < num_unit_files; i++) { - num_targets = get_install_targets(unit_files[i], targets); + unit_instance = strdup(unit_files[i]); + if ((num_asics == 1) && strstr(unit_instance, "@") != NULL) { + prefix = strtok(unit_instance, "@"); + suffix = strtok(NULL, "@"); + + strcpy(unit_instance, prefix); + strcat(unit_instance, suffix); + } + + num_targets = get_install_targets(unit_instance, targets); if (num_targets < 0) { - fprintf(stderr, "Error parsing %s\n", unit_files[i]); + fprintf(stderr, "Error parsing %s\n", unit_instance); + free(unit_instance); free(unit_files[i]); continue; } for (int j = 0; j < num_targets; j++) { - if (install_unit_file(unit_files[i], targets[j], install_dir) != 0) - fprintf(stderr, "Error installing %s to target directory %s\n", unit_files[i], targets[j]); + if (install_unit_file(unit_instance, targets[j], install_dir) != 0) + fprintf(stderr, "Error installing %s to target directory %s\n", unit_instance, targets[j]); free(targets[j]); } + free(unit_instance); free(unit_files[i]); } + + for (int i = 0; i < num_multi_inst; i++) { + free(multi_instance_services[i]); + } + free(multi_instance_services); + return 0; } From a2656416fe48f00f270ba6df8ab056dd90930af2 Mon Sep 17 00:00:00 2001 From: Dong Zhang <41927498+dzhangalibaba@users.noreply.github.com> Date: Wed, 22 Jan 2020 11:27:21 -0800 Subject: [PATCH 025/178] [MultiDB] (./dockers dir) : replace redis-cli with sonic-db-cli and use new DBConnector (#3923) * [MultiDB] (./dockers dirs): replace redis-cli with sonic-db-cli and use new DBConnector * remove unnecessary quota * update typo --- dockers/docker-dhcp-relay/wait_for_intf.sh.j2 | 4 +--- dockers/docker-fpm-frr/bgpcfgd | 11 ++++++----- dockers/docker-lldp-sv2/lldpmgrd | 16 ++++++---------- dockers/docker-orchagent/swssconfig.sh | 6 +++--- .../docker-router-advertiser/wait_for_intf.sh.j2 | 4 +--- dockers/docker-sonic-telemetry/telemetry.sh | 2 +- .../tests/sample_output/wait_for_intf.sh | 4 +--- 7 files changed, 19 insertions(+), 28 deletions(-) diff --git a/dockers/docker-dhcp-relay/wait_for_intf.sh.j2 b/dockers/docker-dhcp-relay/wait_for_intf.sh.j2 index 0488799a4c81..568f128b3772 100644 --- a/dockers/docker-dhcp-relay/wait_for_intf.sh.j2 +++ b/dockers/docker-dhcp-relay/wait_for_intf.sh.j2 @@ -1,7 +1,5 @@ #!/usr/bin/env bash -STATE_DB_IDX="6" - function wait_until_iface_ready { IFACE_NAME=$1 @@ -12,7 +10,7 @@ function wait_until_iface_ready # Wait for the interface to come up # (i.e., interface is present in STATE_DB and state is "ok") while true; do - RESULT=$(redis-cli -n ${STATE_DB_IDX} HGET "INTERFACE_TABLE|${IFACE_NAME}|${IFACE_CIDR}" "state" 2> /dev/null) + RESULT=$(sonic-db-cli STATE_DB HGET "INTERFACE_TABLE|${IFACE_NAME}|${IFACE_CIDR}" "state" 2> /dev/null) if [ x"$RESULT" == x"ok" ]; then break fi diff --git a/dockers/docker-fpm-frr/bgpcfgd b/dockers/docker-fpm-frr/bgpcfgd index 972c85ee271b..4348d22bcb8f 100755 --- a/dockers/docker-fpm-frr/bgpcfgd +++ b/dockers/docker-fpm-frr/bgpcfgd @@ -86,9 +86,10 @@ class Daemon(object): self.callbacks = defaultdict(lambda : defaultdict(list)) # db -> table -> [] self.subscribers = set() - def add_manager(self, db, table_name, callback): + def add_manager(self, db_name, table_name, callback): + db = swsscommon.SonicDBConfig.getDbId(db_name) if db not in self.db_connectors: - self.db_connectors[db] = swsscommon.DBConnector(db, swsscommon.DBConnector.DEFAULT_UNIXSOCKET, 0) + self.db_connectors[db] = swsscommon.DBConnector(db_name, 0) if table_name not in self.callbacks[db]: conn = self.db_connectors[db] @@ -225,7 +226,7 @@ class BGPDeviceMetaMgr(Manager): daemon, directory, [], - swsscommon.CONFIG_DB, + "CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME ) @@ -250,7 +251,7 @@ class BGPNeighborMetaMgr(Manager): daemon, directory, [], - swsscommon.CONFIG_DB, + "CONFIG_DB", swsscommon.CFG_DEVICE_NEIGHBOR_METADATA_TABLE_NAME ) @@ -272,7 +273,7 @@ class BGPPeerMgr(Manager): ("meta", "localhost/bgp_asn"), ("neigmeta", ""), ], - swsscommon.CONFIG_DB, + "CONFIG_DB", swsscommon.CFG_BGP_NEIGHBOR_TABLE_NAME ) self.peers = self.load_peers() diff --git a/dockers/docker-lldp-sv2/lldpmgrd b/dockers/docker-lldp-sv2/lldpmgrd index edcdc5c42e47..36b6e67a5f47 100755 --- a/dockers/docker-lldp-sv2/lldpmgrd +++ b/dockers/docker-lldp-sv2/lldpmgrd @@ -84,22 +84,18 @@ class LldpManager(object): pending_cmds: Dictionary where key is port name, value is pending LLDP configuration command to run """ - REDIS_HOSTNAME = "localhost" - REDIS_PORT = 6379 REDIS_TIMEOUT_MS = 0 def __init__(self): # Open a handle to the Config database - self.config_db = swsscommon.DBConnector(swsscommon.CONFIG_DB, - self.REDIS_HOSTNAME, - self.REDIS_PORT, - self.REDIS_TIMEOUT_MS) + self.config_db = swsscommon.DBConnector("CONFIG_DB", + self.REDIS_TIMEOUT_MS, + True) # Open a handle to the Application database - self.appl_db = swsscommon.DBConnector(swsscommon.APPL_DB, - self.REDIS_HOSTNAME, - self.REDIS_PORT, - self.REDIS_TIMEOUT_MS) + self.appl_db = swsscommon.DBConnector("APPL_DB", + self.REDIS_TIMEOUT_MS, + True) self.pending_cmds = {} diff --git a/dockers/docker-orchagent/swssconfig.sh b/dockers/docker-orchagent/swssconfig.sh index c521fadf0a49..856b3bcd0e41 100755 --- a/dockers/docker-orchagent/swssconfig.sh +++ b/dockers/docker-orchagent/swssconfig.sh @@ -43,11 +43,11 @@ HWSKU=`sonic-cfggen -d -v "DEVICE_METADATA['localhost']['hwsku']"` # Don't load json config if system warm start or # swss docker warm start is enabled, the data already exists in appDB. -SYSTEM_WARM_START=`redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|system" enable` -SWSS_WARM_START=`redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|swss" enable` +SYSTEM_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` +SWSS_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|swss" enable` if [[ "$SYSTEM_WARM_START" == "true" ]] || [[ "$SWSS_WARM_START" == "true" ]]; then # We have to make sure db data has not been flushed. - RESTORE_COUNT=`redis-cli -n 6 hget "WARM_RESTART_TABLE|orchagent" restore_count` + RESTORE_COUNT=`sonic-db-cli STATE_DB hget "WARM_RESTART_TABLE|orchagent" restore_count` if [[ -n "$RESTORE_COUNT" ]] && [[ "$RESTORE_COUNT" != "0" ]]; then exit 0 fi diff --git a/dockers/docker-router-advertiser/wait_for_intf.sh.j2 b/dockers/docker-router-advertiser/wait_for_intf.sh.j2 index a044df0fc996..980b472b3e0a 100644 --- a/dockers/docker-router-advertiser/wait_for_intf.sh.j2 +++ b/dockers/docker-router-advertiser/wait_for_intf.sh.j2 @@ -1,7 +1,5 @@ #!/usr/bin/env bash -STATE_DB_IDX="6" - VLAN_TABLE_PREFIX="VLAN_TABLE" function wait_until_iface_ready @@ -14,7 +12,7 @@ function wait_until_iface_ready # Wait for the interface to come up # (i.e., interface is present in STATE_DB and state is "ok") while true; do - RESULT=$(redis-cli -n ${STATE_DB_IDX} HGET "${TABLE_PREFIX}|${IFACE}" "state" 2> /dev/null) + RESULT=$(sonic-db-cli STATE_DB HGET "${TABLE_PREFIX}|${IFACE}" "state" 2> /dev/null) if [ x"$RESULT" == x"ok" ]; then break fi diff --git a/dockers/docker-sonic-telemetry/telemetry.sh b/dockers/docker-sonic-telemetry/telemetry.sh index 8b29b4d616a5..37ab4dd2d04f 100755 --- a/dockers/docker-sonic-telemetry/telemetry.sh +++ b/dockers/docker-sonic-telemetry/telemetry.sh @@ -29,7 +29,7 @@ fi # If no configuration entry exists for TELEMETRY, create one default port if [ -z $TELEMETRY ]; then - redis-cli -n 4 hset "TELEMETRY|gnmi" port 8080 + sonic-db-cli CONFIG_DB hset "TELEMETRY|gnmi" port 8080 fi PORT=`sonic-cfggen -d -v "TELEMETRY['gnmi']['port']"` diff --git a/src/sonic-config-engine/tests/sample_output/wait_for_intf.sh b/src/sonic-config-engine/tests/sample_output/wait_for_intf.sh index 918f0b6e1648..6d90afa60ad7 100644 --- a/src/sonic-config-engine/tests/sample_output/wait_for_intf.sh +++ b/src/sonic-config-engine/tests/sample_output/wait_for_intf.sh @@ -1,7 +1,5 @@ #!/usr/bin/env bash -STATE_DB_IDX="6" - function wait_until_iface_ready { IFACE_NAME=$1 @@ -12,7 +10,7 @@ function wait_until_iface_ready # Wait for the interface to come up # (i.e., interface is present in STATE_DB and state is "ok") while true; do - RESULT=$(redis-cli -n ${STATE_DB_IDX} HGET "INTERFACE_TABLE|${IFACE_NAME}|${IFACE_CIDR}" "state" 2> /dev/null) + RESULT=$(sonic-db-cli STATE_DB HGET "INTERFACE_TABLE|${IFACE_NAME}|${IFACE_CIDR}" "state" 2> /dev/null) if [ x"$RESULT" == x"ok" ]; then break fi From c841693007a8a9df1e116aff4bf5caf5a5442bf7 Mon Sep 17 00:00:00 2001 From: Arun Saravanan Balachandran <52521751+ArunSaravananBalachandran@users.noreply.github.com> Date: Fri, 24 Jan 2020 23:38:22 +0530 Subject: [PATCH 026/178] DellEMC: Platform2.0 API enhancements in DellEMC S6000 and other API changes (#3956) --- .../s6000/sonic_platform/chassis.py | 1 + .../s6000/sonic_platform/eeprom.py | 4 ++ .../s6000/sonic_platform/fan.py | 42 ++++++++++++++++--- .../s6000/sonic_platform/psu.py | 30 ++++++++++++- .../s6000/sonic_platform/thermal.py | 37 +++++++++++++++- .../s6100/sonic_platform/fan.py | 11 +++-- .../z9100/sonic_platform/chassis.py | 2 +- .../z9100/sonic_platform/fan.py | 11 +++-- 8 files changed, 122 insertions(+), 16 deletions(-) diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py index c212df88c147..e94a7d1210f5 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py @@ -43,6 +43,7 @@ class Chassis(ChassisBase): reset_reason_dict[0x6] = ChassisBase.REBOOT_CAUSE_NON_HARDWARE def __init__(self): + ChassisBase.__init__(self) # Initialize SFP list self.PORT_START = 0 self.PORT_END = 31 diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/eeprom.py index 32462e5a256e..a82fd6a70201 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/eeprom.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/eeprom.py @@ -150,6 +150,10 @@ def _load_device_eeprom(self): except: self.serial_number = 'NA' self.part_number = 'NA' + if self.is_psu_eeprom: + self.psu_type = 'NA' + else: + self.fan_type = 'NA' else: (valid, data) = self._get_eeprom_field("PPID") if valid: diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/fan.py index 29555b443a22..92f83c8fbc79 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/fan.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/fan.py @@ -11,6 +11,7 @@ try: import os + import glob from sonic_platform_base.fan_base import FanBase from sonic_platform.eeprom import Eeprom except ImportError as e: @@ -29,6 +30,7 @@ class Fan(FanBase): def __init__(self, fan_index, psu_fan=False, dependency=None): self.is_psu_fan = psu_fan + self.is_driver_initialized = True if not self.is_psu_fan: # Fan is 1-based in DellEMC platforms @@ -45,10 +47,18 @@ def __init__(self, fan_index, psu_fan=False, dependency=None): else: self.index = fan_index self.dependency = dependency - self.get_fan_speed_reg = self.I2C_DIR +\ - "i2c-1/1-005{}/fan1_target".format(10 - self.index) self.set_fan_speed_reg = self.I2C_DIR +\ "i2c-1/1-005{}/fan1_target".format(10 - self.index) + + hwmon_dir = self.I2C_DIR +\ + "i2c-1/1-005{}/hwmon/".format(10 - self.index) + try: + hwmon_node = os.listdir(hwmon_dir)[0] + except OSError: + hwmon_node = "hwmon*" + self.is_driver_initialized = False + + self.get_fan_speed_reg = hwmon_dir + hwmon_node + '/fan1_input' self.max_fan_speed = MAX_S6000_PSU_FAN_SPEED def _get_cpld_register(self, reg_name): @@ -93,6 +103,14 @@ def _get_i2c_register(self, reg_file): # reg_name and on failure returns 'ERR' rv = 'ERR' + if not self.is_driver_initialized: + reg_file_path = glob.glob(reg_file) + if len(reg_file_path): + reg_file = reg_file_path[0] + self._get_sysfs_path() + else: + return rv + if (not os.path.isfile(reg_file)): return rv @@ -122,6 +140,13 @@ def _set_i2c_register(self, reg_file, value): return rv + def _get_sysfs_path(self): + fan_speed_reg = glob.glob(self.get_fan_speed_reg) + + if len(fan_speed_reg): + self.get_fan_speed_reg = fan_speed_reg[0] + self.is_driver_initialized = True + def get_name(self): """ Retrieves the name of the Fan @@ -200,16 +225,21 @@ def get_direction(self): Returns: A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST depending on fan direction + + Notes: + In DellEMC platforms, + - Forward/Exhaust : Air flows from Port side to Fan side. + - Reverse/Intake : Air flows from Fan side to Port side. """ if self.is_psu_fan: - direction = {1: 'FAN_DIRECTION_EXHAUST', 2: 'FAN_DIRECTION_INTAKE', - 3: 'FAN_DIRECTION_EXHAUST', 4: 'FAN_DIRECTION_INTAKE'} + direction = {1: self.FAN_DIRECTION_EXHAUST, 2: self.FAN_DIRECTION_INTAKE, + 3: self.FAN_DIRECTION_EXHAUST, 4: self.FAN_DIRECTION_INTAKE} fan_direction = self.dependency.eeprom.airflow_fan_type() else: - direction = {1: 'FAN_DIRECTION_EXHAUST', 2: 'FAN_DIRECTION_INTAKE'} + direction = {1: self.FAN_DIRECTION_EXHAUST, 2: self.FAN_DIRECTION_INTAKE} fan_direction = self.eeprom.airflow_fan_type() - return direction.get(fan_direction,'NA') + return direction.get(fan_direction, self.FAN_DIRECTION_NOT_APPLICABLE) def get_speed(self): """ diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/psu.py index e2897a78d9fd..24200f1c7d39 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/psu.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/psu.py @@ -11,6 +11,7 @@ try: import os + import glob from sonic_platform_base.psu_base import PsuBase from sonic_platform.eeprom import Eeprom from sonic_platform.fan import Fan @@ -29,12 +30,20 @@ def __init__(self, psu_index): self.index = psu_index + 1 self.psu_presence_reg = "psu{}_prs".format(psu_index) self.psu_status_reg = "powersupply_status" + self.is_driver_initialized = False if self.index == 1: ltc_dir = self.I2C_DIR + "i2c-11/11-0042/hwmon/" else: ltc_dir = self.I2C_DIR + "i2c-11/11-0040/hwmon/" - hwmon_node = os.listdir(ltc_dir)[0] + + try: + hwmon_node = os.listdir(ltc_dir)[0] + except OSError: + hwmon_node = "hwmon*" + else: + self.is_driver_initialized = True + self.HWMON_DIR = ltc_dir + hwmon_node + '/' self.psu_voltage_reg = self.HWMON_DIR + "in1_input" @@ -73,6 +82,14 @@ def _get_i2c_register(self, reg_file): # reg_name and on failure returns 'ERR' rv = 'ERR' + if not self.is_driver_initialized: + reg_file_path = glob.glob(reg_file) + if len(reg_file_path): + reg_file = reg_file_path[0] + self._get_sysfs_path() + else: + return rv + if (not os.path.isfile(reg_file)): return rv @@ -86,6 +103,17 @@ def _get_i2c_register(self, reg_file): rv = rv.lstrip(" ") return rv + def _get_sysfs_path(self): + voltage_reg = glob.glob(self.psu_voltage_reg) + current_reg = glob.glob(self.psu_current_reg) + power_reg = glob.glob(self.psu_power_reg) + + if len(voltage_reg) and len(current_reg) and len(power_reg): + self.psu_voltage_reg = voltage_reg_path[0] + self.psu_current_reg = current_reg_path[0] + self.psu_power_reg = power_reg_path[0] + self.is_driver_initialized = True + def get_name(self): """ Retrieves the name of the device diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/thermal.py index 70bac0c729d2..a54336d40f1c 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/thermal.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/thermal.py @@ -11,6 +11,7 @@ try: import os + import glob from sonic_platform_base.thermal_base import ThermalBase from sonic_platform.psu import Psu except ImportError as e: @@ -36,13 +37,19 @@ class Thermal(ThermalBase): def __init__(self, thermal_index): self.index = thermal_index + 1 self.is_psu_thermal = False + self.is_driver_initialized = True self.dependency = None if self.index < 9: i2c_path = self.I2C_DIR + self.I2C_DEV_MAPPING[self.index - 1][0] hwmon_temp_index = self.I2C_DEV_MAPPING[self.index - 1][1] hwmon_temp_suffix = "max" - hwmon_node = os.listdir(i2c_path)[0] + try: + hwmon_node = os.listdir(i2c_path)[0] + except OSError: + hwmon_node = "hwmon*" + self.is_driver_initialized = False + self.HWMON_DIR = i2c_path + hwmon_node + '/' if self.index == 4: @@ -55,7 +62,12 @@ def __init__(self, thermal_index): dev_path = "/sys/devices/platform/coretemp.0/hwmon/" hwmon_temp_index = self.index - 7 hwmon_temp_suffix = "crit" - hwmon_node = os.listdir(dev_path)[0] + try: + hwmon_node = os.listdir(dev_path)[0] + except OSError: + hwmon_node = "hwmon*" + self.is_driver_initialized = False + self.HWMON_DIR = dev_path + hwmon_node + '/' self.thermal_temperature_file = self.HWMON_DIR \ @@ -70,6 +82,14 @@ def _read_sysfs_file(self, sysfs_file): # sysfs_file and on failure returns 'ERR' rv = 'ERR' + if not self.is_driver_initialized: + sysfs_file_path = glob.glob(sysfs_file) + if len(sysfs_file_path): + sysfs_file = sysfs_file_path[0] + self._get_sysfs_path() + else: + return rv + if (not os.path.isfile(sysfs_file)): return rv @@ -83,6 +103,19 @@ def _read_sysfs_file(self, sysfs_file): rv = rv.lstrip(" ") return rv + def _get_sysfs_path(self): + temperature_path = glob.glob(self.thermal_temperature_file) + high_threshold_path = glob.glob(self.thermal_high_threshold_file) + low_threshold_path = glob.glob(self.thermal_low_threshold_file) + + if len(temperature_path) and len(high_threshold_path): + self.thermal_temperature_file = temperature_path[0] + self.thermal_high_threshold_file = high_threshold_path[0] + if len(low_threshold_path): + self.thermal_low_threshold_file = low_threshold_path + + self.is_driver_initialized = True + def get_name(self): """ Retrieves the name of the thermal diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan.py index a2ee0cd10421..49e95357b6f1 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan.py @@ -146,7 +146,7 @@ def get_status(self): fantray_status = self._get_pmc_register(self.get_fan_speed_reg) if (fantray_status != 'ERR'): fantray_status = int(fantray_status, 10) - if (fantray_status > 5000): + if (fantray_status > 1000): status = True else: fantray_status = self._get_pmc_register(self.fan_status_reg) @@ -163,13 +163,18 @@ def get_direction(self): Returns: A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST depending on fan direction + + Notes: + In DellEMC platforms, + - Forward/Exhaust : Air flows from Port side to Fan side. + - Reverse/Intake : Air flows from Fan side to Port side. """ - direction = ['FAN_DIRECTION_INTAKE', 'FAN_DIRECTION_EXHAUST'] + direction = [self.FAN_DIRECTION_INTAKE, self.FAN_DIRECTION_EXHAUST] fan_direction = self._get_pmc_register(self.get_fan_dir_reg) if (fan_direction != 'ERR') and self.get_presence(): fan_direction = int(fan_direction, 10) else: - return 'N/A' + return self.FAN_DIRECTION_NOT_APPLICABLE return direction[fan_direction] def get_speed(self): diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py index 27164409d962..7f4dab3a19c0 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py @@ -73,6 +73,7 @@ class Chassis(ChassisBase): power_reason_dict[44] = ChassisBase.REBOOT_CAUSE_INSUFFICIENT_FAN_SPEED def __init__(self): + ChassisBase.__init__(self) PORT_START = 0 PORT_END = 31 PORTS_IN_BLOCK = (PORT_END + 1) @@ -92,7 +93,6 @@ def __init__(self): self.PORT_I2C_MAPPING[index][1]) self._sfp_list.append(sfp_node) - ChassisBase.__init__(self) # Initialize EEPROM self._eeprom = Eeprom() for i in range(MAX_Z9100_FANTRAY): diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/fan.py index 03ac8cd5c71f..6ff688fa3a1e 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/fan.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/fan.py @@ -145,7 +145,7 @@ def get_status(self): fantray_status = self._get_pmc_register(self.get_fan_speed_reg) if (fantray_status != 'ERR'): fantray_status = int(fantray_status, 10) - if (fantray_status > 5000): + if (fantray_status > 1000): status = True else: fantray_status = self._get_pmc_register(self.fan_status_reg) @@ -162,13 +162,18 @@ def get_direction(self): Returns: A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST depending on fan direction + + Notes: + In DellEMC platforms, + - Forward/Exhaust : Air flows from Port side to Fan side. + - Reverse/Intake : Air flows from Fan side to Port side. """ - direction = ['FAN_DIRECTION_INTAKE', 'FAN_DIRECTION_EXHAUST'] + direction = [self.FAN_DIRECTION_INTAKE, self.FAN_DIRECTION_EXHAUST] fan_direction = self._get_pmc_register(self.get_fan_dir_reg) if (fan_direction != 'ERR') and self.get_presence(): fan_direction = int(fan_direction, 10) else: - return 'N/A' + return self.FAN_DIRECTION_NOT_APPLICABLE return direction[fan_direction] def get_speed(self): From cc825ff2fe34f31b8661d9b672ed87fe0fa07174 Mon Sep 17 00:00:00 2001 From: Howard Persh Date: Wed, 22 Jan 2020 10:02:28 -0800 Subject: [PATCH 027/178] [startup] Fixes issue with /var/platform directory not created (#4000) --- files/image_config/platform/rc.local | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/files/image_config/platform/rc.local b/files/image_config/platform/rc.local index d64ec1bb7916..e36b20950b42 100755 --- a/files/image_config/platform/rc.local +++ b/files/image_config/platform/rc.local @@ -328,10 +328,10 @@ if [ -f $FIRST_BOOT_FILE ]; then mv /host/grub.cfg /host/grub/grub.cfg fi + # Create dir where following scripts put their output files + mkdir -p /var/platform + firsttime_exit fi -# Create dir where following scripts put their output files -mkdir -p /var/platform - exit 0 From 8a7a88306c1edc44d5fc55d5fc6b52a3bcbc1fac Mon Sep 17 00:00:00 2001 From: Volodymyr Samotiy Date: Wed, 29 Jan 2020 07:53:46 +0200 Subject: [PATCH 028/178] [Mellanox] Update SAI/SDK/FW versions (#4028) * SAI implementation 1.15.5 (headers 1.5.1) * SDK 4.3.2908 * FW xx.2000.2720 Signed-off-by: Volodymyr Samotiy --- platform/mellanox/fw.mk | 4 ++-- platform/mellanox/mlnx-sai.mk | 2 +- platform/mellanox/mlnx-sai/SAI-Implementation | 2 +- platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers | 2 +- platform/mellanox/sdk.mk | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/platform/mellanox/fw.mk b/platform/mellanox/fw.mk index 4f6e7199eac8..c088fe274b06 100644 --- a/platform/mellanox/fw.mk +++ b/platform/mellanox/fw.mk @@ -11,12 +11,12 @@ else FW_FROM_URL = n endif -MLNX_SPC_FW_VERSION = 13.2000.2714 +MLNX_SPC_FW_VERSION = 13.2000.2720 MLNX_SPC_FW_FILE = fw-SPC-rel-$(subst .,_,$(MLNX_SPC_FW_VERSION))-EVB.mfa $(MLNX_SPC_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC_FW_FILE) -MLNX_SPC2_FW_VERSION = 29.2000.2714 +MLNX_SPC2_FW_VERSION = 29.2000.2720 MLNX_SPC2_FW_FILE = fw-SPC2-rel-$(subst .,_,$(MLNX_SPC2_FW_VERSION))-EVB.mfa $(MLNX_SPC2_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC2_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC2_FW_FILE) diff --git a/platform/mellanox/mlnx-sai.mk b/platform/mellanox/mlnx-sai.mk index 39942111f26a..baced2780637 100644 --- a/platform/mellanox/mlnx-sai.mk +++ b/platform/mellanox/mlnx-sai.mk @@ -1,6 +1,6 @@ # Mellanox SAI -MLNX_SAI_VERSION = SAIRel1.15.2-master +MLNX_SAI_VERSION = SAIRel1.15.5-master export MLNX_SAI_VERSION diff --git a/platform/mellanox/mlnx-sai/SAI-Implementation b/platform/mellanox/mlnx-sai/SAI-Implementation index d878245e364c..4b40b5191b07 160000 --- a/platform/mellanox/mlnx-sai/SAI-Implementation +++ b/platform/mellanox/mlnx-sai/SAI-Implementation @@ -1 +1 @@ -Subproject commit d878245e364ce8d5edd08bbd7120c44c92362235 +Subproject commit 4b40b5191b07118326a29be2d491f4362fc02eee diff --git a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers index b85c06417b2d..026b12e2bd02 160000 --- a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers +++ b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers @@ -1 +1 @@ -Subproject commit b85c06417b2df7e18990d0143a30ab1c46e34225 +Subproject commit 026b12e2bd02b79fdf50eb5f45a161c95ec94837 diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index 55a5b08bba31..f105f6b22f7b 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -1,5 +1,5 @@ MLNX_SDK_BASE_PATH = $(PLATFORM_PATH)/sdk-src/sx-kernel/Switch-SDK-drivers/bin/ -MLNX_SDK_VERSION = 4.3.2904 +MLNX_SDK_VERSION = 4.3.2908 MLNX_SDK_ISSU_VERSION = 101 MLNX_SDK_DEB_VERSION = $(subst _,.,$(MLNX_SDK_VERSION)) From d6aee4cc659bb5f4a0a78cdd4a839af5c119280f Mon Sep 17 00:00:00 2001 From: yozhao101 <56170650+yozhao101@users.noreply.github.com> Date: Wed, 22 Jan 2020 17:00:50 -0800 Subject: [PATCH 029/178] [Monit] Change the full process name of syncd in the monit config file. (#4033) Since the syncd process running on different platforms will have the different full path names, we change the full path name of process syncd in the monit config file such that it will be universal and is not for a specific vendor. Signed-off-by: Yong Zhao --- platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd | 2 +- .../broadcom/docker-syncd-brcm/base_image_files/monit_syncd | 2 +- platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd | 2 +- .../centec/docker-syncd-centec/base_image_files/monit_syncd | 2 +- .../docker-syncd-mrvl/base_image_files/monit_syncd | 2 +- .../docker-syncd-mrvl/base_image_files/monit_syncd | 2 +- platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd | 2 +- .../mellanox/docker-syncd-mlnx/base_image_files/monit_syncd | 2 +- .../nephos/docker-syncd-nephos/base_image_files/monit_syncd | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd b/platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd index 9cc5891c7c32..3079618990ed 100644 --- a/platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd +++ b/platform/barefoot/docker-syncd-bfn/base_image_files/monit_syncd @@ -3,5 +3,5 @@ ## process list: ## syncd ############################################################################### -check process syncd matching "/usr/bin/syncd --diag" +check process syncd matching "/usr/bin/syncd" if does not exist for 5 times within 5 cycles then alert diff --git a/platform/broadcom/docker-syncd-brcm/base_image_files/monit_syncd b/platform/broadcom/docker-syncd-brcm/base_image_files/monit_syncd index 3f8bc50007d7..0b9ec741cd57 100644 --- a/platform/broadcom/docker-syncd-brcm/base_image_files/monit_syncd +++ b/platform/broadcom/docker-syncd-brcm/base_image_files/monit_syncd @@ -4,7 +4,7 @@ ## syncd ## dsserve ############################################################################### -check process syncd matching "/usr/bin/syncd --diag" +check process syncd matching "/usr/bin/syncd" if does not exist for 5 times within 5 cycles then alert check process dsserve matching "/usr/bin/dsserve /usr/bin/syncd" diff --git a/platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd b/platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd index 9cc5891c7c32..3079618990ed 100644 --- a/platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd +++ b/platform/cavium/docker-syncd-cavm/base_image_files/monit_syncd @@ -3,5 +3,5 @@ ## process list: ## syncd ############################################################################### -check process syncd matching "/usr/bin/syncd --diag" +check process syncd matching "/usr/bin/syncd" if does not exist for 5 times within 5 cycles then alert diff --git a/platform/centec/docker-syncd-centec/base_image_files/monit_syncd b/platform/centec/docker-syncd-centec/base_image_files/monit_syncd index 9cc5891c7c32..3079618990ed 100644 --- a/platform/centec/docker-syncd-centec/base_image_files/monit_syncd +++ b/platform/centec/docker-syncd-centec/base_image_files/monit_syncd @@ -3,5 +3,5 @@ ## process list: ## syncd ############################################################################### -check process syncd matching "/usr/bin/syncd --diag" +check process syncd matching "/usr/bin/syncd" if does not exist for 5 times within 5 cycles then alert diff --git a/platform/marvell-arm64/docker-syncd-mrvl/base_image_files/monit_syncd b/platform/marvell-arm64/docker-syncd-mrvl/base_image_files/monit_syncd index 9cc5891c7c32..3079618990ed 100644 --- a/platform/marvell-arm64/docker-syncd-mrvl/base_image_files/monit_syncd +++ b/platform/marvell-arm64/docker-syncd-mrvl/base_image_files/monit_syncd @@ -3,5 +3,5 @@ ## process list: ## syncd ############################################################################### -check process syncd matching "/usr/bin/syncd --diag" +check process syncd matching "/usr/bin/syncd" if does not exist for 5 times within 5 cycles then alert diff --git a/platform/marvell-armhf/docker-syncd-mrvl/base_image_files/monit_syncd b/platform/marvell-armhf/docker-syncd-mrvl/base_image_files/monit_syncd index 9cc5891c7c32..3079618990ed 100644 --- a/platform/marvell-armhf/docker-syncd-mrvl/base_image_files/monit_syncd +++ b/platform/marvell-armhf/docker-syncd-mrvl/base_image_files/monit_syncd @@ -3,5 +3,5 @@ ## process list: ## syncd ############################################################################### -check process syncd matching "/usr/bin/syncd --diag" +check process syncd matching "/usr/bin/syncd" if does not exist for 5 times within 5 cycles then alert diff --git a/platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd b/platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd index 9cc5891c7c32..3079618990ed 100644 --- a/platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd +++ b/platform/marvell/docker-syncd-mrvl/base_image_files/monit_syncd @@ -3,5 +3,5 @@ ## process list: ## syncd ############################################################################### -check process syncd matching "/usr/bin/syncd --diag" +check process syncd matching "/usr/bin/syncd" if does not exist for 5 times within 5 cycles then alert diff --git a/platform/mellanox/docker-syncd-mlnx/base_image_files/monit_syncd b/platform/mellanox/docker-syncd-mlnx/base_image_files/monit_syncd index 9cc5891c7c32..3079618990ed 100644 --- a/platform/mellanox/docker-syncd-mlnx/base_image_files/monit_syncd +++ b/platform/mellanox/docker-syncd-mlnx/base_image_files/monit_syncd @@ -3,5 +3,5 @@ ## process list: ## syncd ############################################################################### -check process syncd matching "/usr/bin/syncd --diag" +check process syncd matching "/usr/bin/syncd" if does not exist for 5 times within 5 cycles then alert diff --git a/platform/nephos/docker-syncd-nephos/base_image_files/monit_syncd b/platform/nephos/docker-syncd-nephos/base_image_files/monit_syncd index 3f8bc50007d7..0b9ec741cd57 100644 --- a/platform/nephos/docker-syncd-nephos/base_image_files/monit_syncd +++ b/platform/nephos/docker-syncd-nephos/base_image_files/monit_syncd @@ -4,7 +4,7 @@ ## syncd ## dsserve ############################################################################### -check process syncd matching "/usr/bin/syncd --diag" +check process syncd matching "/usr/bin/syncd" if does not exist for 5 times within 5 cycles then alert check process dsserve matching "/usr/bin/dsserve /usr/bin/syncd" From 42bffc1215acaf5c79ad0547a45be36ee971a6dd Mon Sep 17 00:00:00 2001 From: Dong Zhang <41927498+dzhangalibaba@users.noreply.github.com> Date: Wed, 22 Jan 2020 11:26:23 -0800 Subject: [PATCH 030/178] [MultiDB] (except ./src and ./dockers dirs): replace redis-cli with sonic-db-cli and use new DBConnector (#4035) * [MultiDB] (except ./src and ./dockers dirs): replace redis-cli with sonic-db-cli and use new DBConnector * update comment for a potential bug * update comment * add TODO maker as review reqirement --- .../x86_64-mlnx_msn2700-r0/plugins/sfputil.py | 9 ++--- files/build_templates/docker_image_ctl.j2 | 38 ++++++++++--------- files/image_config/config-setup/config-setup | 11 +++--- files/image_config/updategraph/updategraph | 10 ++--- .../warmboot-finalizer/finalize-warmboot.sh | 10 ++--- files/scripts/configdb-load.sh | 2 +- files/scripts/swss.sh | 26 ++++++------- files/scripts/syncd.sh | 12 +++--- .../s9180-32x/utils/qsfp_monitor.sh | 2 +- .../s9280-64x/utils/qsfp_monitor.sh | 2 +- .../s8810-32q/utils/qsfp_monitor.sh | 2 +- .../s8900-54xc/utils/qsfp_monitor.sh | 2 +- .../s8900-64xc/utils/qsfp_monitor.sh | 2 +- .../s9100/utils/qsfp_monitor.sh | 2 +- .../s9200-64x/utils/qsfp_monitor.sh | 2 +- .../s9130-32x/utils/qsfp_monitor.sh | 2 +- .../s9230-64x/utils/qsfp_monitor.sh | 2 +- 17 files changed, 64 insertions(+), 72 deletions(-) diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py index e41ac2924da2..7c4f33f74973 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py @@ -22,8 +22,6 @@ SFP_I2C_PAGE_SIZE = 256 # parameters for DB connection -REDIS_HOSTNAME = "localhost" -REDIS_PORT = 6379 REDIS_TIMEOUT_USECS = 0 # parameters for SFP presence @@ -190,10 +188,9 @@ def get_transceiver_change_event(self, timeout=0): if self.db_sel == None: from swsscommon import swsscommon - self.state_db = swsscommon.DBConnector(swsscommon.STATE_DB, - REDIS_HOSTNAME, - REDIS_PORT, - REDIS_TIMEOUT_USECS) + self.state_db = swsscommon.DBConnector("STATE_DB", + REDIS_TIMEOUT_USECS, + True)) # Subscribe to state table for SFP change notifications self.db_sel = swsscommon.Select() diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index a9201b8a346d..995abce19379 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -89,20 +89,20 @@ function preStartAction() docker cp /tmp/dump.rdb database:/var/lib/redis/ fi {%- elif docker_container_name == "snmp" %} - docker exec -i database redis-cli -n 6 HSET 'DEVICE_METADATA|localhost' chassis_serial_number $(decode-syseeprom -s) - vrfenabled=`/usr/bin/redis-cli -n 4 hget "MGMT_VRF_CONFIG|vrf_global" mgmtVrfEnabled` - v1SnmpTrapIp=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v1TrapDest" DestIp` - v1SnmpTrapPort=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v1TrapDest" DestPort` - v1Vrf=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v1TrapDest" vrf` - v1Comm=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v1TrapDest" Community` - v2SnmpTrapIp=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v2TrapDest" DestIp` - v2SnmpTrapPort=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v2TrapDest" DestPort` - v2Vrf=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v2TrapDest" vrf` - v2Comm=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v2TrapDest" Community` - v3SnmpTrapIp=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v3TrapDest" DestIp` - v3SnmpTrapPort=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v3TrapDest" DestPort` - v3Vrf=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v3TrapDest" vrf` - v3Comm=`/usr/bin/redis-cli -n 4 hget "SNMP_TRAP_CONFIG|v3TrapDest" Community` + sonic-db-cli STATE_DB HSET 'DEVICE_METADATA|localhost' chassis_serial_number $(decode-syseeprom -s) + vrfenabled=`sonic-db-cli CONFIG_DB hget "MGMT_VRF_CONFIG|vrf_global" mgmtVrfEnabled` + v1SnmpTrapIp=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v1TrapDest" DestIp` + v1SnmpTrapPort=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v1TrapDest" DestPort` + v1Vrf=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v1TrapDest" vrf` + v1Comm=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v1TrapDest" Community` + v2SnmpTrapIp=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v2TrapDest" DestIp` + v2SnmpTrapPort=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v2TrapDest" DestPort` + v2Vrf=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v2TrapDest" vrf` + v2Comm=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v2TrapDest" Community` + v3SnmpTrapIp=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v3TrapDest" DestIp` + v3SnmpTrapPort=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v3TrapDest" DestPort` + v3Vrf=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v3TrapDest" vrf` + v3Comm=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v3TrapDest" Community` if [ "${v1SnmpTrapIp}" != "" ] then @@ -139,7 +139,11 @@ function preStartAction() fi echo -n "" > /tmp/snmpagentaddr.yml - keys=`/usr/bin/redis-cli -n 4 keys "SNMP_AGENT_ADDRESS_CONFIG|*"` + # TODO + # we should avoid using 'keys' operation via redis-cli or sonic-db-cli + # there would be an issue when KEY in database contains space or '\n' + # for loop on the non-tty 'keys' output will take the space or `\n` as seperator when parsing the element + keys=`sonic-db-cli CONFIG_DB keys "SNMP_AGENT_ADDRESS_CONFIG|*"` count=1 for key in $keys;do ip=`echo $key|cut -d "|" -f2` @@ -180,10 +184,10 @@ function postStartAction() if [[ "$BOOT_TYPE" == "fast" ]]; then # set the key to expire in 3 minutes - redis-cli -n 6 SET "FAST_REBOOT|system" "1" "EX" "180" + sonic-db-cli STATE_DB SET "FAST_REBOOT|system" "1" "EX" "180" fi - redis-cli -n 4 SET "CONFIG_DB_INITIALIZED" "1" + sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" fi if [[ -x /usr/bin/db_migrator.py ]]; then diff --git a/files/image_config/config-setup/config-setup b/files/image_config/config-setup/config-setup index bd497d06b257..f19abd266e95 100755 --- a/files/image_config/config-setup/config-setup +++ b/files/image_config/config-setup/config-setup @@ -25,7 +25,6 @@ ########################################################################### # Initialize constants -CONFIG_DB_INDEX=4 UPDATEGRAPH_CONF=/etc/sonic/updategraph.conf CONFIG_DB_JSON=/etc/sonic/config_db.json MINGRAPH_FILE=/etc/sonic/minigraph.xml @@ -107,9 +106,9 @@ reload_minigraph() if [ ! -f /etc/sonic/init_cfg.json ]; then echo "{}" > /etc/sonic/init_cfg.json fi - redis-cli -n $CONFIG_DB_INDEX FLUSHDB + sonic-db-cli CONFIG_DB FLUSHDB sonic-cfggen -H -m -j /etc/sonic/init_cfg.json --write-to-db - redis-cli -n $CONFIG_DB_INDEX SET "CONFIG_DB_INITIALIZED" "1" + sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" if [ -f /etc/sonic/acl.json ]; then acl-loader update full /etc/sonic/acl.json fi @@ -138,7 +137,7 @@ function copy_config_files_and_directories() # Check if SONiC swich has booted after a warm reboot request check_system_warm_boot() { - SYSTEM_WARM_START=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|system" enable` + SYSTEM_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` # SYSTEM_WARM_START could be empty, always make WARM_BOOT meaningful. if [[ x"$SYSTEM_WARM_START" == x"true" ]]; then WARM_BOOT="true" @@ -187,7 +186,7 @@ load_config() return 1 fi - redis-cli -n $CONFIG_DB_INDEX FLUSHDB + sonic-db-cli CONFIG_DB FLUSHDB sonic-cfggen -j ${CONFIG_FILE} --write-to-db if [ $? -ne 0 ]; then return $? @@ -198,7 +197,7 @@ load_config() /usr/bin/db_migrator.py -o migrate fi - redis-cli -n $CONFIG_DB_INDEX SET "CONFIG_DB_INITIALIZED" "1" + sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" return 0 } diff --git a/files/image_config/updategraph/updategraph b/files/image_config/updategraph/updategraph index b2bd027e82e7..a24d452b1ad2 100755 --- a/files/image_config/updategraph/updategraph +++ b/files/image_config/updategraph/updategraph @@ -1,16 +1,14 @@ #!/bin/bash -CONFIG_DB_INDEX=4 - reload_minigraph() { echo "Reloading minigraph..." if [ ! -f /etc/sonic/init_cfg.json ]; then echo "{}" > /etc/sonic/init_cfg.json fi - redis-cli -n $CONFIG_DB_INDEX FLUSHDB + sonic-db-cli CONFIG_DB FLUSHDB sonic-cfggen -H -m -j /etc/sonic/init_cfg.json --write-to-db - redis-cli -n $CONFIG_DB_INDEX SET "CONFIG_DB_INITIALIZED" "1" + sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" if [ -f /etc/sonic/acl.json ]; then acl-loader update full /etc/sonic/acl.json fi @@ -77,9 +75,9 @@ if [ "$src" = "dhcp" ]; then else cp -f /tmp/device_meta.json /etc/sonic/config_db.json fi - redis-cli -n $CONFIG_DB_INDEX FLUSHDB + sonic-db-cli CONFIG_DB FLUSHDB sonic-cfggen -j /etc/sonic/config_db.json --write-to-db - redis-cli -n $CONFIG_DB_INDEX SET "CONFIG_DB_INITIALIZED" "1" + sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" if [ "$dhcp_as_static" = "true" ]; then sed -i "/enabled=/d" /etc/sonic/updategraph.conf echo "enabled=false" >> /etc/sonic/updategraph.conf diff --git a/files/image_config/warmboot-finalizer/finalize-warmboot.sh b/files/image_config/warmboot-finalizer/finalize-warmboot.sh index ba473feab0ab..0f9e0f7da299 100755 --- a/files/image_config/warmboot-finalizer/finalize-warmboot.sh +++ b/files/image_config/warmboot-finalizer/finalize-warmboot.sh @@ -20,7 +20,7 @@ function debug() function check_warm_boot() { - WARM_BOOT=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|system" enable` + WARM_BOOT=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` } @@ -29,12 +29,10 @@ function wait_for_database_service() debug "Wait for database to become ready..." # Wait for redis server start before database clean - until [[ $(/usr/bin/docker exec database redis-cli ping | grep -c PONG) -gt 0 ]]; - do sleep 1; - done + /usr/bin/docker exec database ping_pong_db_insts # Wait for configDB initialization - until [[ $(/usr/bin/docker exec database redis-cli -n 4 GET "CONFIG_DB_INITIALIZED") ]]; + until [[ $(sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; do sleep 1; done @@ -44,7 +42,7 @@ function wait_for_database_service() function get_component_state() { - /usr/bin/redis-cli -n 6 hget "WARM_RESTART_TABLE|$1" state + sonic-db-cli STATE_DB hget "WARM_RESTART_TABLE|$1" state } diff --git a/files/scripts/configdb-load.sh b/files/scripts/configdb-load.sh index 5ba2e0e0bc7f..e7080eb40f3d 100755 --- a/files/scripts/configdb-load.sh +++ b/files/scripts/configdb-load.sh @@ -10,4 +10,4 @@ if [ -r /etc/sonic/config_db.json ]; then sonic-cfggen -j /etc/sonic/config_db.json --write-to-db fi -redis-cli -n 4 SET "CONFIG_DB_INITIALIZED" "1" +sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" diff --git a/files/scripts/swss.sh b/files/scripts/swss.sh index 93f311019d66..a14d03e40f50 100755 --- a/files/scripts/swss.sh +++ b/files/scripts/swss.sh @@ -31,8 +31,8 @@ function unlock_service_state_change() function check_warm_boot() { - SYSTEM_WARM_START=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|system" enable` - SERVICE_WARM_START=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` + SYSTEM_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` + SERVICE_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` if [[ x"$SYSTEM_WARM_START" == x"true" ]] || [[ x"$SERVICE_WARM_START" == x"true" ]]; then WARM_BOOT="true" else @@ -43,7 +43,7 @@ function check_warm_boot() function validate_restore_count() { if [[ x"$WARM_BOOT" == x"true" ]]; then - RESTORE_COUNT=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_TABLE|orchagent" restore_count` + RESTORE_COUNT=`sonic-db-cli STATE_DB hget "WARM_RESTART_TABLE|orchagent" restore_count` # We have to make sure db data has not been flushed. if [[ -z "$RESTORE_COUNT" ]]; then WARM_BOOT="false" @@ -54,12 +54,10 @@ function validate_restore_count() function wait_for_database_service() { # Wait for redis server start before database clean - until [[ $(/usr/bin/docker exec database redis-cli ping | grep -c PONG) -gt 0 ]]; - do sleep 1; - done + /usr/bin/docker exec database ping_pong_db_insts # Wait for configDB initialization - until [[ $(/usr/bin/docker exec database redis-cli -n 4 GET "CONFIG_DB_INITIALIZED") ]]; + until [[ $(sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; do sleep 1; done } @@ -69,7 +67,7 @@ function wait_for_database_service() # $2 the string of a list of table prefixes function clean_up_tables() { - redis-cli -n $1 EVAL " + sonic-db-cli $1 EVAL " local tables = {$2} for i = 1, table.getn(tables) do local matches = redis.call('KEYS', tables[i]) @@ -114,11 +112,11 @@ start() { # Don't flush DB during warm boot if [[ x"$WARM_BOOT" != x"true" ]]; then debug "Flushing APP, ASIC, COUNTER, CONFIG, and partial STATE databases ..." - /usr/bin/docker exec database redis-cli -n 0 FLUSHDB - /usr/bin/docker exec database redis-cli -n 1 FLUSHDB - /usr/bin/docker exec database redis-cli -n 2 FLUSHDB - /usr/bin/docker exec database redis-cli -n 5 FLUSHDB - clean_up_tables 6 "'PORT_TABLE*', 'MGMT_PORT_TABLE*', 'VLAN_TABLE*', 'VLAN_MEMBER_TABLE*', 'LAG_TABLE*', 'LAG_MEMBER_TABLE*', 'INTERFACE_TABLE*', 'MIRROR_SESSION*', 'VRF_TABLE*', 'FDB_TABLE*'" + sonic-db-cli APPL_DB FLUSHDB + sonic-db-cli ASIC_DB FLUSHDB + sonic-db-cli COUNTERS_DB FLUSHDB + sonic-db-cli FLEX_COUNTER_DB FLUSHDB + clean_up_tables STATE_DB "'PORT_TABLE*', 'MGMT_PORT_TABLE*', 'VLAN_TABLE*', 'VLAN_MEMBER_TABLE*', 'LAG_TABLE*', 'LAG_MEMBER_TABLE*', 'INTERFACE_TABLE*', 'MIRROR_SESSION*', 'VRF_TABLE*', 'FDB_TABLE*'" fi # start service docker @@ -166,7 +164,7 @@ stop() { # encountered error, e.g. syncd crashed. And swss needs to # be restarted. debug "Clearing FAST_REBOOT flag..." - clean_up_tables 6 "'FAST_REBOOT*'" + clean_up_tables STATE_DB "'FAST_REBOOT*'" # Unlock has to happen before reaching out to peer service unlock_service_state_change diff --git a/files/scripts/syncd.sh b/files/scripts/syncd.sh index 05e5552a64b1..4b47e7ad4c45 100755 --- a/files/scripts/syncd.sh +++ b/files/scripts/syncd.sh @@ -30,8 +30,8 @@ function unlock_service_state_change() function check_warm_boot() { - SYSTEM_WARM_START=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|system" enable` - SERVICE_WARM_START=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` + SYSTEM_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` + SERVICE_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` # SYSTEM_WARM_START could be empty, always make WARM_BOOT meaningful. if [[ x"$SYSTEM_WARM_START" == x"true" ]] || [[ x"$SERVICE_WARM_START" == x"true" ]]; then WARM_BOOT="true" @@ -43,12 +43,10 @@ function check_warm_boot() function wait_for_database_service() { # Wait for redis server start before database clean - until [[ $(/usr/bin/docker exec database redis-cli ping | grep -c PONG) -gt 0 ]]; - do sleep 1; - done + /usr/bin/docker exec database ping_pong_db_insts # Wait for configDB initialization - until [[ $(/usr/bin/docker exec database redis-cli -n 4 GET "CONFIG_DB_INITIALIZED") ]]; + until [[ $(sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; do sleep 1; done } @@ -65,7 +63,7 @@ function getBootType() ;; *SONIC_BOOT_TYPE=fast*|*fast-reboot*) # check that the key exists - if [[ $(redis-cli -n 6 GET "FAST_REBOOT|system") == "1" ]]; then + if [[ $(sonic-db-cli STATE_DB GET "FAST_REBOOT|system") == "1" ]]; then TYPE='fast' else TYPE='cold' diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/utils/qsfp_monitor.sh b/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/utils/qsfp_monitor.sh index 249f179216a6..7776493bc20a 100755 --- a/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/utils/qsfp_monitor.sh +++ b/platform/barefoot/sonic-platform-modules-ingrasys/s9180-32x/utils/qsfp_monitor.sh @@ -65,7 +65,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi diff --git a/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/utils/qsfp_monitor.sh b/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/utils/qsfp_monitor.sh index 23a3fd066bee..9213d115f656 100755 --- a/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/utils/qsfp_monitor.sh +++ b/platform/barefoot/sonic-platform-modules-ingrasys/s9280-64x/utils/qsfp_monitor.sh @@ -66,7 +66,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/utils/qsfp_monitor.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/utils/qsfp_monitor.sh index 249f179216a6..7776493bc20a 100755 --- a/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/utils/qsfp_monitor.sh +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8810-32q/utils/qsfp_monitor.sh @@ -65,7 +65,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/utils/qsfp_monitor.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/utils/qsfp_monitor.sh index 7f50d137bcb7..0a4ba20ab767 100644 --- a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/utils/qsfp_monitor.sh +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-54xc/utils/qsfp_monitor.sh @@ -67,7 +67,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/utils/qsfp_monitor.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/utils/qsfp_monitor.sh index 36f9e53ef108..b3192f2efb7a 100644 --- a/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/utils/qsfp_monitor.sh +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s8900-64xc/utils/qsfp_monitor.sh @@ -67,7 +67,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s9100/utils/qsfp_monitor.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s9100/utils/qsfp_monitor.sh index 249f179216a6..7776493bc20a 100755 --- a/platform/broadcom/sonic-platform-modules-ingrasys/s9100/utils/qsfp_monitor.sh +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s9100/utils/qsfp_monitor.sh @@ -65,7 +65,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi diff --git a/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/utils/qsfp_monitor.sh b/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/utils/qsfp_monitor.sh index 51c49c1152f5..47cfbb3ea008 100755 --- a/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/utils/qsfp_monitor.sh +++ b/platform/broadcom/sonic-platform-modules-ingrasys/s9200-64x/utils/qsfp_monitor.sh @@ -66,7 +66,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi diff --git a/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/utils/qsfp_monitor.sh b/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/utils/qsfp_monitor.sh index 249f179216a6..7776493bc20a 100755 --- a/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/utils/qsfp_monitor.sh +++ b/platform/nephos/sonic-platform-modules-ingrasys/s9130-32x/utils/qsfp_monitor.sh @@ -65,7 +65,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi diff --git a/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/utils/qsfp_monitor.sh b/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/utils/qsfp_monitor.sh index 23a3fd066bee..9213d115f656 100755 --- a/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/utils/qsfp_monitor.sh +++ b/platform/nephos/sonic-platform-modules-ingrasys/s9230-64x/utils/qsfp_monitor.sh @@ -66,7 +66,7 @@ function _docker_swss_check { while true do # Check if syncd starts - result=`docker exec -i swss bash -c "echo -en \"SELECT 1\\nHLEN HIDDEN\" | redis-cli | sed -n 2p"` #TBD FIX ME + result=`sonic-db-cli ASIC_DB HLEN HIDDEN` if [ "$result" == "3" ]; then return fi From e32d22c0b939bbdf45bbcf26bc5ae4652dc7acff Mon Sep 17 00:00:00 2001 From: paavaanan Date: Thu, 23 Jan 2020 22:57:41 +0530 Subject: [PATCH 031/178] [devices]: DellEMC S6000 fancontrol support (#4048) - Implemented fancontrol service to monitor S6000 fans and adjust fan speed w.r.t temperature. - fancontrol.service starts the fancontrol script at startup. - This script takes the average temperature by reading three sensors and configure FANS to appropritate RPM against the temperature. - When the temperature is adjusted script will log in syslog for future reference. - Also, script checks for faulty fans and report the status in syslog. --- .../debian/platform-modules-s6000.install | 2 + .../debian/platform-modules-s6000.postinst | 5 + .../s6000/scripts/fancontrol.sh | 189 ++++++++++++++++++ .../s6000/systemd/fancontrol.service | 13 ++ 4 files changed, 209 insertions(+) create mode 100755 platform/broadcom/sonic-platform-modules-dell/s6000/scripts/fancontrol.sh create mode 100644 platform/broadcom/sonic-platform-modules-dell/s6000/systemd/fancontrol.service diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6000.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6000.install index c2dcb5dc03a9..f662e751a3f8 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6000.install +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6000.install @@ -1,6 +1,8 @@ s6000/scripts/s6000_platform.sh usr/local/bin s6000/scripts/reset-qsfp usr/local/bin s6000/scripts/set-fan-speed usr/local/bin +s6000/scripts/fancontrol.sh usr/local/bin s6000/systemd/platform-modules-s6000.service etc/systemd/system +s6000/systemd/fancontrol.service etc/systemd/system common/io_rd_wr.py usr/local/bin s6000/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-dell_s6000_s1220-r0 diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6000.postinst b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6000.postinst index a9b90fa86f3a..052e5a6f574e 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6000.postinst +++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6000.postinst @@ -4,4 +4,9 @@ depmod -a systemctl enable platform-modules-s6000.service systemctl start platform-modules-s6000.service + +systemctl enable fancontrol.service +systemctl start fancontrol.service + + #DEBHELPER# diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/scripts/fancontrol.sh b/platform/broadcom/sonic-platform-modules-dell/s6000/scripts/fancontrol.sh new file mode 100755 index 000000000000..43315e06c930 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/scripts/fancontrol.sh @@ -0,0 +1,189 @@ +#!/bin/bash + +LEVEL=99 +INTERVAL=5 +FAULTY_FANTRAY1=1 +FAULTY_FANTRAY2=1 +FAULTY_FANTRAY3=1 + +# FAN RPM Speed +IDLE=7000 +LEVEL1=10000 +LEVEL2=13000 +LEVEL3=16000 +LEVEL4=19000 +LEVEL5=19000 + +I2C_ADAPTER="/sys/class/i2c-adapter/i2c-2/i2c-11" +SENSOR1="$I2C_ADAPTER/11-004c/hwmon/hwmon*/temp1_input" +SENSOR2="$I2C_ADAPTER/11-004d/hwmon/hwmon*/temp1_input" +SENSOR3="$I2C_ADAPTER/11-004e/hwmon/hwmon*/temp1_input" + +# Three fan trays with each contains two separate fans +# fan1-fan4 fan2-fan5 fan3-fan6 +FANTRAY1_FAN1=$I2C_ADAPTER/11-0029/fan1_target +FANTRAY1_FAN2=$I2C_ADAPTER/11-0029/fan2_target +FANTRAY2_FAN1=$I2C_ADAPTER/11-0029/fan3_target +FANTRAY2_FAN2=$I2C_ADAPTER/11-0029/fan4_target +FANTRAY3_FAN1=$I2C_ADAPTER/11-002a/fan1_target +FANTRAY3_FAN2=$I2C_ADAPTER/11-002a/fan2_target + +FANTRAY1_FAN1_RPM=$I2C_ADAPTER/11-0029/fan1_input +FANTRAY1_FAN2_RPM=$I2C_ADAPTER/11-0029/fan2_input +FANTRAY2_FAN1_RPM=$I2C_ADAPTER/11-0029/fan3_input +FANTRAY2_FAN2_RPM=$I2C_ADAPTER/11-0029/fan4_input +FANTRAY3_FAN1_RPM=$I2C_ADAPTER/11-002a/fan1_input +FANTRAY3_FAN2_RPM=$I2C_ADAPTER/11-002a/fan2_input + +function check_module +{ + MODULE=$1 + lsmod | grep "$MODULE" > /dev/null + ret=$? + if [[ $ret = "1" ]]; then + echo "$MODULE is not loaded!" + exit 1 + fi +} + +function check_faulty_fan +{ + + # Assume fans in FanTray spins less than 1000 RPM is faulty. + # To Maintain temperature assign max speed 16200 RPM to all other fans. + # This RPM speed handle temperature upto 75C degrees + + fan1=$(cat $FANTRAY1_FAN1_RPM) + fan2=$(cat $FANTRAY1_FAN2_RPM) + fan3=$(cat $FANTRAY2_FAN1_RPM) + fan4=$(cat $FANTRAY2_FAN2_RPM) + fan5=$(cat $FANTRAY3_FAN1_RPM) + fan6=$(cat $FANTRAY3_FAN2_RPM) + + # FanTray1 + if [ "$fan1" -le "1000" ] || [ "$fan2" -le "1000" ]; then + + # First time detecting failure + if [ $FAULTY_FANTRAY1 -lt "2" ]; then + FAULTY_FANTRAY1=2 + /usr/local/bin/set-fan-speed 16200 2 > /dev/null + logger "Faulty Fans in Fantray1 $fan1 $fan2 Please check." + fi + + elif [ "$fan1" -ge "1000" ] || [ "$fan2" -ge "1000" ]; then + FAULTY_FANTRAY1=0 + fi + + + # FanTray2 + if [ "$fan3" -le "1000" ] || [ "$fan4" -le "1000" ]; then + + # First time detecting failure + if [ $FAULTY_FANTRAY2 -lt "2" ]; then + + FAULTY_FANTRAY2=2 + /usr/local/bin/set-fan-speed 16200 2 > /dev/null + logger "Faulty Fans in FanTray2: $fan3 $fan4. Please check." + fi + + elif [ "$fan3" -ge "1000" ] || [ "$fan4" -ge "1000" ]; then + FAULTY_FANTRAY2=0 + fi + + # FanTray3 + if [ "$fan5" -le "1000" ] || [ "$fan6" -le "1000" ]; then + + # First time detecting failure + if [ $FAULTY_FANTRAY3 -lt "2" ]; then + + FAULTY_FANTRAY3=2 + /usr/local/bin/set-fan-speed 16200 2 > /dev/null + logger "FanTray3 Fans are Faulty.. $fan5 $fan6. Please check." + fi + + elif [ "$fan5" -ge "1000" ] || [ "$fan6" -ge "1000" ]; then + + FAULTY_FANTRAY3=0 + fi + +} + +function update_fan_speed +{ + local fan_speed=$1 + + echo $fan_speed > $FANTRAY1_FAN1 + echo $fan_speed > $FANTRAY1_FAN2 + echo $fan_speed > $FANTRAY2_FAN1 + echo $fan_speed > $FANTRAY2_FAN2 + echo $fan_speed > $FANTRAY3_FAN1 + echo $fan_speed > $FANTRAY3_FAN2 + +} + +function monitor_temp_sensors +{ + + while true # go through all temp sensor outputs + do + sensor1=$(expr `echo $(cat $SENSOR1)` / 1000) + sensor2=$(expr `echo $(cat $SENSOR2)` / 1000) + sensor3=$(expr `echo $(cat $SENSOR3)` / 1000) + sum=$(($sensor1 + $sensor2 + $sensor3)) + sensor_temp=$(($sum/3)) + + if [ "$sensor_temp" -le "25" ] && [ "$LEVEL" -ne "0" ] + then + # Set Fan Speed to 7000 RPM" + LEVEL=0 + update_fan_speed $IDLE + logger "Adjusted FAN Speed to $IDLE RPM against $sensor_temp Temperature" + + elif [ "$sensor_temp" -ge "26" ] && [ "$sensor_temp" -le "44" ] && [ "$LEVEL" -ne "1" ] + then + # Set Fan Speed to 10000 RPM" + LEVEL=1 + update_fan_speed $LEVEL1 + logger "Adjusted FAN Speed to $IDLE RPM against $sensor_temp Temperature" + + elif [ "$sensor_temp" -ge "45" ] && [ "$sensor_temp" -le "59" ] && [ "$LEVEL" -ne "2" ] + then + # Set Fan Speed to 13000 RPM" + LEVEL=2 + update_fan_speed $LEVEL2 + logger "Adjusted FAN Speed to $IDLE RPM against $sensor_temp Temperature" + + elif [ "$sensor_temp" -ge "60" ] && [ "$sensor_temp" -le "79" ] && [ "$LEVEL" -ne "3" ] + then + # Set Fan Speed to 16000 RPM" + LEVEL=3 + update_fan_speed $LEVEL3 + logger "Adjusted FAN Speed to $IDLE RPM against $sensor_temp Temperature" + + elif [ "$sensor_temp" -ge "80" ] && [ "$LEVEL" -ne "4" ] + then + # Set Fan Speed to 19000 RPM" + LEVEL=4 + update_fan_speed $LEVEL4 + logger "Adjusted FAN Speed to $IDLE RPM against $sensor_temp Temperature" + fi + + # Check for faulty fan + check_faulty_fan + + done + +} + +# Check drivers for sysfs attributes +check_module "dell_s6000_platform" +check_module "max6620" + +# main loop calling the main function at specified intervals +while true +do + monitor_temp_sensors + # Sleep while still handling signals + sleep $INTERVAL & + wait +done diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/systemd/fancontrol.service b/platform/broadcom/sonic-platform-modules-dell/s6000/systemd/fancontrol.service new file mode 100644 index 000000000000..75cc977b9935 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/systemd/fancontrol.service @@ -0,0 +1,13 @@ +[Unit] +Description=Dell S6000 fan speed regulator +After=platform-modules-s6000.service +Before=pmon.service + +[Service] +ExecStart=-/usr/local/bin/fancontrol.sh +Restart=always +RestartSec=30 + +[Install] +WantedBy=multi-user.target + From 8e4a4caf79c651616755f621a4a4eea5d6b6189f Mon Sep 17 00:00:00 2001 From: pra-moh <49077256+pra-moh@users.noreply.github.com> Date: Thu, 23 Jan 2020 17:49:41 -0800 Subject: [PATCH 032/178] [baseimage]: removing space from shebang in procdockerstatsd (#4051) --- files/image_config/procdockerstatsd/procdockerstatsd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/image_config/procdockerstatsd/procdockerstatsd b/files/image_config/procdockerstatsd/procdockerstatsd index 66d2d45009d5..a7bdcd6e6ce6 100644 --- a/files/image_config/procdockerstatsd/procdockerstatsd +++ b/files/image_config/procdockerstatsd/procdockerstatsd @@ -1,4 +1,4 @@ -# !/usr/bin/env python +#!/usr/bin/env python ''' procdockerstatsd Daemon which periodically gathers process and docker statistics and pushes the data to STATE_DB From a836ead68819866f800febb044c86a33dd96fcc1 Mon Sep 17 00:00:00 2001 From: kannankvs Date: Wed, 29 Jan 2020 07:11:21 +0530 Subject: [PATCH 033/178] =?UTF-8?q?mvrf=5Favoid=5Fsnmp=5Fyml=5Fconfig:=20m?= =?UTF-8?q?ade=20changes=20to=20pass=20SNMP=20config=20from=20con=E2=80=A6?= =?UTF-8?q?=20(#4057)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * mvrf_avoid_snmp_yml_config: made changes to pass SNMP config from confiDB to snmpd.conf without using snmp.yml * added a missing if condition --- dockers/docker-snmp-sv2/snmpd.conf.j2 | 38 +++++++----- files/build_templates/docker_image_ctl.j2 | 71 ----------------------- files/image_config/snmp/snmp.yml | 3 - 3 files changed, 22 insertions(+), 90 deletions(-) diff --git a/dockers/docker-snmp-sv2/snmpd.conf.j2 b/dockers/docker-snmp-sv2/snmpd.conf.j2 index 16d7e5bff79c..7d4022501fbb 100644 --- a/dockers/docker-snmp-sv2/snmpd.conf.j2 +++ b/dockers/docker-snmp-sv2/snmpd.conf.j2 @@ -15,16 +15,10 @@ # Listen for connections on all ip addresses, including eth0, ipv4 lo # -{% if snmp_agent_address_1 or snmp_agent_address_2 or snmp_agent_address_3 %} -{% if snmp_agent_address_1 %} -agentAddress {{ snmp_agent_address_1 }} -{% endif %} -{% if snmp_agent_address_2 %} -agentAddress {{ snmp_agent_address_2 }} -{% endif %} -{% if snmp_agent_address_3 %} -agentAddress {{ snmp_agent_address_3 }} -{% endif %} +{% if SNMP_AGENT_ADDRESS_CONFIG %} +{% for (agentip, port, vrf) in SNMP_AGENT_ADDRESS_CONFIG %} +agentAddress {{ agentip }}{% if port %}:{{ port }}{% endif %}{% if vrf %}%{{ vrf }}{% endif %}{{ "" }} +{% endfor %} {% else %} agentAddress udp:161 agentAddress udp6:161 @@ -105,20 +99,32 @@ load 12 10 5 # Note: disabled snmp traps due to side effect of causing snmpd to listen on all ports (0.0.0.0) # # send SNMPv1 traps -{%if v1_trap_dest and v1_trap_dest != 'NotConfigured' %} -trapsink {{ v1_trap_dest }} +{% if SNMP_TRAP_CONFIG and SNMP_TRAP_CONFIG['v1TrapDest'] %} +{% set v1SnmpTrapIp = SNMP_TRAP_CONFIG['v1TrapDest']['DestIp'] %} +{% set v1SnmpTrapPort = SNMP_TRAP_CONFIG['v1TrapDest']['DestPort'] %} +{% set v1SnmpTrapVrf = SNMP_TRAP_CONFIG['v1TrapDest']['vrf'] %} +{% set v1SnmpTrapComm = SNMP_TRAP_CONFIG['v1TrapDest']['Community'] %} +trapsink {{ v1SnmpTrapIp }}:{{ v1SnmpTrapPort }}{% if v1SnmpTrapVrf != 'None' %}%{{ v1SnmpTrapVrf }}{% endif %} {{ v1SnmpTrapComm }}{{ "" }} {% else %} #trapsink localhost public {% endif %} # send SNMPv2c traps -{%if v2_trap_dest and v2_trap_dest != 'NotConfigured' %} -trap2sink {{ v2_trap_dest }} +{% if SNMP_TRAP_CONFIG and SNMP_TRAP_CONFIG['v2TrapDest'] %} +{% set v2SnmpTrapIp = SNMP_TRAP_CONFIG['v2TrapDest']['DestIp'] %} +{% set v2SnmpTrapPort = SNMP_TRAP_CONFIG['v2TrapDest']['DestPort'] %} +{% set v2SnmpTrapVrf = SNMP_TRAP_CONFIG['v2TrapDest']['vrf'] %} +{% set v2SnmpTrapComm = SNMP_TRAP_CONFIG['v2TrapDest']['Community'] %} +trap2sink {{ v2SnmpTrapIp }}:{{ v2SnmpTrapPort }}{% if v2SnmpTrapVrf != 'None' %}%{{ v2SnmpTrapVrf }}{% endif %} {{ v2SnmpTrapComm }}{{ "" }} {% else %} #trap2sink localhost public {% endif %} # send SNMPv2c INFORMs -{%if v3_trap_dest and v3_trap_dest != 'NotConfigured' %} -informsink {{ v3_trap_dest }} +{% if SNMP_TRAP_CONFIG and SNMP_TRAP_CONFIG['v3TrapDest'] %} +{% set v3SnmpTrapIp = SNMP_TRAP_CONFIG['v3TrapDest']['DestIp'] %} +{% set v3SnmpTrapPort = SNMP_TRAP_CONFIG['v3TrapDest']['DestPort'] %} +{% set v3SnmpTrapVrf = SNMP_TRAP_CONFIG['v3TrapDest']['vrf'] %} +{% set v3SnmpTrapComm = SNMP_TRAP_CONFIG['v3TrapDest']['Community'] %} +trapsink {{ v3SnmpTrapIp }}:{{ v3SnmpTrapPort }}{% if v3SnmpTrapVrf != 'None' %}%{{ v3SnmpTrapVrf }}{% endif %} {{ v3SnmpTrapComm }}{{ "" }} {% else %} #informsink localhost public {% endif %} diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 995abce19379..2777a26c8edf 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -90,77 +90,6 @@ function preStartAction() fi {%- elif docker_container_name == "snmp" %} sonic-db-cli STATE_DB HSET 'DEVICE_METADATA|localhost' chassis_serial_number $(decode-syseeprom -s) - vrfenabled=`sonic-db-cli CONFIG_DB hget "MGMT_VRF_CONFIG|vrf_global" mgmtVrfEnabled` - v1SnmpTrapIp=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v1TrapDest" DestIp` - v1SnmpTrapPort=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v1TrapDest" DestPort` - v1Vrf=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v1TrapDest" vrf` - v1Comm=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v1TrapDest" Community` - v2SnmpTrapIp=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v2TrapDest" DestIp` - v2SnmpTrapPort=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v2TrapDest" DestPort` - v2Vrf=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v2TrapDest" vrf` - v2Comm=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v2TrapDest" Community` - v3SnmpTrapIp=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v3TrapDest" DestIp` - v3SnmpTrapPort=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v3TrapDest" DestPort` - v3Vrf=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v3TrapDest" vrf` - v3Comm=`sonic-db-cli CONFIG_DB hget "SNMP_TRAP_CONFIG|v3TrapDest" Community` - - if [ "${v1SnmpTrapIp}" != "" ] - then - if [ "${v1Vrf}" != "None" ] - then - sed -i "s/v1_trap_dest:.*/v1_trap_dest: ${v1SnmpTrapIp}:${v1SnmpTrapPort}%${v1Vrf} ${v1Comm}/" "/etc/sonic/snmp.yml" - else - sed -i "s/v1_trap_dest:.*/v1_trap_dest: ${v1SnmpTrapIp}:${v1SnmpTrapPort} ${v1Comm}/" "/etc/sonic/snmp.yml" - fi - else - sed -i "s/v1_trap_dest:.*/v1_trap_dest: NotConfigured/" "/etc/sonic/snmp.yml" - fi - if [ "${v2SnmpTrapIp}" != "" ] - then - if [ "${v2Vrf}" != "None" ] - then - sed -i "s/v2_trap_dest:.*/v2_trap_dest: ${v2SnmpTrapIp}:${v2SnmpTrapPort}%${v2Vrf} ${v2Comm}/" "/etc/sonic/snmp.yml" - else - sed -i "s/v2_trap_dest:.*/v2_trap_dest: ${v2SnmpTrapIp}:${v2SnmpTrapPort} ${v2Comm}/" "/etc/sonic/snmp.yml" - fi - else - sed -i "s/v2_trap_dest:.*/v2_trap_dest: NotConfigured/" "/etc/sonic/snmp.yml" - fi - if [ "${v3SnmpTrapIp}" != "" ] - then - if [ "${v3Vrf}" != "None" ] - then - sed -i "s/v3_trap_dest:.*/v3_trap_dest: ${v3SnmpTrapIp}:${v3SnmpTrapPort}%${v3Vrf} ${v3Comm}/" "/etc/sonic/snmp.yml" - else - sed -i "s/v3_trap_dest:.*/v3_trap_dest: ${v3SnmpTrapIp}:${v3SnmpTrapPort} ${v3Comm}/" "/etc/sonic/snmp.yml" - fi - else - sed -i "s/v3_trap_dest:.*/v3_trap_dest: NotConfigured/" "/etc/sonic/snmp.yml" - fi - - echo -n "" > /tmp/snmpagentaddr.yml - # TODO - # we should avoid using 'keys' operation via redis-cli or sonic-db-cli - # there would be an issue when KEY in database contains space or '\n' - # for loop on the non-tty 'keys' output will take the space or `\n` as seperator when parsing the element - keys=`sonic-db-cli CONFIG_DB keys "SNMP_AGENT_ADDRESS_CONFIG|*"` - count=1 - for key in $keys;do - ip=`echo $key|cut -d "|" -f2` - echo -n "snmp_agent_address_$count: $ip" >> /tmp/snmpagentaddr.yml - port=`echo $key|cut -d "|" -f3` - if [ -n "$port" ]; then - echo -n ":$port" >> /tmp/snmpagentaddr.yml - fi - vrf=`echo $key|cut -d "|" -f4` - if [ -n "$vrf" ]; then - echo -n "%$vrf" >> /tmp/snmpagentaddr.yml - fi - echo "" >> /tmp/snmpagentaddr.yml - count=$((count+1)) - done - sed -i '/snmp_agent_address_*/d' /etc/sonic/snmp.yml - cat /tmp/snmpagentaddr.yml >> /etc/sonic/snmp.yml {%- else %} : # nothing {%- endif %} diff --git a/files/image_config/snmp/snmp.yml b/files/image_config/snmp/snmp.yml index b200670f0d94..117619975fbb 100644 --- a/files/image_config/snmp/snmp.yml +++ b/files/image_config/snmp/snmp.yml @@ -1,5 +1,2 @@ snmp_rocommunity: public snmp_location: public -v1_trap_dest: NotConfigured -v2_trap_dest: NotConfigured -v3_trap_dest: NotConfigured From a4ca818ca991436fe86945c55411bcb8bc273109 Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Fri, 31 Jan 2020 04:54:09 +0200 Subject: [PATCH 034/178] [mellanox]: Add new Mellanox-SN3800-D112C8 sku. (#4085) Signed-off-by: Nazarii Hnydyn --- .../x86_64-mlnx_msn2700-r0/plugins/sfputil.py | 2 +- .../Mellanox-SN3800-D112C8/buffers.json.j2 | 1 + .../buffers_defaults_t0.j2 | 1 + .../buffers_defaults_t1.j2 | 1 + .../pg_profile_lookup.ini | 1 + .../Mellanox-SN3800-D112C8/port_config.ini | 105 ++++++++++++++++++ .../Mellanox-SN3800-D112C8/qos.json.j2 | 1 + .../Mellanox-SN3800-D112C8/sai.profile | 1 + .../Mellanox-SN3800-D112C8/sai_3800.xml | 1 + .../sonic_platform/chassis.py | 2 +- .../mlnx-platform-api/sonic_platform/psu.py | 2 +- .../sonic_platform/thermal.py | 2 +- 12 files changed, 116 insertions(+), 4 deletions(-) create mode 120000 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers.json.j2 create mode 120000 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t0.j2 create mode 120000 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t1.j2 create mode 120000 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/pg_profile_lookup.ini create mode 100644 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/port_config.ini create mode 120000 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/qos.json.j2 create mode 100644 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai.profile create mode 120000 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai_3800.xml diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py index 7c4f33f74973..40734349a230 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py @@ -41,7 +41,7 @@ # magic code defnition for port number, qsfp port position of each hwsku # port_position_tuple = (PORT_START, QSFP_PORT_START, PORT_END, PORT_IN_BLOCK, EEPROM_OFFSET) -hwsku_dict = {'ACS-MSN2700': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, "LS-SN2700":0, 'ACS-MSN2740': 0, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 3, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'ACS-MSN3800': 4} +hwsku_dict = {'ACS-MSN2700': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, "LS-SN2700":0, 'ACS-MSN2740': 0, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 3, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'ACS-MSN3800': 4, 'Mellanox-SN3800-D112C8': 4} port_position_tuple_list = [(0, 0, 31, 32, 1), (0, 0, 15, 16, 1), (0, 48, 55, 56, 1), (0, 18, 21, 22, 1), (0, 0, 63, 64, 1)] def log_info(msg, also_print_to_console=False): diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers.json.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers.json.j2 new file mode 120000 index 000000000000..add8bf8bb7c2 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t0.j2 new file mode 120000 index 000000000000..85f0b6b6b354 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t0.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t0.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t1.j2 new file mode 120000 index 000000000000..3bb496a5103b --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t1.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t1.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/pg_profile_lookup.ini new file mode 120000 index 000000000000..252ae8d4149b --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/pg_profile_lookup.ini @@ -0,0 +1 @@ +../../x86_64-mlnx_msn3700-r0/ACS-MSN3700/pg_profile_lookup.ini \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/port_config.ini b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/port_config.ini new file mode 100644 index 000000000000..9559119c7e38 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/port_config.ini @@ -0,0 +1,105 @@ +# name lanes alias index speed fec +Ethernet0 0,1 etp1a 0 50000 none +Ethernet2 2,3 etp1b 0 50000 none +Ethernet4 4,5 etp2a 1 50000 none +Ethernet6 6,7 etp2b 1 50000 none +Ethernet8 8,9 etp3a 2 50000 none +Ethernet10 10,11 etp3b 2 50000 none +Ethernet12 12,13,14,15 etp4 3 50000 none +Ethernet16 16,17 etp5a 4 50000 none +Ethernet18 18,19 etp5b 4 50000 none +Ethernet20 20,21 etp6a 5 50000 none +Ethernet22 22,23 etp6b 5 50000 none +Ethernet24 24,25 etp7a 6 50000 none +Ethernet26 26,27 etp7b 6 50000 none +Ethernet28 28,29,30,31 etp8 7 50000 none +Ethernet32 32,33 etp9a 8 50000 none +Ethernet34 34,35 etp9b 8 50000 none +Ethernet36 36,37 etp10a 9 50000 none +Ethernet38 38,39 etp10b 9 50000 none +Ethernet40 40,41 etp11a 10 50000 none +Ethernet42 42,43 etp11b 10 50000 none +Ethernet44 44,45,46,47 etp12 11 50000 none +Ethernet48 48,49 etp13a 12 50000 none +Ethernet50 50,51 etp13b 12 50000 none +Ethernet52 52,53 etp14a 13 50000 none +Ethernet54 54,55 etp14b 13 50000 none +Ethernet56 56,57 etp15a 14 50000 none +Ethernet58 58,59 etp15b 14 50000 none +Ethernet60 60,61,62,63 etp16 15 50000 none +Ethernet64 64,65 etp17a 16 50000 none +Ethernet66 66,67 etp17b 16 50000 none +Ethernet68 68,69 etp18a 17 50000 none +Ethernet70 70,71 etp18b 17 50000 none +Ethernet72 72,73 etp19a 18 50000 none +Ethernet74 74,75 etp19b 18 50000 none +Ethernet76 76,77,78,79 etp20 19 50000 none +Ethernet80 80,81 etp21a 20 50000 none +Ethernet82 82,83 etp21b 20 50000 none +Ethernet84 84,85 etp22a 21 50000 none +Ethernet86 86,87 etp22b 21 50000 none +Ethernet88 88,89 etp23a 22 50000 none +Ethernet90 90,91 etp23b 22 50000 none +Ethernet92 92,93,94,95 etp24 23 50000 none +Ethernet96 96,97,98,99 etp25 24 100000 rs +Ethernet100 100,101,102,103 etp26 25 100000 rs +Ethernet104 104,105 etp27a 26 50000 none +Ethernet106 106,107 etp27b 26 50000 none +Ethernet108 108,109,110,111 etp28 27 50000 none +Ethernet112 112,113,114,115 etp29 28 100000 rs +Ethernet116 116,117,118,119 etp30 29 100000 rs +Ethernet120 120,121 etp31a 30 50000 none +Ethernet122 122,123 etp31b 30 50000 none +Ethernet124 124,125,126,127 etp32 31 50000 none +Ethernet128 128,129,130,131 etp33 32 100000 rs +Ethernet132 132,133,134,135 etp34 33 100000 rs +Ethernet136 136,137 etp35a 34 50000 none +Ethernet138 138,139 etp35b 34 50000 none +Ethernet140 140,141,142,143 etp36 35 50000 none +Ethernet144 144,145,146,147 etp37 36 100000 rs +Ethernet148 148,149,150,151 etp38 37 100000 rs +Ethernet152 152,153 etp39a 38 50000 none +Ethernet154 154,155 etp39b 38 50000 none +Ethernet156 156,157,158,159 etp40 39 50000 none +Ethernet160 160,161 etp41a 40 50000 none +Ethernet162 162,163 etp41b 40 50000 none +Ethernet164 164,165 etp42a 41 50000 none +Ethernet166 166,167 etp42b 41 50000 none +Ethernet168 168,169 etp43a 42 50000 none +Ethernet170 170,171 etp43b 42 50000 none +Ethernet172 172,173,174,175 etp44 43 50000 none +Ethernet176 176,177 etp45a 44 50000 none +Ethernet178 178,179 etp45b 44 50000 none +Ethernet180 180,181 etp46a 45 50000 none +Ethernet182 182,183 etp46b 45 50000 none +Ethernet184 184,185 etp47a 46 50000 none +Ethernet186 186,187 etp47b 46 50000 none +Ethernet188 188,189,190,191 etp48 47 50000 none +Ethernet192 192,193 etp49a 48 50000 none +Ethernet194 194,195 etp49b 48 50000 none +Ethernet196 196,197 etp50a 49 50000 none +Ethernet198 198,199 etp50b 49 50000 none +Ethernet200 200,201 etp51a 50 50000 none +Ethernet202 202,203 etp51b 50 50000 none +Ethernet204 204,205,206,207 etp52 51 50000 none +Ethernet208 208,209 etp53a 52 50000 none +Ethernet210 210,211 etp53b 52 50000 none +Ethernet212 212,213 etp54a 53 50000 none +Ethernet214 214,215 etp54b 53 50000 none +Ethernet216 216,217 etp55a 54 50000 none +Ethernet218 218,219 etp55b 54 50000 none +Ethernet220 220,221,222,223 etp56 55 50000 none +Ethernet224 224,225 etp57a 56 50000 none +Ethernet226 226,227 etp57b 56 50000 none +Ethernet228 228,229 etp58a 57 50000 none +Ethernet230 230,231 etp58b 57 50000 none +Ethernet232 232,233 etp59a 58 50000 none +Ethernet234 234,235 etp59b 58 50000 none +Ethernet236 236,237,238,239 etp60 59 50000 none +Ethernet240 240,241 etp61a 60 50000 none +Ethernet242 242,243 etp61b 60 50000 none +Ethernet244 244,245 etp62a 61 50000 none +Ethernet246 246,247 etp62b 61 50000 none +Ethernet248 248,249 etp63a 62 50000 none +Ethernet250 250,251 etp63b 62 50000 none +Ethernet252 252,253,254,255 etp64 63 50000 none diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/qos.json.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/qos.json.j2 new file mode 120000 index 000000000000..eccf286dc879 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/qos.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/qos.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai.profile b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai.profile new file mode 100644 index 000000000000..367f6c4e99c0 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/sai_3800.xml diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai_3800.xml b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai_3800.xml new file mode 120000 index 000000000000..686d6298865c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai_3800.xml @@ -0,0 +1 @@ +../ACS-MSN3800/sai_3800.xml \ No newline at end of file diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index 44ef8981281f..63d432eb0b89 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -43,7 +43,7 @@ # magic code defnition for port number, qsfp port position of each hwsku # port_position_tuple = (PORT_START, QSFP_PORT_START, PORT_END, PORT_IN_BLOCK, EEPROM_OFFSET) -hwsku_dict_port = {'ACS-MSN2010': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2700': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'LS-SN2700':0, 'ACS-MSN2740': 0, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'ACS-MSN3800': 4} +hwsku_dict_port = {'ACS-MSN2010': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2700': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'LS-SN2700':0, 'ACS-MSN2740': 0, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'ACS-MSN3800': 4, 'Mellanox-SN3800-D112C8': 4} port_position_tuple_list = [(0, 0, 31, 32, 1), (0, 0, 15, 16, 1), (0, 48, 55, 56, 1), (0, 18, 21, 22, 1), (0, 0, 63, 64, 1)] class Chassis(ChassisBase): diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py index 0789f67e4f09..87d6024f7d8b 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py @@ -32,7 +32,7 @@ # in most SKUs the file psuX_curr, psuX_volt and psuX_power contain current, voltage and power data respectively. # but there are exceptions which will be handled by the following dictionary -hwsku_dict_psu = {'ACS-MSN3700': 1, 'ACS-MSN3700C': 1, 'ACS-MSN3800': 1} +hwsku_dict_psu = {'ACS-MSN3700': 1, 'ACS-MSN3700C': 1, 'ACS-MSN3800': 1, 'Mellanox-SN3800-D112C8': 1} psu_profile_list = [ # default filename convention { diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py index 6862b3fb258b..74d61220738f 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py @@ -106,7 +106,7 @@ THERMAL_API_GET_HIGH_THRESHOLD ] -hwsku_dict_thermal = {'ACS-MSN2700': 0, 'LS-SN2700':0, 'ACS-MSN2740': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 4, 'ACS-MSN3700': 5, 'ACS-MSN3700C': 6, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'ACS-MSN3800': 7} +hwsku_dict_thermal = {'ACS-MSN2700': 0, 'LS-SN2700':0, 'ACS-MSN2740': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 4, 'ACS-MSN3700': 5, 'ACS-MSN3700C': 6, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'ACS-MSN3800': 7, 'Mellanox-SN3800-D112C8': 7} thermal_profile_list = [ # 2700 { From 45c40005c247a952e5f2438ec97bf2f0b2d04406 Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Sat, 1 Feb 2020 00:30:00 -0800 Subject: [PATCH 035/178] Revert "Disable SNMPv1 (#2156)" (#4088) --- .../0004-Disable-SNMPv1.patch | 25 ------------------- src/snmpd/patch-5.7.3+dfsg/series | 1 - 2 files changed, 26 deletions(-) delete mode 100644 src/snmpd/patch-5.7.3+dfsg/0004-Disable-SNMPv1.patch diff --git a/src/snmpd/patch-5.7.3+dfsg/0004-Disable-SNMPv1.patch b/src/snmpd/patch-5.7.3+dfsg/0004-Disable-SNMPv1.patch deleted file mode 100644 index 6782a18c7758..000000000000 --- a/src/snmpd/patch-5.7.3+dfsg/0004-Disable-SNMPv1.patch +++ /dev/null @@ -1,25 +0,0 @@ -From db633987abf1ea093cb1785b3cd37adfdb55e4cc Mon Sep 17 00:00:00 2001 -From: Qi Luo -Date: Mon, 15 Oct 2018 22:30:28 +0000 -Subject: [PATCH] Disable SNMPv1 - -Signed-off-by: Qi Luo ---- - debian/rules | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/debian/rules b/debian/rules -index 9eb8d2d..4c3b5b6 100755 ---- a/debian/rules -+++ b/debian/rules -@@ -42,6 +42,7 @@ endif - override_dh_auto_configure: - dh_auto_configure -- --prefix=/usr --sysconfdir=/etc --mandir=/usr/share/man \ - --with-persistent-directory=/var/lib/snmp \ -+ --disable-snmpv1 \ - --enable-ucd-snmp-compatibility \ - --enable-shared --with-cflags="$(CFLAGS) -DNETSNMP_USE_INLINE" \ - --with-ldflags="$(LDFLAGS)" \ --- -2.18.0 - diff --git a/src/snmpd/patch-5.7.3+dfsg/series b/src/snmpd/patch-5.7.3+dfsg/series index 5cd0b06510f6..428a81eb6b22 100644 --- a/src/snmpd/patch-5.7.3+dfsg/series +++ b/src/snmpd/patch-5.7.3+dfsg/series @@ -1,7 +1,6 @@ 0001-SNMP-Stop-spamming-logs-with-statfs-permission-denie.patch 0002-at.c-properly-check-return-status-from-realloc.-Than.patch 0003-CHANGES-BUG-2743-snmpd-crashes-when-receiving-a-GetN.patch -0004-Disable-SNMPv1.patch 0005-Port-OpenSSL-1.1.0-with-support-for-1.0.2.patch 0006-From-Jiri-Cervenka-snmpd-Fixed-agentx-crashing-and-or-freezing-on-timeout.patch 0007-Linux-VRF-5.7.3-Support.patch From b6c978d27a2f27c3215c7f113479a5a5009222fe Mon Sep 17 00:00:00 2001 From: tahmed-dev <56694863+tahmed-dev@users.noreply.github.com> Date: Mon, 6 Jan 2020 17:01:28 -0800 Subject: [PATCH 036/178] [libnl]: Debian Packaging libnl version 3.5.0 (#3967) Packaging libnl 3.5.0 based off libnl 3.2.27 packaging. libnl contains various bug fixes that are nice to have. pull-request: https://github.com/Azure/sonic-buildimage/pull/3967 signed-off-by: Tamer Ahmed --- .gitignore | 16 + rules/libnl3.mk | 4 +- src/libnl3/Makefile | 9 +- src/libnl3/debian/README.Debian | 17 + src/libnl3/debian/README.source | 10 + src/libnl3/debian/changelog | 1043 +++++++++ src/libnl3/debian/compat | 1 + src/libnl3/debian/control | 245 ++ src/libnl3/debian/copyright | 160 ++ src/libnl3/debian/gbp.conf | 16 + src/libnl3/debian/libnl-3-200-udeb.install | 1 + src/libnl3/debian/libnl-3-200.install | 3 + src/libnl3/debian/libnl-3-200.symbols | 661 ++++++ src/libnl3/debian/libnl-3-dev.install | 5 + src/libnl3/debian/libnl-cli-3-200.install | 4 + src/libnl3/debian/libnl-cli-3-200.symbols | 226 ++ src/libnl3/debian/libnl-cli-3-dev.install | 3 + .../debian/libnl-genl-3-200-udeb.install | 2 + src/libnl3/debian/libnl-genl-3-200.install | 2 + src/libnl3/debian/libnl-genl-3-200.symbols | 88 + src/libnl3/debian/libnl-genl-3-dev.install | 4 + src/libnl3/debian/libnl-idiag-3-200.install | 1 + src/libnl3/debian/libnl-idiag-3-200.symbols | 206 ++ src/libnl3/debian/libnl-idiag-3-dev.install | 3 + src/libnl3/debian/libnl-nf-3-200.install | 1 + src/libnl3/debian/libnl-nf-3-200.symbols | 620 +++++ src/libnl3/debian/libnl-nf-3-dev.install | 3 + src/libnl3/debian/libnl-route-3-200.install | 1 + src/libnl3/debian/libnl-route-3-200.symbols | 2051 +++++++++++++++++ src/libnl3/debian/libnl-route-3-dev.install | 3 + src/libnl3/debian/libnl-utils.install | 1 + src/libnl3/debian/libnl-utils.manpages | 1 + src/libnl3/debian/libnl-xfrm-3-200.install | 1 + src/libnl3/debian/libnl-xfrm-3-200.symbols | 484 ++++ src/libnl3/debian/libnl-xfrm-3-dev.install | 3 + src/libnl3/debian/patches/series | 0 src/libnl3/debian/rules | 39 + src/libnl3/debian/source/format | 1 + src/libnl3/debian/watch | 2 + 39 files changed, 5934 insertions(+), 7 deletions(-) create mode 100644 src/libnl3/debian/README.Debian create mode 100644 src/libnl3/debian/README.source create mode 100644 src/libnl3/debian/changelog create mode 100644 src/libnl3/debian/compat create mode 100644 src/libnl3/debian/control create mode 100644 src/libnl3/debian/copyright create mode 100644 src/libnl3/debian/gbp.conf create mode 100644 src/libnl3/debian/libnl-3-200-udeb.install create mode 100755 src/libnl3/debian/libnl-3-200.install create mode 100644 src/libnl3/debian/libnl-3-200.symbols create mode 100755 src/libnl3/debian/libnl-3-dev.install create mode 100755 src/libnl3/debian/libnl-cli-3-200.install create mode 100644 src/libnl3/debian/libnl-cli-3-200.symbols create mode 100644 src/libnl3/debian/libnl-cli-3-dev.install create mode 100755 src/libnl3/debian/libnl-genl-3-200-udeb.install create mode 100755 src/libnl3/debian/libnl-genl-3-200.install create mode 100644 src/libnl3/debian/libnl-genl-3-200.symbols create mode 100755 src/libnl3/debian/libnl-genl-3-dev.install create mode 100644 src/libnl3/debian/libnl-idiag-3-200.install create mode 100644 src/libnl3/debian/libnl-idiag-3-200.symbols create mode 100644 src/libnl3/debian/libnl-idiag-3-dev.install create mode 100644 src/libnl3/debian/libnl-nf-3-200.install create mode 100644 src/libnl3/debian/libnl-nf-3-200.symbols create mode 100644 src/libnl3/debian/libnl-nf-3-dev.install create mode 100644 src/libnl3/debian/libnl-route-3-200.install create mode 100644 src/libnl3/debian/libnl-route-3-200.symbols create mode 100644 src/libnl3/debian/libnl-route-3-dev.install create mode 100644 src/libnl3/debian/libnl-utils.install create mode 100644 src/libnl3/debian/libnl-utils.manpages create mode 100644 src/libnl3/debian/libnl-xfrm-3-200.install create mode 100644 src/libnl3/debian/libnl-xfrm-3-200.symbols create mode 100644 src/libnl3/debian/libnl-xfrm-3-dev.install create mode 100644 src/libnl3/debian/patches/series create mode 100755 src/libnl3/debian/rules create mode 100644 src/libnl3/debian/source/format create mode 100644 src/libnl3/debian/watch diff --git a/.gitignore b/.gitignore index 73a99e67854e..316cf974e6c1 100644 --- a/.gitignore +++ b/.gitignore @@ -55,6 +55,8 @@ src/isc-dhcp/* !src/isc-dhcp/Makefile !src/isc-dhcp/patch/ src/libnl3/* +!src/libnl3/debian +src/libnl3/debian/libnl-*/ !src/libnl3/Makefile src/libteam/* !src/libteam/Makefile @@ -146,3 +148,17 @@ src/sonic-daemon-base/sonic_daemon_base.egg-info # Misc. files files/initramfs-tools/arista-convertfs files/initramfs-tools/union-mount + +# Debian byproduct files +src/**/debian/stamp-*/ +src/**/debian/*.log +src/**/debian/*.substvars +src/**/debian/.debhelper/ +src/**/debian/tmp/ +src/**/debian/autoreconf.* +src/**/debian/build/ +src/**/debian/files +src/**/debian/stamp-autotools-files + +# .o files +src/**/*.o diff --git a/rules/libnl3.mk b/rules/libnl3.mk index 897b6c34482f..cdd807b2f5c8 100644 --- a/rules/libnl3.mk +++ b/rules/libnl3.mk @@ -1,7 +1,7 @@ # libnl3 -LIBNL3_VERSION_BASE = 3.2.27 -LIBNL3_VERSION = $(LIBNL3_VERSION_BASE)-2 +LIBNL3_VERSION_BASE = 3.5.0 +LIBNL3_VERSION = $(LIBNL3_VERSION_BASE)-1 export LIBNL3_VERSION_BASE export LIBNL3_VERSION diff --git a/src/libnl3/Makefile b/src/libnl3/Makefile index c9fc72f50f74..a0e9891c9efc 100644 --- a/src/libnl3/Makefile +++ b/src/libnl3/Makefile @@ -16,12 +16,11 @@ DERIVED_TARGETS = libnl-3-dev_$(LIBNL3_VERSION)_$(CONFIGURED_ARCH).deb \ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : # Obtaining the libnl3 rm -rf ./libnl3-$(LIBNL3_VERSION_BASE) - wget -O libnl3_$(LIBNL3_VERSION_BASE).orig.tar.gz -N "https://sonicstorage.blob.core.windows.net/packages/libnl3_$(LIBNL3_VERSION_BASE).orig.tar.gz?sv=2015-04-05&sr=b&sig=b4DnqrIsyVBDLmYhw7qwfaUJWqGCX2lDVMmmx7ihfrU%3D&se=2028-06-16T21%3A06%3A00Z&sp=r" - wget -O libnl3_$(LIBNL3_VERSION).dsc -N "https://sonicstorage.blob.core.windows.net/packages/libnl3_$(LIBNL3_VERSION).dsc?sv=2015-04-05&sr=b&sig=AWTX45oDbeGA%2BRJZyiCcHmeIfCAgSeNV3IqopOBaRDg%3D&se=2028-06-16T21%3A05%3A30Z&sp=r" - wget -O libnl3_$(LIBNL3_VERSION).debian.tar.xz -N "https://sonicstorage.blob.core.windows.net/packages/libnl3_$(LIBNL3_VERSION).debian.tar.xz?sv=2015-04-05&sr=b&sig=upIZ9dp5WEcLqp3ODeWKJXq5pJWCfeT0TIM0bx76wxM%3D&se=2028-06-16T21%3A04%3A44Z&sp=r" - dpkg-source -x libnl3_$(LIBNL3_VERSION).dsc + git clone https://github.com/thom311/libnl libnl3-$(LIBNL3_VERSION_BASE) + pushd libnl3-$(LIBNL3_VERSION_BASE) + git checkout tags/libnl$(subst .,_,$(LIBNL3_VERSION_BASE)) - pushd ./libnl3-$(LIBNL3_VERSION_BASE) + ln -s ../debian debian dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) popd diff --git a/src/libnl3/debian/README.Debian b/src/libnl3/debian/README.Debian new file mode 100644 index 000000000000..002e249bbfcb --- /dev/null +++ b/src/libnl3/debian/README.Debian @@ -0,0 +1,17 @@ + +libnl versions explained +======================== + +Once libnl3 hits the archive there will exist 3 versions of libnl. +libnl1 with libnl-dev - up until March 2011 the stable version +libnl2 with libnl2-dev - development version that resulted in +libnl3 with libnl3-dev - the new stable (API and ABI wise) version + +libnl1 has currently a lot of users in the archive and a lot of changes +happened since its last upstream release in 2008-01. + +The plan is therefore to introduce libnl3, port the two users of libnl2 +(freesmartphone.org libs and powertop) to it, remove libnl2 and don't touch +libnl1 and libnl-dev for now. + + -- Heiko Stuebner Sat, 21 May 2011 19:25:13 +0200 diff --git a/src/libnl3/debian/README.source b/src/libnl3/debian/README.source new file mode 100644 index 000000000000..f6e8ee70da94 --- /dev/null +++ b/src/libnl3/debian/README.source @@ -0,0 +1,10 @@ +This package uses the simple-patchsys of cdbs. + +The following patches are used: +0001: Fixes the header inclusion in the Makefiles. + This for example make distcheck +0002: Includes all generated libraries as linktargets in the pkg-config file. + Reason: Currently libnl3 generates a bunch of child libraries. + These don't get individual .pc files from upstream at the moment but + programs linking against libnl3 using the .pc file mostly need these + additional libraries too. diff --git a/src/libnl3/debian/changelog b/src/libnl3/debian/changelog new file mode 100644 index 000000000000..c51ae1121796 --- /dev/null +++ b/src/libnl3/debian/changelog @@ -0,0 +1,1043 @@ +libnl3 (3.5.0-1) unstable; urgency=low + + [ skuklinski ] + * route/link: IFLA_VLAN_PROTOCOL added to vlan_put_attrs + + [ Thomas Haller ] + * rtnl/link: indicate capability NL_CAPABILITY_RTNL_LINK_VLAN_PROTOCOL_SERIALZE + + [ David Ahern ] + * route/vrf: add VRF support + * neigh: add support for NTF_SELF + + [ Beniamino Galvani ] + * route/link: fix parsing of 'remote' attribute for GRE links + + [ Thomas Haller ] + * route/vlan: allow clearing vlan ingress map + + [ David Ahern ] + * link/neigh: add flags option to link and neighbor caches + + [ Thomas Haller ] + * gitignore: ignore test binaries in "tests/" + + [ Beniamino Galvani ] + * route/link: add macvtap support + * route/link: fix dump of parent link for some link types + * route/link: add ipv6 support to vxlan links + + [ Tobias Jungel ] + * route/link: corrected array size for inet_policy + + [ David Ahern ] + * route/link: add link info compare operation + * route/link/vxlan: trivial rename VXLAN_HAS_ prefix and vxi_mask + * route/link/vxlan: add support for link_info compare + + [ Andrew Vagin ] + * libnl: don't use out-of-scope buffer in nl_send_iovec() + + [ David Ahern ] + * link: add AF operation to append attributes to a GETLINK message + * lib: handle family-based parsing of IFLA_AF_SPEC attribute + + [ Thomas Haller ] + * include/linux: update copy of kernel headers + + [ David Ahern ] + * bridge: add support for VLANs + + [ Tobias Jungel ] + * route/link: handle RTEXT_FILTER_BRVLAN_COMPRESSED + * route/link/bridge: fixed return type + + [ Quentin Armitage ] + * route/link: add support for IN6_ADDR_GEN_MODE_STABLE_PRIVACY + + [ Amit Khatri ] + * lib/route: potential memory leak in pktloc.c + + [ Nick Lewycky ] + * remove null dereference from netlink/link.h + + [ David Ahern ] + * lib: update ce-mask to uint64_t + + [ Thomas Haller ] + * libnl: add nl_object_diff64() to libnl-3.sym + * lib/utils: add NL_CAPABILITY_NL_OBJECT_DIFF64 capability + + [ Przemyslaw Szczerbik ] + * lib: add type casting for nla_for_each_nested macro + + [ Tobias Klauser ] + * build: move -rdynamic from CPPFLAGS to LDFLAGS + + [ Thomas Haller ] + * route: sort entries in libnl-route-3.sym by name + + [ Haishuang Yan ] + * ipgre: add support for gretap tunnel + + [ Thadeu Lima de Souza Cascardo ] + * sit: add 6RD support + + [ Thomas Haller ] + * sit/trivial: whitespace + * sit: don't print ip6rd_prefix as integer in sit_dump_details() + * sit: refactor IS_SIT_LINK_ASSERT() + * sit: fix invalid declaration of rtnl_link_sit_get_proto() in sit.h + * sit: add public API for sit 6RD support + + [ Jonas Johansson ] + * neigh: support neighbour flag NTF_SELF + * neigh: add function to look up neighbour (fdb) by ifindex, mac and vlan + + [ Jef Oliver ] + * link: support RTEXT_FILTER_VF + + [ Thomas Haller ] + * link: allow overwriting IFLA_EXT_MASK flag in ao_get_af() function + + [ Przemyslaw Szczerbik ] + * lib: return error on Netlink attribute length overflow + + [ Thomas Egerer ] + * xfrm: fix buffer overflow when copying keys + * xfrm: check length of alg_name before strcpying it + * xfrm: make character pointers in setters const + * xfrm: fix segfault when using encapsulation templates + + [ Thomas Haller ] + * xfrm: reuse encap data in xfrmnl_sa_set_encap_tmpl() + + [ Thomas Egerer ] + * xfrm: fix memory leak for encap original address + * xfrm: attach only one xfrm alg attribute to netlink message + + [ Thomas Haller ] + * xfrm: fix memleak in build_xfrm_sa_message() error-path + + [ Sabrina Dubroca ] + * pass flags through ->io_compare op + * vxlan: properly handle LOOSE_COMPARISON in ->io_compare + * import macsec uapi headers + * lib/route: add macsec support + + [ Thomas Haller ] + * xfrm: allow avoiding buffer overflow for key in xfrmnl_sa_get_*_params() + * route/addr: fix ID comparison for AF_INET and AF_INET6 addresses + * route/addr: fix handling peer addresses for IPv4 addresses + * route/addr: add capability NL_CAPABILITY_RTNL_ADDR_PEER_FIX to indicate address fixes + * build: fix adding macsec files to include/Makefile.am + * libnl-3.2.28-rc1 release + * libnl-3.2.28 release + + [ Craig Gallek ] + * build: fixup headers for C++ inclusion + + [ Peter Wu ] + * trivial: whitespace-only fixes for src and lib + * cli: add noreturn attributes + * xfrm: fix memleak in another error path of build_xfrm_sa_message + * exp: fix a GCC 6 -Wmisleading-indentation warning + * doc: fix URLs and typo + + [ Tobias Jungel ] + * route/addr: address attributes based on object + + [ Thomas Haller ] + * lib: capability NL_CAPABILITY_RTNL_ADDR_PEER_ID_FIX for ID comparison of v4 addresses + * nl-addr: avoid read-out-of-bound in nl_addr_fill_sockaddr() + + [ André Draszik ] + * lib: add utility function nl_strerror_l() + * lib: switch to using strerror_l() instead of strerror_r() + * src: switch to using strerror_l() instead of strerror_r() + + [ Jeff Squyres ] + * compat: add linux/socket.h for __kernel_sa_family_t + + [ Jef Oliver ] + * lib/route: allow override of message type during link change + * lib/route: set IFLA_PROTINFO attribute in request message + * lib/route: modify link/bridge to set attributes + + [ Davide Caratti ] + * macsec: fix endianness of 'sci' parameter + * macsec: fix maximum ICV length + * remove multiple implementations of htonll(), ntohll() + + [ Jef Oliver ] + * lib/route: Fix appending IFLA_BRPORT_FASTLEAVE + * lib/route: Add port state translation functions + * lib/route: Extend Bridge Flags + * lib/route: Allow override of IFLA_AF_SPEC nesting + * lib/route: Support IFLA_BRIDGE_MODE + + [ Thomas Haller ] + * trivial: whitespace + * bridge: change return values for rtnl_link_bridge_get_hwmode() + + [ Michael Braun ] + * macvlan: add support for "source" mode + + [ Thomas Haller ] + * macvlan: adjust types and merge MACVLAN_HAS_MACCOUNT and MACVLAN_HAS_MACDATA + + [ Brandon Carpenter ] + * vxlan: add support for additional VXLAN attributes. + + [ Thomas Haller ] + * vxlan: fix exporting new symbols + * vxlan: remove redundant enable/disable API from vxlan + * vxlan: restore previous VXLAN_ATTR flag values + * vxlan: don't store vxlan flags as ce_mask + * vxlan: refactor setting/getting vxlan flags + * vxlan: fix error code for missing attribute + + [ Jef Oliver ] + * lib/route: Export correct ipgre functionality + + [ Thomas Haller ] + * lib/route: preserve old ABI for rtnl_link_get_pmtudisc() + + [ Thomas Egerer ] + * xfrm: fix xfrm security context management + * xfrm: add capability reference to xfrmnl_sa_set_* + + [ Thomas Haller ] + * xfrm: remove unused struct xfrmnl_sec_ctx from header files + + [ Jef Oliver ] + * lib/route: SRIOV Parse and Read support + * lib/route: SRIOV Clone Support + * lib/route: SRIOV Utility Functions + * lib/route: SRIOV Info Dump Functions + * lib/route: SRIOV Set Functionality + + [ Thomas Haller ] + * route: remove symbols of internal API from ABI + + [ Tobias Klauser ] + * lib/route: keep link stats minlen compatible with kernel < 4.6 + + [ Thomas Haller ] + * utils: add internal _nl_offset_plus_sizeof() macro + * lib/route: use _nl_offset_plus_sizeof() macro for minlen field for rtln_link_policy + + [ Jonas Johansson ] + * Add PPP support + * ppp: update code after review + * ppp: rename local struct ppp_info* variables; pi -> info + * ppp: fix type of file descriptor; uint32_t -> int32_t + + [ Thomas Haller ] + * ppp: fix API in ppp.h header + + [ Sushma Sitaram ] + * route/cls: support setting of selector fields + + [ Tobias Klauser ] + * src: nl-link-stats: use correct rtnl link stats maximum + * lib/route: add rx_nohandler link stats field + + [ Thomas Haller ] + * nl-link-stats: prefer RTNL_LINK_STATS_MAX over __RTNL_LINK_STATS_MAX + * lib/route: pass sizeof() argument to nl_memcpy() + * link: set ifi_change flags for rtnl_link_build_add_request() + * lib: use MSG_PEEK by default for nl_recvmsgs() + + [ Tobias Jungel ] + * cache_mngr: add include callback v2 + + [ Tobias Klauser ] + * cache: fix GCC warning and avoid variable shadowing + + [ Sushma Sitaram ] + * route/act: add gact tc action + + [ Tobias Klauser ] + * link: add support for IFLA_CARRIER_CHANGES + * link: add support for IFLA_PHYS_PORT_NAME + * link: add support for IFLA_PHYS_SWITCH_ID + * link: add support for IFLA_GSO_MAX_SEGS and IFLA_GSO_MAX_SIZE + * link: fix documentation for rtnl_link_get_carrier_changes + + [ Thomas Haller ] + * libnl-3.2.29-rc1 release + * utils/trivial: rename internal _nl_offset_plus_sizeof() macro to _nl_offsetofend() + + [ Beniamino Galvani ] + * Revert "macsec: fix endianness of 'sci' parameter" + * macsec: document byte order for the SCI and port attributes + + [ Thomas Haller ] + * macsec: fix endianness of sci during dump() + * libnl-3.2.29 release + + [ Tobias Klauser ] + * route/tc: Remove unused function tca_set_kind() + + [ Laine Stump ] + * sriov: fix crash in rtnl_link_sriov_parse_vflist + + [ Thomas Haller ] + * sriov: avoid buffer overrun in rtnl_link_sriov_parse_vflist() + + [ Nick Kralevich ] + * lib/utils.c: lazy initialize user_hz and psched_hz + + [ Thomas Haller ] + * lib/utils.c: ensure calling get_psched_settings() for nl_us2ticks()/nl_ticks2us() + * lib/utils.c: add mutex to get_psched_settings() + + [ Nick Kralevich ] + * fopen: add O_CLOEXEC + + [ Thomas Haller ] + * lib/attr.c: check for valid length argument in nla_reserve() + + [ Tobias Klauser ] + * sit: Fix invalid function prototypes in public header + * sriov: Add missing prototype for rtnl_link_vf_vlan_free() + * qdisc/red: Add missing prototypes for rtnl_red_set_limit() and rtnl_red_get_limit() + * fib_lookup: Add missing prototypes to public header + * link/inet6: Include own public header for function prototypes + * link/ipip: Include own public header for function prototypes + * link/ipip: Add missing prototype for rtnl_link_is_ipip() + * link/ipvti: Include own public header for function prototypes + * link/ipvti: Fix and add function prototypes in public header + * link/macsec: Include own public header for function prototypes + * link/sit: Add missing prototype for rtnl_link_is_sit() + * link/ipgre: Add prototype for ABI-preserving wrapper rtnl_link_get_pmtudisc() + * netfilter/queue: Add missing prototype for nfnl_queue_msg_build_verdict_batch() + * netfilter/exp: Add missing function prototypes + * idiag/req: Add missing function prototype + * xfrm/ae: Include own public header for function prototypes + * xfrm/lifetime: Include own public header for function prototypes + * xfrm/sa: Include own public header for function prototypes + * xfrm/selector: Include own public header for function prototypes + * xfrm/template: Include own public header for function prototypes + * pktloc: Add missing function prototypes + * ematch: Add missing function prototypes + * build: Add -Wmissing-prototypes to CPPFLAGS + + [ Jeroen Roovers ] + * build: distribute in.h in6.h libc-compat.h + + [ Thomas Haller ] + * lib: fix comment for nl_recv() about return value for non-blocking read + * lib: check for integer-overflow in nlmsg_reserve() + * build: cleanup top-level Makefile.am + * build: merge include/Makefile.am into top-level makefile + * build: merge lib/Makefile.am into top-level makefile + * build: merge man/Makefile.am into top-level makefile + * build: merge python/Makefile.am into top-level makefile + * build: merge tests/Makefile.am into top-level makefile + * build: merge src/lib/Makefile.am into top-level makefile + * build: merge src/Makefile.am into top-level makefile + * build: enable building cli during tests + * build: move compiler warning flags to separate autoconf variable + * all: enable -Wmissing-prototype warning for all components + * build: enable more warnings + + [ Roopa Prabhu ] + * route: neigh: use NDA_MASTER for neigh->n_master if available + + [ Simon Buttgereit ] + * fix build_xfrm_sp_message index condition + * fix xfrmnl_sp_set_sec_ctx length attributes + * little style fixes. + * update sp_attr condition in build_xfrm_sp_message + * add possibity to delete policy without index + * update documentation of xfrmnl_sp_get_sec_ctx + * fix of boolean operators + + [ Thomas Haller ] + * xfrm: allow quering optional arguments from xfrmnl_sp_get_sec_ctx() + * xfrm: NUL terminate the ctx_str buffer in xfrmnl_sa_set_sec_ctx() + * build: ensure build directory for generated sources exist + * build: pass --disable-dependency-tracking to `make distcheck` + * build: fix creating directories for generated sources + * build: style cleanup in doc/Makefile.am + * build: reorder checks in configure.ac + * build: add tools/build_release.sh script + * include: don't include kernel headers in public libnl3 headers + * include: restore linux header includes in public headers + * libnl-3.3.0-rc1 release + + [ Alexey Brodkin ] + * lib: escape usage of strerror_l() if it doesn't exist in libc + + [ Thomas Haller ] + * all: don't use math.h or link with libm.so + * libnl-3.3.0 release + * tools: fix building doc in build_release.sh + + [ Markus Trapp ] + * route/link: add accessor API for IPv6 flags + + [ Santhosh Kumar ] + * Provide accessors for actions (rtnl_act). + * Do not increment refcount in rtnl_*_get_action APIs. + + [ Thomas Haller ] + * route: fix symbol versioning + + [ David Ahern ] + * route: Add support for netconf + * nl-monitor: All user to specify line format + * nl-monitor: Add support for netconf caches + * route: Add support for MPLS to netconf + * Update fib_rules.h to latest kernel + * rule: Add support for l3mdev in FIB rules + + [ Thomas Haller ] + * rule: change API for setting/getting l3mdev rule property + + [ Tobias Klauser ] + * addr: add AF_VSOCK to translation table + + [ Thomas Haller ] + * build: don't build cli libraries by default + * build: allow building cli without dynamic librarires support + + [ Tobias Klauser ] + * genl: drop usage of GENL_ID_GENERATE + + [ Rasmus Villemoes ] + * lib/cache_mngr.c: avoid memleak if realloc fails + * lib/cache_mgr.c: remove pointless goto + * lib/data.c: avoid memleak if realloc fails + * lib/route/cls/u32.c: remove pointless nl_data_append calls + * lib/route/cls/u32.c: avoid overflowing an unsigned char + * lib/route/cls/u32.c: let the compiler do pointer arithmetic + * lib/route/cls/u32.c: remove bogus comment + * lib/route/qdisc/netem.c: avoid memory leak if realloc fails + + [ Thomas Haller ] + * lib/route/cls/u32.c: use UCHAR_MAX define instead of numeric 255 + * lib/route/qdisc/netem.c/trivial: fix whitespace and indentation in netem_msg_fill_raw() + * lib/route/qdisc/netem.c/trivial: don't use braces for one-line blocks + + [ Rasmus Villemoes ] + * lib/xfrm/ae.c: fix memcpy(dst, dst) bug + * lib/genl/family.c: fix if (x) y; else y; + + [ Thomas Haller ] + * all: avoid compiler warnings -Wimplicit-fallthrough + * lib/route: add /usr/lib64/tc/ search path for netem dist file + + [ David Ahern ] + * Update rtnetlink.h from kernel tree + * Import mpls header from kernel tree + + [ Thomas Haller ] + * build: add include/linux-private/linux/mpls.h to Makefile.am + + [ David Ahern ] + * addr: Add implementations for mpls_ntop and mpls_pton + * addr: Add support for AF_MPLS + * route: Add support for MPLS address family + * route: Add support for ttl propagation in MPLS routes + * Add support for label stack in nl-route commands + * Import lwtunnel encap files from kernel + * route: Add support for lwtunnel encapsulations + * route: Add support for MPLS encap + + [ Thomas Haller ] + * build: add new include/netlink-private/route/*.h files to Makefile.am + + [ Amit Khatri ] + * Potential memory leak becaue of wrong variable check. + + [ Tobias Klauser ] + * cli: include sys/select.h for select(2) + + [ Thomas Haller ] + * libnl-3.4.0-rc1 release + + [ David Ahern ] + * netconf: Put nc reference in msg_parser + + [ Jeroen Roovers ] + * build: add missing headers for issue #152 + + [ Thomas Haller ] + * libnl-3.4.0 release + * nl: add "const" specifier for nla_policy argument of parse functions [ Roopa Prabhu ] + * route: link: add family to dump messages + * route: neigh: print family in neigh dumps + + [ Sebastian Bixl ] + * route/vlan: fix memory corruption in rtnl_link_vlan_set_egress_map + + [ Thomas Haller ] + * route/vlan: fix cloning vlan link in vlan_clone() + * route/vlan: grow buffer exponentially in rtnl_link_vlan_set_egress_map() + * route/vlan: add capability to indicate heap overflow fix in rtnl_link_vlan_set_egress_map() + * route: fix handling old_nh in rtnl_route_parse() and avoid leak + + [ Jef Oliver ] + * Change rtnl_link_af_ops.ao_override_rtm behavior + + [ Chris Grahn ] + * tests: fix bug in test-create-bridge.c + + [ Steffen Vogel ] + * route: add separate function to set netem qdisc delay distribution + + [ Thomas Haller ] + * all: declare all variables at the beginning of scope (-Wdeclaration-after-statement) + * route: add rtnl_netem_set_delay_distribution_data() to linker script + * route: mark data argument for rtnl_netem_set_delay_distribution_data() as const + * route: fix memleak in rtnl_netem_set_delay_distribution_data() + * route: free previous data in rtnl_netem_set_delay_distribution_data() + * travis: enable more warnings during build + + [ Marcos Paulo de Souza ] + * tests: Add test to {de}activate loopback interface + * lib/veth.c: Disassociate link name of peer name + + [ d0u9 ] + * Coding style format + * Add new function for setting ifindex and parent of a classifier cache. + + [ Thomas Haller ] + * route: rename rtnl_cls_cache_set_tcm_params() and fix symbol versioning + + [ d0u9 ] + * Fix for cgroup filter addition problem. + + [ Thomas Haller ] + * lib: merge implementations of nl_attr_end() and nl_attr_keep_empty() + + [ Wang Jian ] + * link: add Geneve support. + + [ Thomas Haller ] + * lib/rtnl: rename public define RTNL_GENEVE_ID_MAX + + [ Roopa Prabhu ] + * lib: route: rule: add rule_groups to cache ops + + [ Jonas Johansson ] + * route/vrf: initalize clone destination with NULL in vrf_clone() + + [ David Ahern ] + * Update fib_rules.h to latest kernel + * rule: Add support for protocol and port ranges + + [ Lukáš Karas ] + * add demo program for listen conntrack events + * nf-ct-add typo + + [ Thomas Haller ] + * build: sort entries in Makefile.am and .gitignore by name + * build: indent libnl-route-3.sym with tabs + + [ Tobias Jungel ] + * neigh: set correct AF for NDA_DST + * neigh: support bridge entries for vxlan interfaces + + [ Tuetuopay ] + * cache: make "result" output argument for nl_cache_mngr_add() optional + + [ Volodymyr Bendiuga ] + * include: copy entire pkt_cls.h from linux + * route:cls: add matchall classifier + + [ Thomas Haller ] + * route/mall: fix deep cloning mall + + [ Tuetuopay ] + * route/link: fix sequence number handling in rtnl_link_change() + + [ Thomas Haller ] + * route/link: assert in rtnl_link_change() that the sequence number is set as expected + * nl-msg: explicitly initialize nlmsg_seq and nlmsg_pid field in nlmsg_alloc_simple() + + [ d0u9 ] + * route/class: add new api rtnl_class_get_by_parent() + + [ Tobias Jungel ] + * neigh: correct symbol exposed + + [ Matthieu Baerts ] + * nl: fix function name in debug msg + + [ Tobias Jungel ] + * neigh: cache updates as well query AF_BRIDGE neigh + * whitespace cleanup + * nl-neigh-list: free allocated items + * neigh: add get/set functions for NEIGH_ATTR_MASTER + * neigh_dump_line: dump master as well + + [ d0u9 ] + * Add support for cloning cgroup filter object. + + [ Tuetuopay ] + * route/link/vxlan: Fix IPv4 set_local resetting ce_mask + + [ Tobias Jungel ] + * neigh: update neighbour.h and add missing flags + + [ Thomas Winter ] + * ipgre: Fix wrong array size initialization + * ipvti: Fix wrong array size initialization + * if_tunnel: Update IFLA defines up to FWMARK + + [ Thomas Haller ] + * include/linux: update copy of kernel headers + + [ Volodymyr Bendiuga ] + * include: import linux header pkt_sched.h + * route:qdisc: add MQPRIO Qdisc + + [ Thomas Haller ] + * build: cleanup Makefile.am + * lib/tc: ensure correct error code in rtnl_tc_msg_build() + * lib/qdisc: style fixes in "lib/route/qdisc/mqprio.c" + * lib/qdisc: avoid BUG() in "lib/route/qdisc/mqprio.c" + * build: sort entries in libnl-route-3.sym + * lib/tc: fix uninitalized err variable in rtnl_tc_msg_build() + + [ Volodymyr Bendiuga ] + * route:tc: allow to set chain index for tc objects + + [ Thomas Haller ] + * route/tc: return error code from rtnl_tc_get_chain() + + [ Volodymyr Bendiuga ] + * include: import tc_vlan.h + * route:act: add vlan action + + [ Thomas Haller ] + * route/act: style fixes in "lib/route/act/vlan.c" + * route/act: return error code from act-vlan getters + + [ Ilya Pronin ] + * route/cls: fix potential memory leak + + [ Patrick Havelange ] + * nla_ok: fix overrun in attribute iteration. + + [ Wang Jian ] + * link: macvlan fixes + + [ Thomas Haller ] + * route/macvlan: style fixes in "lib/route/link/macvlan.c" + + [ Tobias Jungel ] + * route/link: expose IFLA_INFO_SLAVE_KIND + + [ Thomas Haller ] + * route/link: avoid dangling pointer in rtnl_link_set_slave_type() + + [ Byeonggon Lee ] + * tests: use nl_send_auto() instead of deprecated nl_send_auto_complete() in test-genl.c + + [ Thomas Haller ] + * doc: fix typos in example in documentation + * attr: mark nested attributes as NLA_F_NESTED + + [ xinbao ] + * Add CTA_LABELS and CTA_LABELS_MASK to ctattr_type according to the new kernel + + [ Thomas Haller ] + * route: fix strncpy() warning from coverity about unterminated string + * link/sriov: fix memleak in rtnl_link_sriov_clone() + * utils: add internal helper macros for cleanup + * lib/genl: avoid VLA in cmd_msg_parser() + * travis: enable -Wvla compiler warning in tests + * travis: build tests with NL_MORE_ASSERTS enabled + * xfrm: fix memory corruption (dangling pointer) when when setting xfrmnl_sa + * route/inet6: fix strncpy() in inet6_dump_details() + * route/tc: ensure not string truncation in rtnl_tc_set_kind() + * genl: reject invalid group names in genl_family_add_grp() + + [ Yegor Yefremov ] + * Add SPDX identifiers + + [ Thomas Haller ] + * lib/genl: fix allocating buffer of too small size in cmd_msg_parser() + + [ Michael Forney ] + * dbg: Use __func__ instead of __PRETTY_FUNCTION__ + * all: Avoid pointer arithmetic on `void *` + * lib: Don't return expression in function returning void + * lib: Don't omit second operand to `?` operator + * all: Use __typeof__ instead of typeof + * route: Remove stray `;` at top-level + * Sync linux headers to 4.19.66 + + [ Thomas Haller ] + * idiag: workaround and add comment about idiagnl_send_simple() only handling 8 bit flags + * lib: accept %NULL arguments for nl_addr_cmp() + * lib: fix error code from nfnl_exp_build_message() + + [ Eyal Birger ] + * doc/route: fix example code comments + * xfrmi: introduce XFRM interfaces support + + [ Thomas Haller ] + * xfrmi: return error code from getters for XFRM links + * route/trivial: sort entries in "libnl-route-3.sym" asciibetically + + [ d0u9 ] + * Add 64bit rate/ceil support for htb class + + [ Thomas Haller ] + * route/qdisc: adjust API for 64 bit rate/ceil support for htb class + * libnl-3.5.0 release + + -- Tamer Ahmed Thu, 02 Jan 2020 10:25:18 -0800 + +libnl3 (3.2.27-2) unstable; urgency=low + + * Add upstream fix for CVE-2017-0553 (Closes: #859948) + + -- Heiko Stuebner Mon, 10 Apr 2017 11:48:23 +0200 + +libnl3 (3.2.27-1) unstable; urgency=low + + * New upstream release + Including fixes for unusable sockets after a failed portid + generation (Closes: #808213) + + -- Heiko Stuebner Sun, 24 Jan 2016 23:54:47 +0100 + +libnl3 (3.2.26-1) unstable; urgency=low + + * New upstream release + * Provide Multiarch:same dev packages + * Add new libnl-xfrm library handling packet transformations + * Update standards to 3.9.6 + + -- Heiko Stuebner Mon, 13 Jul 2015 14:16:22 +0200 + +libnl3 (3.2.24-2) unstable; urgency=low + + * Backport two upstream fixes to prevent issues with older kernels: + - dfd0a80ec845 (route: don't enforce minlen in inet6_parse_protinfo() + (IFLA_PROTINFO) and inet_parse_af() (IFLA_AF_SPEC) + - 5206c050504f (route/addr: only sent IFA_FLAGS when needed to workaround + picky older kernels) + + -- Heiko Stuebner Fri, 18 Apr 2014 17:19:37 +0200 + +libnl3 (3.2.24-1) unstable; urgency=low + + * New upstream release + * Add new libnl-idiag library handling inetdiag requests + + -- Heiko Stuebner Sun, 16 Feb 2014 14:23:26 +0100 + +libnl3 (3.2.21-1) unstable; urgency=low + + * New upstream release (Closes: #707081) + Including CAN support (Closes: #698954) + * Add symbols files (Closes: #654758) + * Provide static libraries (Closes: #693939, #693940) + * Update standards to 3.9.4 + * Removed doc package. Libnl3 documentation is released + separately now. + + -- Heiko Stuebner Tue, 21 May 2013 11:39:13 +0200 + +libnl3 (3.2.7-4) unstable; urgency=low + + * Add watch file (Closes: #679473) + * Use dh-autoreconf to update the build system (Closes: 679474) + + -- Heiko Stuebner Sat, 30 Jun 2012 15:54:25 +0200 + +libnl3 (3.2.7-3) unstable; urgency=low + + * Fix FTBFS due to failing gen-tags.sh (Closes: #674322) + * Convert to Multi-Arch (Closes: #676611) + * Update standards to 3.9.3 - no changes + * Switch to dpkg-source format 3.0 (quilt) + + -- Heiko Stuebner Mon, 18 Jun 2012 21:19:30 +0200 + +libnl3 (3.2.7-2) unstable; urgency=low + + * Force doxygen dot-threads to 1 to circumvent segfaults on armel + * Add missing build-dependency on ghostscript + + -- Heiko Stuebner Mon, 05 Mar 2012 23:29:10 +0100 + +libnl3 (3.2.7-1) unstable; urgency=low + + * New upstream release + * Build-depend on source-highlight (Closes: #657254) + + -- Heiko Stuebner Mon, 13 Feb 2012 18:59:30 +0100 + +libnl3 (3.2.3-2) unstable; urgency=low + + * Upload to unstable + * Split split udeb to be in line with regular packages + * Move libnl and libnl-genl to /lib for iw and wpa_supplicant. + + -- Heiko Stuebner Mon, 19 Dec 2011 20:43:21 +0100 + +libnl3 (3.2.3-1) experimental; urgency=low + + * Upload to experimental to not break debian-installer + * Split library and dev packages for the individual libraries + * Add utils package + + [Mathieu Trudel-Lapierre ] + * New upstream release (Closes: #648819) + * debian/patches/0001-fix-headers.patch, + debian/patches/0002-link-sub-libs.patch, + debian/patches/0003-fix-out-of-tree-build.patch: dropped. + * debian/patches/0004-more-out-of-tree-build-fixes.patch: new patch; adjust + Makefiles some more to properly deal with the out-of-tree build when + generating headers and documentation. + * debian/control: + - rename packages to follow upstream soname. + - add python-pygments, xmlstarlet, texlive-latex-base and asciidoc to + Build-Depends. + * debian/rules: update due to upstream soname changes. + * debian/*.install: rename and update due to upstream soname changes. + * debian/libnl-3-200.install: netlink config files should be installed to + /etc/libnl, not /etc/libnl3. + * debian/libnl-3-doc.install, + debian/libnl-3-doc.doc-base: update to take into account new paths. + + -- Heiko Stuebner Tue, 06 Nov 2011 21:23:12 +0200 + +libnl3 (3.0-2) unstable; urgency=low + + * Acknowledge NMU + * Install config-files to /etc/libnl3 (Closes: #632790) + + -- Heiko Stuebner Mon, 26 Sep 2011 20:27:45 +0200 + +libnl3 (3.0-1.1) unstable; urgency=low + + * Non-maintainer upload with agreement from Heiko Stuebner + * Add libnl3-udeb package with seperate build for + debian-installer (Closes: #635962). + + -- Gaudenz Steinlin Fri, 29 Jul 2011 23:25:48 +0200 + +libnl3 (3.0-1) unstable; urgency=low + + * New upstream release (Closes: #626098) + see README.Debian for version explanation. + * Update standards to 3.9.2 + + -- Heiko Stuebner Sat, 21 May 2011 19:25:13 +0200 + +libnl2 (2.0-1) unstable; urgency=low + + * New upstream release (Closes: #603765) + * Fix compilation with binutils-gold or ld --no-add-needed + (Closes: #615745) + * Update standards + * Update build dependencies - tetex-live is not necessary + anymore (Closes: #616260) + + -- Heiko Stuebner Sun, 06 Mar 2011 18:20:47 +0100 + +libnl2 (1.99+git20091216-2) unstable; urgency=low + + * add README.source describing the patches in use. + * remove libnl*-provides - libnl2 should stay sepparate + from libnl1 for now + + -- Heiko Stuebner Wed, 10 Mar 2010 18:03:35 +0100 + +libnl2 (1.99+git20091216-1) unstable; urgency=low + + * New upstream snapshot + * New source name to enable installing libnl and libnl2 side by side + * Set myself as new maintainer for libnl2 according to agreement + with Michael Biebl + * Add debug package + * README.Debian warns of possible breakage in this snapshot + * Add Patch 0001 which fixes some errors in the build system + * Add Patch 0002 which adds libnl-?? libs to linker statement + until I can resolve this with upstream + + -- Heiko Stuebner Mon, 15 Feb 2010 21:50:35 +0100 + +libnl (1.1-5) unstable; urgency=low + + * Add symbols file for libnl1. + + -- Michael Biebl Wed, 25 Feb 2009 00:26:05 +0100 + +libnl (1.1-4) unstable; urgency=low + + * debian/control + - Add ${misc:Depends} to all binary packages. + - Bump Build-Depends on debhelper to (>= 7). + * debian/compat + - Bump debhelper compat level to 7. + * debian/rules + - Include debhelper.mk before other files as recommended by the cdbs + documentation. + + -- Michael Biebl Wed, 18 Feb 2009 13:26:53 +0100 + +libnl (1.1-3) unstable; urgency=low + + * debian/control + - Bump Standards-Version to 3.8.0. + * Switch to quilt for patch management. + * Add README.source which refers to the quilt documentation. + * debian/patches/limits.patch + - Add missing include to limits.h. This is required when compiling against + glibc 2.8. Thanks to Kees Cook for the patch. Closes: #501485 + + -- Michael Biebl Wed, 08 Oct 2008 21:34:34 +0200 + +libnl (1.1-2) unstable; urgency=low + + * debian/libnl-doc.doc-base + - Register the API documentation with doc-base. + * debian/control + - Add Suggests: doc-base to libnl-doc. + + -- Michael Biebl Wed, 05 Mar 2008 00:42:54 +0100 + +libnl (1.1-1) unstable; urgency=low + + * New stable upstream release. + * debian/patches/01-ip_mg_alg_internal_only.patch + - Removed, merged upstream. + * debian/control + - Rename binary package libnl1-pre8 to libnl1. + - [libnl1] Add Conflicts/Replaces: libnl1-pre8. + - [libnl-dev] Change Depends to libnl1. + * Rename debian/libnl1-pre8.install to debian/libnl1.install + * debian/copyright + - Minor updates and additions. + + -- Michael Biebl Thu, 10 Jan 2008 16:58:12 +0100 + +libnl (1.0~pre8-1) unstable; urgency=low + + * New upstream release. Closes: #456175 + * debian/control + - Bump Standards-Version to 3.7.3. No further changes required. + - The Vcs-* fields are now officially supported, so remove the XS- prefix. + - Rename binary package libnl1-pre6 to libnl1-pre8. + - [libnl1-pre8] Add Conflicts/Replaces: libnl1-pre6. The two versions are + not coinstallable. + - [libnl-dev] Change Depends to libnl1-pre8. + * Rename debian/libnl1-pre6.install to debian/libnl1-pre8.install. + * debian/patches/10-amd64-linux-types.patch + - Removed, merged upstream. + * debian/patches/01-ip_mg_alg_internal_only.patch + - Pull a fix from upstream. The header linux/ip_mp_alg.h is no longer part + of the linux kernel headers (i.e. linux-libc-dev) so remove it from + netlink/netlink.h. + + -- Michael Biebl Thu, 20 Dec 2007 07:45:03 +0100 + +libnl (1.0~pre6-6) unstable; urgency=low + + * debian/control + - Use the new "Homepage:" field to specify the upstream URL. + - Replace deprecated ${Source-Version} substvar with ${binary:Version}. + - Change Build-Depends: gs-gpl | gs-esp to Build-Depends: ghostscript. + + -- Michael Biebl Mon, 22 Oct 2007 07:15:29 +0200 + +libnl (1.0~pre6-5) unstable; urgency=low + + * debian/control + - Add XS-Vcs-* fields. + - Replace Build-Depends: tetex-bin with texlive-latex-base. teTeX is now + gone, superseded by texlive. + - Add Build-Depends: graphviz, gs-gpl | gs-esp. + The "dot" program is needed for generating the diagram image and "gs" + for the ps to png conversion. + + -- Michael Biebl Sun, 15 Apr 2007 15:45:48 +0200 + +libnl (1.0~pre6-4) unstable; urgency=medium + + * Autobuilders do not distinguish between build-arch and build-indep, they + simply run build. So we have to move doxygen and tetex-bin from + Build-Depends-Indep to Build-Depends. Closes: #408719 + * Urgency medium, as it fixes a FTBFS bug. + + -- Michael Biebl Fri, 12 Jan 2007 11:23:52 +0100 + +libnl (1.0~pre6-3) unstable; urgency=low + + * Build and package the API documentation. Closes: #406497 + * debian/control + - Add Build-Depends-Indep on doxygen and tetex-bin (dvips). + - Add new package libnl-doc. + - Add a "Suggests: libnl-doc" to libnl-dev. + * debian/rules + - Call "make gendoc" to build the API documentation. + * debian/libnl-doc.install + - Added. List the files that should be installed. + + -- Michael Biebl Fri, 12 Jan 2007 10:30:40 +0100 + +libnl (1.0~pre6-2) unstable; urgency=low + + * Update maintainer email address to biebl@debian.org. + + -- Michael Biebl Thu, 19 Oct 2006 20:16:09 +0200 + +libnl (1.0~pre6-1) unstable; urgency=low + + * New upstream release. + * Removed 20-autoconf-dirs.patch, merged upstream. + * Updated debian/copyright, libnl is now licensed under the LGPL 2.1. + * Updated debian/watch. + + -- Michael Biebl Fri, 18 Aug 2006 00:40:34 +0200 + +libnl (1.0~pre6~svn30-1) unstable; urgency=low + + * Updated to svn revision 30. + * Bumped Standards-Version to 3.7.2, no further changes required. + * Now that dak officially supports ~ in the version number, let's make use + of it. + * Some install directories were not set correctly, 20-autoconf-dirs.patch + fixes that. + + -- Michael Biebl Thu, 10 Aug 2006 19:51:42 +0200 + +libnl (0.99+1.0.svn21-4) unstable; urgency=low + + * Do not create bogus /usr/lib/pkg-config directory. Closes: #364601 + + -- Michael Biebl Mon, 24 Apr 2006 15:40:23 +0200 + +libnl (0.99+1.0.svn21-3) unstable; urgency=low + + * Include simple-patchsys.mk in debian/rules. + * Merged debian/patches/10-amd64-linux-types.patch from Ubuntu which fixes + the FTBFS error on AMD64. Closes: #358887 + Thanks to Scott James Remnant for this patch. + + -- Michael Biebl Sat, 1 Apr 2006 04:52:13 +0200 + +libnl (0.99+1.0.svn21-2) unstable; urgency=low + + * Initial upload to unstable. + * Renamed libnl1 to libnl1-pre6 to match the currently used so-name. + Otherwise dependent packages like NM will break on upgrades of libnl. + + -- Michael Biebl Tue, 7 Mar 2006 21:22:09 +0100 + +libnl (0.99+1.0.svn21-1) experimental; urgency=low + + * Initial release. Closes: #286847 + + -- Michael Biebl Tue, 21 Feb 2006 18:36:35 +0100 diff --git a/src/libnl3/debian/compat b/src/libnl3/debian/compat new file mode 100644 index 000000000000..ec635144f600 --- /dev/null +++ b/src/libnl3/debian/compat @@ -0,0 +1 @@ +9 diff --git a/src/libnl3/debian/control b/src/libnl3/debian/control new file mode 100644 index 000000000000..ba5062607bc1 --- /dev/null +++ b/src/libnl3/debian/control @@ -0,0 +1,245 @@ +Source: libnl3 +Section: net +Priority: optional +Maintainer: Heiko Stuebner +Build-Depends: debhelper (>= 9), dh-exec (>= 0.3), cdbs (>= 0.4.93~), bison, flex, + automake, autoconf, dh-autoreconf, linux-libc-dev (>= 3.2.41), pkg-config +Standards-Version: 3.9.6 +Homepage: http://www.infradead.org/~tgr/libnl/ +#Vcs-Git: https://github.com/thom311/libnl/ +#Vcs-Browser: https://github.com/thom311/libnl/ + +Package: libnl-3-200 +Architecture: linux-any +Section: libs +Pre-Depends: ${misc:Pre-Depends} +Depends: ${misc:Depends}, ${shlibs:Depends} +Multi-Arch: same +Description: library for dealing with netlink sockets + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + +Package: libnl-cli-3-200 +Architecture: linux-any +Section: libs +Pre-Depends: ${misc:Pre-Depends} +Depends: libnl-3-200 (= ${binary:Version}), libnl-genl-3-200 (= ${binary:Version}), libnl-nf-3-200 (= ${binary:Version}), libnl-route-3-200 (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} +Multi-Arch: same +Description: library for dealing with netlink sockets - cli helpers + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + Library for cli helpers in libnl-utils. + +Package: libnl-utils +Architecture: linux-any +Section: libs +Depends: libnl-cli-3-200 (= ${binary:Version}), libnl-idiag-3-200 (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} +Description: Utilities for dealing with netlink sockets + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + These utilities help dealing with netlink sockets. + +Package: libnl-genl-3-200 +Architecture: linux-any +Section: libs +Pre-Depends: ${misc:Pre-Depends} +Depends: libnl-3-200 (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} +Multi-Arch: same +Description: library for dealing with netlink sockets - generic netlink + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + API to the generic netlink protocol, an extended version of the netlink + protocol. + +Package: libnl-idiag-3-200 +Architecture: linux-any +Section: libs +Pre-Depends: ${misc:Pre-Depends} +Depends: libnl-3-200 (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} +Multi-Arch: same +Description: library for dealing with netlink sockets - inetdiag interface + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + API to the inetdiag netlink protocol, handling inetdiag requests + +Package: libnl-nf-3-200 +Architecture: linux-any +Section: libs +Pre-Depends: ${misc:Pre-Depends} +Depends: libnl-3-200 (= ${binary:Version}), libnl-route-3-200 (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} +Multi-Arch: same +Description: library for dealing with netlink sockets - netfilter interface + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + API to netlink based netfilter configuration and monitoring interfaces. + +Package: libnl-route-3-200 +Architecture: linux-any +Section: libs +Pre-Depends: ${misc:Pre-Depends} +Depends: libnl-3-200 (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} +Multi-Arch: same +Description: library for dealing with netlink sockets - route interface + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + API to the configuration interfaces of the NETLINK_ROUTE family. + +Package: libnl-xfrm-3-200 +Architecture: linux-any +Section: libs +Pre-Depends: ${misc:Pre-Depends} +Depends: libnl-3-200 (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} +Multi-Arch: same +Description: library for dealing with netlink sockets - package transformations + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + API to netlink based package transformations (such as encrypting + their payloads). + +Package: libnl-3-dev +Architecture: linux-any +Section: libdevel +Depends: libnl-3-200 (= ${binary:Version}), ${misc:Depends} +Conflicts: libnl-dev, libnl2-dev +Breaks: libnl3-dev +Replaces: libnl3-dev +Multi-Arch: same +Description: development library and headers for libnl-3 + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + This package contains the headers needed by all libraries and the files + that are needed to build applications using libnl3. + +Package: libnl-cli-3-dev +Architecture: linux-any +Section: libdevel +Depends: libnl-3-dev (= ${binary:Version}), libnl-genl-3-dev (= ${binary:Version}), libnl-nf-3-dev (= ${binary:Version}), libnl-route-3-dev (= ${binary:Version}), libnl-cli-3-200 (= ${binary:Version}), ${misc:Depends} +Multi-Arch: same +Description: development library and headers for libnl-cli-3 + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + This package contains the files that are needed to build applications using + libnl-cli-3. + +Package: libnl-genl-3-dev +Architecture: linux-any +Section: libdevel +Depends: libnl-3-dev (= ${binary:Version}), libnl-genl-3-200 (= ${binary:Version}), ${misc:Depends} +Multi-Arch: same +Description: development library and headers for libnl-genl-3 + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + This package contains the files that are needed to build applications using + libnl-genl-3. + +Package: libnl-idiag-3-dev +Architecture: linux-any +Section: libdevel +Depends: libnl-3-dev (= ${binary:Version}), libnl-idiag-3-200 (= ${binary:Version}), ${misc:Depends} +Multi-Arch: same +Description: development library and headers for libnl-genl-3 + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + This package contains the files that are needed to build applications using + libnl-idiag-3. + +Package: libnl-nf-3-dev +Architecture: linux-any +Section: libdevel +Depends: libnl-3-dev (= ${binary:Version}), libnl-route-3-dev (= ${binary:Version}), libnl-nf-3-200 (= ${binary:Version}), ${misc:Depends} +Multi-Arch: same +Description: development library and headers for libnl-nf-3 + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + This package contains the files that are needed to build applications using + libnl-nf-3. + +Package: libnl-route-3-dev +Architecture: linux-any +Section: libdevel +Depends: libnl-3-dev (= ${binary:Version}), libnl-route-3-200 (= ${binary:Version}), ${misc:Depends} +Multi-Arch: same +Description: development library and headers for libnl-route-3 + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + This package contains the files that are needed to build applications using + libnl-route-3. + +Package: libnl-xfrm-3-dev +Architecture: linux-any +Section: libdevel +Depends: libnl-3-dev (= ${binary:Version}), libnl-xfrm-3-200 (= ${binary:Version}), ${misc:Depends} +Multi-Arch: same +Description: development library and headers for libnl-xfrm-3 + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + This package contains the files that are needed to build applications using + libnl-xfrm-3. + +Package: libnl-3-200-dbg +Architecture: linux-any +Section: debug +Depends: libnl-3-200 (= ${binary:Version}), ${misc:Depends} +Priority: extra +Description: debug symbols for libnl3 + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + This package contains unstripped shared libraries. It is provided primarily + to provide a backtrace with names in a debugger, this makes it somewhat easier + to interpret core dumps. The libraries are installed in /usr/lib/debug and + are automatically used by gdb. + +Package: libnl-3-200-udeb +Architecture: linux-any +XC-Package-Type: udeb +Section: debian-installer +Depends: ${misc:Depends}, ${shlibs:Depends} +Description: library for dealing with netlink sockets + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + This package is a udeb. It's only useful inside of debian-installer. + +Package: libnl-genl-3-200-udeb +Architecture: linux-any +XC-Package-Type: udeb +Section: debian-installer +Depends: libnl-3-200-udeb (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends} +Description: library for dealing with netlink sockets - generic netlink + This is a library for applications dealing with netlink sockets. + The library provides an interface for raw netlink messaging and various + netlink family specific interfaces. + . + This package is a udeb. It's only useful inside of debian-installer. diff --git a/src/libnl3/debian/copyright b/src/libnl3/debian/copyright new file mode 100644 index 000000000000..07457363bf67 --- /dev/null +++ b/src/libnl3/debian/copyright @@ -0,0 +1,160 @@ +This package was debianized by Tamer Ahmed on +Tue, 31 Decn 2019 12:00:46 +0000. +The packaging is based on Heiko Stuebner's original packaging +of libnl1. + +It was downloaded from https://github.com/thom311/libnl/releases + +Upstream Author: + Thomas Graf + + +Copyright: + +lib/route/addr.c +include/netlink/route/addr.h + + Copyright (c) Thomas Graf + Baruch Even + + +lib/route/cls/u32.c +lib/route/cls/fw.c +lib/route/sch/htb.c +include/netlink/route/cls/fw.h +include/netlink/route/sch/htb.h + + Copyright (c) Thomas Graf + Copyright (c) Petr Gotthard + Copyright (c) Siemens AG Oesterreich + + + +lib/netfilter/log_msg.c +lib/netfilter/ct.c +include/netlink/netfilter/log_msg.h +include/netlink/netfilter/log.h +lib/netfilter/log_obj.c + + Copyright (c) Thomas Graf + Copyright (c) Philip Craig + Copyright (c) Patrick McHardy + Copyright (c) Secure Computing Corporation + + + +include/netlink/netfilter/queue_msg.h +lib/netfilter/queue_msg_obj.c +lib/netfilter/queue_msg.c +lib/netfilter/queue.c +lib/netfilter/netfilter.c +lib/netfilter/queue_obj.c +include/netlink/netfilter/netfilter.h +include/netlink/netfilter/queue.h +src/nf-queue.c + + Copyright (c) Patrick McHardy + + + +include/netlink/xfrm/selector.h +include/netlink/xfrm/sa.h +include/netlink/xfrm/ae.h +include/netlink/xfrm/sp.h +include/netlink/xfrm/template.h +include/netlink/xfrm/lifetime.h +lib/xfrm/sa.c +lib/xfrm/template.c +lib/xfrm/ae.c +lib/xfrm/sp.c +lib/xfrm/selector.c +lib/xfrm/lifetime.c + + Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ + + +All other *.c and *.h files not mentioned above are copyright of: + + Copyright (c) 2003-2006 Thomas Graf + + +License: + +src/nl-addr-add.c +src/nl-addr-list.c +src/nl-cls-add.c +src/cls/utils.c +src/cls/cgroup.c +src/cls/utils.h +src/cls/basic.c +src/nl-addr-delete.c: + + This library is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation version 2 of the License. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + +On Debian GNU/Linux systems, the complete text of the GNU General +Public License can be found in /usr/share/common-licenses/GPL-2 + + +include/netlink/xfrm/selector.h +include/netlink/xfrm/sa.h +include/netlink/xfrm/ae.h +include/netlink/xfrm/sp.h +include/netlink/xfrm/template.h +include/netlink/xfrm/lifetime.h +lib/xfrm/sa.c +lib/xfrm/template.c +lib/xfrm/ae.c +lib/xfrm/sp.c +lib/xfrm/selector.c +lib/xfrm/lifetime.c + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the + distribution. + + Neither the name of Texas Instruments Incorporated nor the names of + its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +All other *.c and *.h files not mentioned above: + + This library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation version 2.1 of the License. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + +On Debian GNU/Linux systems, the complete text of the GNU Lesser General +Public License can be found in /usr/share/common-licenses/LGPL-2.1 + diff --git a/src/libnl3/debian/gbp.conf b/src/libnl3/debian/gbp.conf new file mode 100644 index 000000000000..a504bacc7748 --- /dev/null +++ b/src/libnl3/debian/gbp.conf @@ -0,0 +1,16 @@ +# Configuration file for git-buildpackage and friends + +[DEFAULT] +# the default build command: +#builder = debuild -i -I +# the default clean command: +#cleaner = debuild clean +# the default branch for upstream sources: +upstream-branch = upstream-dist +# the default branch for the debian patch: +#debian-branch = master +# the default tag formats used: +#upstream-tag = upstream/%(version)s +#debian-tag = debian/%(version)s +# use pristine-tar: +pristine-tar = true diff --git a/src/libnl3/debian/libnl-3-200-udeb.install b/src/libnl3/debian/libnl-3-200-udeb.install new file mode 100644 index 000000000000..4b3a77ce011d --- /dev/null +++ b/src/libnl3/debian/libnl-3-200-udeb.install @@ -0,0 +1 @@ +usr/lib/*/libnl-3.so.* lib diff --git a/src/libnl3/debian/libnl-3-200.install b/src/libnl3/debian/libnl-3-200.install new file mode 100755 index 000000000000..0a6aa3850b2c --- /dev/null +++ b/src/libnl3/debian/libnl-3-200.install @@ -0,0 +1,3 @@ +#!/usr/bin/dh-exec +debian/tmp/usr/lib/${DEB_HOST_MULTIARCH}/libnl-3*.so.* lib/${DEB_HOST_MULTIARCH}/ +debian/tmp/etc/libnl/* etc/libnl-3 diff --git a/src/libnl3/debian/libnl-3-200.symbols b/src/libnl3/debian/libnl-3-200.symbols new file mode 100644 index 000000000000..119e0554920f --- /dev/null +++ b/src/libnl3/debian/libnl-3-200.symbols @@ -0,0 +1,661 @@ +libnl-3.so.200 libnl-3-200 #MINVER# + __flags2str@Base 3.5.0-1 + __flags2str@libnl_3 3.5.0-1 + __list_str2type@Base 3.5.0-1 + __list_str2type@libnl_3 3.5.0-1 + __list_type2str@Base 3.5.0-1 + __list_type2str@libnl_3 3.5.0-1 + __nl_cache_mngt_require@Base 3.5.0-1 + __nl_cache_mngt_require@libnl_3 3.5.0-1 + __nl_cache_ops_lookup@Base 3.5.0-1 + __nl_read_num_str_file@Base 3.5.0-1 + __nl_read_num_str_file@libnl_3 3.5.0-1 + __str2flags@Base 3.5.0-1 + __str2flags@libnl_3 3.5.0-1 + __str2type@Base 3.5.0-1 + __str2type@libnl_3 3.5.0-1 + __trans_list_add@Base 3.5.0-1 + __trans_list_add@libnl_3 3.5.0-1 + __trans_list_clear@Base 3.5.0-1 + __trans_list_clear@libnl_3 3.5.0-1 + __type2str@Base 3.5.0-1 + __type2str@libnl_3 3.5.0-1 + _nl_socket_generate_local_port_no_release@Base 3.5.0-1 + _nl_socket_is_local_port_unspecified@Base 3.5.0-1 + _nl_socket_set_local_port_no_release@Base 3.5.0-1 + _nl_socket_used_ports_release_all@Base 3.5.0-1 + _nl_socket_used_ports_set@Base 3.5.0-1 + dump_from_ops@Base 3.5.0-1 + libnl_3@libnl_3 3.5.0-1 + libnl_3_2_26@libnl_3_2_26 3.5.0-1 + libnl_3_2_27@libnl_3_2_27 3.5.0-1 + libnl_3_2_28@libnl_3_2_28 3.5.0-1 + libnl_3_2_29@libnl_3_2_29 3.5.0-1 + libnl_3_5@libnl_3_5 3.5.0-1 + nl_addr2str@Base 3.5.0-1 + nl_addr2str@libnl_3 3.5.0-1 + nl_addr_alloc@Base 3.5.0-1 + nl_addr_alloc@libnl_3 3.5.0-1 + nl_addr_alloc_attr@Base 3.5.0-1 + nl_addr_alloc_attr@libnl_3 3.5.0-1 + nl_addr_build@Base 3.5.0-1 + nl_addr_build@libnl_3 3.5.0-1 + nl_addr_clone@Base 3.5.0-1 + nl_addr_clone@libnl_3 3.5.0-1 + nl_addr_cmp@Base 3.5.0-1 + nl_addr_cmp@libnl_3 3.5.0-1 + nl_addr_cmp_prefix@Base 3.5.0-1 + nl_addr_cmp_prefix@libnl_3 3.5.0-1 + nl_addr_fill_sockaddr@Base 3.5.0-1 + nl_addr_fill_sockaddr@libnl_3 3.5.0-1 + nl_addr_get@Base 3.5.0-1 + nl_addr_get@libnl_3 3.5.0-1 + nl_addr_get_binary_addr@Base 3.5.0-1 + nl_addr_get_binary_addr@libnl_3 3.5.0-1 + nl_addr_get_family@Base 3.5.0-1 + nl_addr_get_family@libnl_3 3.5.0-1 + nl_addr_get_len@Base 3.5.0-1 + nl_addr_get_len@libnl_3 3.5.0-1 + nl_addr_get_prefixlen@Base 3.5.0-1 + nl_addr_get_prefixlen@libnl_3 3.5.0-1 + nl_addr_guess_family@Base 3.5.0-1 + nl_addr_guess_family@libnl_3 3.5.0-1 + nl_addr_info@Base 3.5.0-1 + nl_addr_info@libnl_3 3.5.0-1 + nl_addr_iszero@Base 3.5.0-1 + nl_addr_iszero@libnl_3 3.5.0-1 + nl_addr_parse@Base 3.5.0-1 + nl_addr_parse@libnl_3 3.5.0-1 + nl_addr_put@Base 3.5.0-1 + nl_addr_put@libnl_3 3.5.0-1 + nl_addr_resolve@Base 3.5.0-1 + nl_addr_resolve@libnl_3 3.5.0-1 + nl_addr_set_binary_addr@Base 3.5.0-1 + nl_addr_set_binary_addr@libnl_3 3.5.0-1 + nl_addr_set_family@Base 3.5.0-1 + nl_addr_set_family@libnl_3 3.5.0-1 + nl_addr_set_prefixlen@Base 3.5.0-1 + nl_addr_set_prefixlen@libnl_3 3.5.0-1 + nl_addr_shared@Base 3.5.0-1 + nl_addr_shared@libnl_3 3.5.0-1 + nl_addr_valid@Base 3.5.0-1 + nl_addr_valid@libnl_3 3.5.0-1 + nl_af2str@Base 3.5.0-1 + nl_af2str@libnl_3 3.5.0-1 + nl_auto_complete@Base 3.5.0-1 + nl_auto_complete@libnl_3 3.5.0-1 + nl_cache_add@Base 3.5.0-1 + nl_cache_add@libnl_3 3.5.0-1 + nl_cache_alloc@Base 3.5.0-1 + nl_cache_alloc@libnl_3 3.5.0-1 + nl_cache_alloc_and_fill@Base 3.5.0-1 + nl_cache_alloc_and_fill@libnl_3 3.5.0-1 + nl_cache_alloc_name@Base 3.5.0-1 + nl_cache_alloc_name@libnl_3 3.5.0-1 + nl_cache_clear@Base 3.5.0-1 + nl_cache_clear@libnl_3 3.5.0-1 + nl_cache_clone@Base 3.5.0-1 + nl_cache_clone@libnl_3 3.5.0-1 + nl_cache_dump@Base 3.5.0-1 + nl_cache_dump@libnl_3 3.5.0-1 + nl_cache_dump_filter@Base 3.5.0-1 + nl_cache_dump_filter@libnl_3 3.5.0-1 + nl_cache_find@Base 3.5.0-1 + nl_cache_find@libnl_3 3.5.0-1 + nl_cache_foreach@Base 3.5.0-1 + nl_cache_foreach@libnl_3 3.5.0-1 + nl_cache_foreach_filter@Base 3.5.0-1 + nl_cache_foreach_filter@libnl_3 3.5.0-1 + nl_cache_free@Base 3.5.0-1 + nl_cache_free@libnl_3 3.5.0-1 + nl_cache_get@Base 3.5.0-1 + nl_cache_get@libnl_3 3.5.0-1 + nl_cache_get_first@Base 3.5.0-1 + nl_cache_get_first@libnl_3 3.5.0-1 + nl_cache_get_last@Base 3.5.0-1 + nl_cache_get_last@libnl_3 3.5.0-1 + nl_cache_get_next@Base 3.5.0-1 + nl_cache_get_next@libnl_3 3.5.0-1 + nl_cache_get_ops@Base 3.5.0-1 + nl_cache_get_ops@libnl_3 3.5.0-1 + nl_cache_get_prev@Base 3.5.0-1 + nl_cache_get_prev@libnl_3 3.5.0-1 + nl_cache_include@Base 3.5.0-1 + nl_cache_include@libnl_3 3.5.0-1 + nl_cache_include_v2@libnl_3_2_29 3.5.0-1 + nl_cache_is_empty@Base 3.5.0-1 + nl_cache_is_empty@libnl_3 3.5.0-1 + nl_cache_mark_all@Base 3.5.0-1 + nl_cache_mark_all@libnl_3 3.5.0-1 + nl_cache_mngr_add@Base 3.5.0-1 + nl_cache_mngr_add@libnl_3 3.5.0-1 + nl_cache_mngr_add_cache@Base 3.5.0-1 + nl_cache_mngr_add_cache@libnl_3 3.5.0-1 + nl_cache_mngr_add_cache_v2@libnl_3_2_29 3.5.0-1 + nl_cache_mngr_alloc@Base 3.5.0-1 + nl_cache_mngr_alloc@libnl_3 3.5.0-1 + nl_cache_mngr_data_ready@Base 3.5.0-1 + nl_cache_mngr_data_ready@libnl_3 3.5.0-1 + nl_cache_mngr_free@Base 3.5.0-1 + nl_cache_mngr_free@libnl_3 3.5.0-1 + nl_cache_mngr_get_fd@Base 3.5.0-1 + nl_cache_mngr_get_fd@libnl_3 3.5.0-1 + nl_cache_mngr_info@Base 3.5.0-1 + nl_cache_mngr_info@libnl_3 3.5.0-1 + nl_cache_mngr_poll@Base 3.5.0-1 + nl_cache_mngr_poll@libnl_3 3.5.0-1 + nl_cache_mngt_provide@Base 3.5.0-1 + nl_cache_mngt_provide@libnl_3 3.5.0-1 + nl_cache_mngt_register@Base 3.5.0-1 + nl_cache_mngt_register@libnl_3 3.5.0-1 + nl_cache_mngt_require@Base 3.5.0-1 + nl_cache_mngt_require@libnl_3 3.5.0-1 + nl_cache_mngt_require_safe@Base 3.5.0-1 + nl_cache_mngt_require_safe@libnl_3 3.5.0-1 + nl_cache_mngt_unprovide@Base 3.5.0-1 + nl_cache_mngt_unprovide@libnl_3 3.5.0-1 + nl_cache_mngt_unregister@Base 3.5.0-1 + nl_cache_mngt_unregister@libnl_3 3.5.0-1 + nl_cache_move@Base 3.5.0-1 + nl_cache_move@libnl_3 3.5.0-1 + nl_cache_nitems@Base 3.5.0-1 + nl_cache_nitems@libnl_3 3.5.0-1 + nl_cache_nitems_filter@Base 3.5.0-1 + nl_cache_nitems_filter@libnl_3 3.5.0-1 + nl_cache_ops_associate@Base 3.5.0-1 + nl_cache_ops_associate@libnl_3 3.5.0-1 + nl_cache_ops_associate_safe@Base 3.5.0-1 + nl_cache_ops_associate_safe@libnl_3 3.5.0-1 + nl_cache_ops_foreach@Base 3.5.0-1 + nl_cache_ops_foreach@libnl_3 3.5.0-1 + nl_cache_ops_get@Base 3.5.0-1 + nl_cache_ops_get@libnl_3 3.5.0-1 + nl_cache_ops_lookup@Base 3.5.0-1 + nl_cache_ops_lookup@libnl_3 3.5.0-1 + nl_cache_ops_lookup_safe@Base 3.5.0-1 + nl_cache_ops_lookup_safe@libnl_3 3.5.0-1 + nl_cache_ops_put@Base 3.5.0-1 + nl_cache_ops_put@libnl_3 3.5.0-1 + nl_cache_ops_set_flags@Base 3.5.0-1 + nl_cache_ops_set_flags@libnl_3 3.5.0-1 + nl_cache_parse@Base 3.5.0-1 + nl_cache_parse@libnl_3 3.5.0-1 + nl_cache_parse_and_add@Base 3.5.0-1 + nl_cache_parse_and_add@libnl_3 3.5.0-1 + nl_cache_pickup@Base 3.5.0-1 + nl_cache_pickup@libnl_3 3.5.0-1 + nl_cache_pickup_checkdup@Base 3.5.0-1 + nl_cache_pickup_checkdup@libnl_3 3.5.0-1 + nl_cache_put@Base 3.5.0-1 + nl_cache_put@libnl_3 3.5.0-1 + nl_cache_refill@Base 3.5.0-1 + nl_cache_refill@libnl_3 3.5.0-1 + nl_cache_remove@Base 3.5.0-1 + nl_cache_remove@libnl_3 3.5.0-1 + nl_cache_resync@Base 3.5.0-1 + nl_cache_resync@libnl_3 3.5.0-1 + nl_cache_search@Base 3.5.0-1 + nl_cache_search@libnl_3 3.5.0-1 + nl_cache_set_arg1@Base 3.5.0-1 + nl_cache_set_arg1@libnl_3 3.5.0-1 + nl_cache_set_arg2@Base 3.5.0-1 + nl_cache_set_arg2@libnl_3 3.5.0-1 + nl_cache_set_flags@Base 3.5.0-1 + nl_cache_set_flags@libnl_3 3.5.0-1 + nl_cache_subset@Base 3.5.0-1 + nl_cache_subset@libnl_3 3.5.0-1 + nl_cancel_down_bits@Base 3.5.0-1 + nl_cancel_down_bits@libnl_3 3.5.0-1 + nl_cancel_down_bytes@Base 3.5.0-1 + nl_cancel_down_bytes@libnl_3 3.5.0-1 + nl_cancel_down_us@Base 3.5.0-1 + nl_cancel_down_us@libnl_3 3.5.0-1 + nl_cb_active_type@Base 3.5.0-1 + nl_cb_active_type@libnl_3 3.5.0-1 + nl_cb_alloc@Base 3.5.0-1 + nl_cb_alloc@libnl_3 3.5.0-1 + nl_cb_clone@Base 3.5.0-1 + nl_cb_clone@libnl_3 3.5.0-1 + nl_cb_err@Base 3.5.0-1 + nl_cb_err@libnl_3 3.5.0-1 + nl_cb_get@Base 3.5.0-1 + nl_cb_get@libnl_3 3.5.0-1 + nl_cb_overwrite_recv@Base 3.5.0-1 + nl_cb_overwrite_recv@libnl_3 3.5.0-1 + nl_cb_overwrite_recvmsgs@Base 3.5.0-1 + nl_cb_overwrite_recvmsgs@libnl_3 3.5.0-1 + nl_cb_overwrite_send@Base 3.5.0-1 + nl_cb_overwrite_send@libnl_3 3.5.0-1 + nl_cb_put@Base 3.5.0-1 + nl_cb_put@libnl_3 3.5.0-1 + nl_cb_set@Base 3.5.0-1 + nl_cb_set@libnl_3 3.5.0-1 + nl_cb_set_all@Base 3.5.0-1 + nl_cb_set_all@libnl_3 3.5.0-1 + nl_close@Base 3.5.0-1 + nl_close@libnl_3 3.5.0-1 + nl_complete_msg@Base 3.5.0-1 + nl_complete_msg@libnl_3 3.5.0-1 + nl_connect@Base 3.5.0-1 + nl_connect@libnl_3 3.5.0-1 + nl_data_alloc@Base 3.5.0-1 + nl_data_alloc@libnl_3 3.5.0-1 + nl_data_alloc_attr@Base 3.5.0-1 + nl_data_alloc_attr@libnl_3 3.5.0-1 + nl_data_append@Base 3.5.0-1 + nl_data_append@libnl_3 3.5.0-1 + nl_data_clone@Base 3.5.0-1 + nl_data_clone@libnl_3 3.5.0-1 + nl_data_cmp@Base 3.5.0-1 + nl_data_cmp@libnl_3 3.5.0-1 + nl_data_free@Base 3.5.0-1 + nl_data_free@libnl_3 3.5.0-1 + nl_data_get@Base 3.5.0-1 + nl_data_get@libnl_3 3.5.0-1 + nl_data_get_size@Base 3.5.0-1 + nl_data_get_size@libnl_3 3.5.0-1 + nl_debug@Base 3.5.0-1 + nl_debug@libnl_3 3.5.0-1 + nl_debug_dp@Base 3.5.0-1 + nl_debug_dp@libnl_3 3.5.0-1 + nl_dump@Base 3.5.0-1 + nl_dump@libnl_3 3.5.0-1 + nl_dump_line@Base 3.5.0-1 + nl_dump_line@libnl_3 3.5.0-1 + nl_ether_proto2str@Base 3.5.0-1 + nl_ether_proto2str@libnl_3 3.5.0-1 + nl_get_psched_hz@Base 3.5.0-1 + nl_get_psched_hz@libnl_3 3.5.0-1 + nl_get_user_hz@Base 3.5.0-1 + nl_get_user_hz@libnl_3 3.5.0-1 + nl_geterror@Base 3.5.0-1 + nl_geterror@libnl_3 3.5.0-1 + nl_has_capability@Base 3.5.0-1 + nl_has_capability@libnl_3 3.5.0-1 + nl_hash@Base 3.5.0-1 + nl_hash@libnl_3 3.5.0-1 + nl_hash_any@Base 3.5.0-1 + nl_hash_any@libnl_3 3.5.0-1 + nl_hash_table_add@Base 3.5.0-1 + nl_hash_table_add@libnl_3 3.5.0-1 + nl_hash_table_alloc@Base 3.5.0-1 + nl_hash_table_alloc@libnl_3 3.5.0-1 + nl_hash_table_del@Base 3.5.0-1 + nl_hash_table_del@libnl_3 3.5.0-1 + nl_hash_table_free@Base 3.5.0-1 + nl_hash_table_free@libnl_3 3.5.0-1 + nl_hash_table_lookup@Base 3.5.0-1 + nl_hash_table_lookup@libnl_3 3.5.0-1 + nl_ip_proto2str@Base 3.5.0-1 + nl_ip_proto2str@libnl_3 3.5.0-1 + nl_join_groups@Base 3.5.0-1 + nl_join_groups@libnl_3 3.5.0-1 + nl_llproto2str@Base 3.5.0-1 + nl_llproto2str@libnl_3 3.5.0-1 + nl_msec2str@Base 3.5.0-1 + nl_msec2str@libnl_3 3.5.0-1 + nl_msg_dump@Base 3.5.0-1 + nl_msg_dump@libnl_3 3.5.0-1 + nl_msg_parse@Base 3.5.0-1 + nl_msg_parse@libnl_3 3.5.0-1 + nl_msgtype_lookup@Base 3.5.0-1 + nl_msgtype_lookup@libnl_3 3.5.0-1 + nl_new_line@Base 3.5.0-1 + nl_new_line@libnl_3 3.5.0-1 + nl_nlfamily2str@Base 3.5.0-1 + nl_nlfamily2str@libnl_3 3.5.0-1 + nl_nlmsg_flags2str@Base 3.5.0-1 + nl_nlmsg_flags2str@libnl_3 3.5.0-1 + nl_nlmsgtype2str@Base 3.5.0-1 + nl_nlmsgtype2str@libnl_3 3.5.0-1 + nl_object_alloc@Base 3.5.0-1 + nl_object_alloc@libnl_3 3.5.0-1 + nl_object_alloc_name@Base 3.5.0-1 + nl_object_alloc_name@libnl_3 3.5.0-1 + nl_object_attr_list@Base 3.5.0-1 + nl_object_attr_list@libnl_3 3.5.0-1 + nl_object_attrs2str@Base 3.5.0-1 + nl_object_attrs2str@libnl_3 3.5.0-1 + nl_object_clone@Base 3.5.0-1 + nl_object_clone@libnl_3 3.5.0-1 + nl_object_diff64@libnl_3_2_28 3.5.0-1 + nl_object_diff@Base 3.5.0-1 + nl_object_diff@libnl_3 3.5.0-1 + nl_object_dump@Base 3.5.0-1 + nl_object_dump@libnl_3 3.5.0-1 + nl_object_dump_buf@Base 3.5.0-1 + nl_object_dump_buf@libnl_3 3.5.0-1 + nl_object_free@Base 3.5.0-1 + nl_object_free@libnl_3 3.5.0-1 + nl_object_get@Base 3.5.0-1 + nl_object_get@libnl_3 3.5.0-1 + nl_object_get_cache@Base 3.5.0-1 + nl_object_get_cache@libnl_3 3.5.0-1 + nl_object_get_id_attrs@Base 3.5.0-1 + nl_object_get_id_attrs@libnl_3 3.5.0-1 + nl_object_get_msgtype@Base 3.5.0-1 + nl_object_get_msgtype@libnl_3 3.5.0-1 + nl_object_get_ops@Base 3.5.0-1 + nl_object_get_ops@libnl_3 3.5.0-1 + nl_object_get_refcnt@Base 3.5.0-1 + nl_object_get_refcnt@libnl_3 3.5.0-1 + nl_object_get_type@Base 3.5.0-1 + nl_object_get_type@libnl_3 3.5.0-1 + nl_object_identical@Base 3.5.0-1 + nl_object_identical@libnl_3 3.5.0-1 + nl_object_is_marked@Base 3.5.0-1 + nl_object_is_marked@libnl_3 3.5.0-1 + nl_object_keygen@Base 3.5.0-1 + nl_object_keygen@libnl_3 3.5.0-1 + nl_object_mark@Base 3.5.0-1 + nl_object_mark@libnl_3 3.5.0-1 + nl_object_match_filter@Base 3.5.0-1 + nl_object_match_filter@libnl_3 3.5.0-1 + nl_object_put@Base 3.5.0-1 + nl_object_put@libnl_3 3.5.0-1 + nl_object_shared@Base 3.5.0-1 + nl_object_shared@libnl_3 3.5.0-1 + nl_object_unmark@Base 3.5.0-1 + nl_object_unmark@libnl_3 3.5.0-1 + nl_object_update@Base 3.5.0-1 + nl_object_update@libnl_3 3.5.0-1 + nl_perror@Base 3.5.0-1 + nl_perror@libnl_3 3.5.0-1 + nl_pickup@Base 3.5.0-1 + nl_pickup@libnl_3 3.5.0-1 + nl_pickup_keep_syserr@Base 3.5.0-1 + nl_pickup_keep_syserr@libnl_3 3.5.0-1 + nl_prob2int@Base 3.5.0-1 + nl_prob2int@libnl_3 3.5.0-1 + nl_rate2str@Base 3.5.0-1 + nl_rate2str@libnl_3 3.5.0-1 + nl_recv@Base 3.5.0-1 + nl_recv@libnl_3 3.5.0-1 + nl_recvmsgs@Base 3.5.0-1 + nl_recvmsgs@libnl_3 3.5.0-1 + nl_recvmsgs_default@Base 3.5.0-1 + nl_recvmsgs_default@libnl_3 3.5.0-1 + nl_recvmsgs_report@Base 3.5.0-1 + nl_recvmsgs_report@libnl_3 3.5.0-1 + nl_send@Base 3.5.0-1 + nl_send@libnl_3 3.5.0-1 + nl_send_auto@Base 3.5.0-1 + nl_send_auto@libnl_3 3.5.0-1 + nl_send_auto_complete@Base 3.5.0-1 + nl_send_auto_complete@libnl_3 3.5.0-1 + nl_send_iovec@Base 3.5.0-1 + nl_send_iovec@libnl_3 3.5.0-1 + nl_send_simple@Base 3.5.0-1 + nl_send_simple@libnl_3 3.5.0-1 + nl_send_sync@Base 3.5.0-1 + nl_send_sync@libnl_3 3.5.0-1 + nl_sendmsg@Base 3.5.0-1 + nl_sendmsg@libnl_3 3.5.0-1 + nl_sendto@Base 3.5.0-1 + nl_sendto@libnl_3 3.5.0-1 + nl_size2int@Base 3.5.0-1 + nl_size2int@libnl_3 3.5.0-1 + nl_size2str@Base 3.5.0-1 + nl_size2str@libnl_3 3.5.0-1 + nl_socket_add_membership@Base 3.5.0-1 + nl_socket_add_membership@libnl_3 3.5.0-1 + nl_socket_add_memberships@Base 3.5.0-1 + nl_socket_add_memberships@libnl_3 3.5.0-1 + nl_socket_alloc@Base 3.5.0-1 + nl_socket_alloc@libnl_3 3.5.0-1 + nl_socket_alloc_cb@Base 3.5.0-1 + nl_socket_alloc_cb@libnl_3 3.5.0-1 + nl_socket_disable_auto_ack@Base 3.5.0-1 + nl_socket_disable_auto_ack@libnl_3 3.5.0-1 + nl_socket_disable_msg_peek@Base 3.5.0-1 + nl_socket_disable_msg_peek@libnl_3 3.5.0-1 + nl_socket_disable_seq_check@Base 3.5.0-1 + nl_socket_disable_seq_check@libnl_3 3.5.0-1 + nl_socket_drop_membership@Base 3.5.0-1 + nl_socket_drop_membership@libnl_3 3.5.0-1 + nl_socket_drop_memberships@Base 3.5.0-1 + nl_socket_drop_memberships@libnl_3 3.5.0-1 + nl_socket_enable_auto_ack@Base 3.5.0-1 + nl_socket_enable_auto_ack@libnl_3 3.5.0-1 + nl_socket_enable_msg_peek@Base 3.5.0-1 + nl_socket_enable_msg_peek@libnl_3 3.5.0-1 + nl_socket_free@Base 3.5.0-1 + nl_socket_free@libnl_3 3.5.0-1 + nl_socket_get_cb@Base 3.5.0-1 + nl_socket_get_cb@libnl_3 3.5.0-1 + nl_socket_get_fd@Base 3.5.0-1 + nl_socket_get_fd@libnl_3 3.5.0-1 + nl_socket_get_local_port@Base 3.5.0-1 + nl_socket_get_local_port@libnl_3 3.5.0-1 + nl_socket_get_msg_buf_size@Base 3.5.0-1 + nl_socket_get_msg_buf_size@libnl_3 3.5.0-1 + nl_socket_get_peer_groups@Base 3.5.0-1 + nl_socket_get_peer_groups@libnl_3 3.5.0-1 + nl_socket_get_peer_port@Base 3.5.0-1 + nl_socket_get_peer_port@libnl_3 3.5.0-1 + nl_socket_modify_cb@Base 3.5.0-1 + nl_socket_modify_cb@libnl_3 3.5.0-1 + nl_socket_modify_err_cb@Base 3.5.0-1 + nl_socket_modify_err_cb@libnl_3 3.5.0-1 + nl_socket_recv_pktinfo@Base 3.5.0-1 + nl_socket_recv_pktinfo@libnl_3 3.5.0-1 + nl_socket_set_buffer_size@Base 3.5.0-1 + nl_socket_set_buffer_size@libnl_3 3.5.0-1 + nl_socket_set_cb@Base 3.5.0-1 + nl_socket_set_cb@libnl_3 3.5.0-1 + nl_socket_set_fd@Base 3.5.0-1 + nl_socket_set_fd@libnl_3_2_26 3.5.0-1 + nl_socket_set_local_port@Base 3.5.0-1 + nl_socket_set_local_port@libnl_3 3.5.0-1 + nl_socket_set_msg_buf_size@Base 3.5.0-1 + nl_socket_set_msg_buf_size@libnl_3 3.5.0-1 + nl_socket_set_nonblocking@Base 3.5.0-1 + nl_socket_set_nonblocking@libnl_3 3.5.0-1 + nl_socket_set_passcred@Base 3.5.0-1 + nl_socket_set_passcred@libnl_3 3.5.0-1 + nl_socket_set_peer_groups@Base 3.5.0-1 + nl_socket_set_peer_groups@libnl_3 3.5.0-1 + nl_socket_set_peer_port@Base 3.5.0-1 + nl_socket_set_peer_port@libnl_3 3.5.0-1 + nl_socket_use_seq@Base 3.5.0-1 + nl_socket_use_seq@libnl_3 3.5.0-1 + nl_str2af@Base 3.5.0-1 + nl_str2af@libnl_3 3.5.0-1 + nl_str2ether_proto@Base 3.5.0-1 + nl_str2ether_proto@libnl_3 3.5.0-1 + nl_str2ip_proto@Base 3.5.0-1 + nl_str2ip_proto@libnl_3 3.5.0-1 + nl_str2llproto@Base 3.5.0-1 + nl_str2llproto@libnl_3 3.5.0-1 + nl_str2msec@Base 3.5.0-1 + nl_str2msec@libnl_3 3.5.0-1 + nl_str2nlfamily@Base 3.5.0-1 + nl_str2nlfamily@libnl_3 3.5.0-1 + nl_str2nlmsgtype@Base 3.5.0-1 + nl_str2nlmsgtype@libnl_3 3.5.0-1 + nl_strerror_l@libnl_3_2_29 3.5.0-1 + nl_syserr2nlerr@Base 3.5.0-1 + nl_syserr2nlerr@libnl_3 3.5.0-1 + nl_ticks2us@Base 3.5.0-1 + nl_ticks2us@libnl_3 3.5.0-1 + nl_us2ticks@Base 3.5.0-1 + nl_us2ticks@libnl_3 3.5.0-1 + nl_ver_maj@Base 3.5.0-1 + nl_ver_maj@libnl_3 3.5.0-1 + nl_ver_mic@Base 3.5.0-1 + nl_ver_mic@libnl_3 3.5.0-1 + nl_ver_min@Base 3.5.0-1 + nl_ver_min@libnl_3 3.5.0-1 + nl_ver_num@Base 3.5.0-1 + nl_ver_num@libnl_3 3.5.0-1 + nl_wait_for_ack@Base 3.5.0-1 + nl_wait_for_ack@libnl_3 3.5.0-1 + nla_attr_size@Base 3.5.0-1 + nla_attr_size@libnl_3 3.5.0-1 + nla_data@Base 3.5.0-1 + nla_data@libnl_3 3.5.0-1 + nla_find@Base 3.5.0-1 + nla_find@libnl_3 3.5.0-1 + nla_get_flag@Base 3.5.0-1 + nla_get_flag@libnl_3 3.5.0-1 + nla_get_msecs@Base 3.5.0-1 + nla_get_msecs@libnl_3 3.5.0-1 + nla_get_s16@Base 3.5.0-1 + nla_get_s16@libnl_3_2_27 3.5.0-1 + nla_get_s32@Base 3.5.0-1 + nla_get_s32@libnl_3_2_27 3.5.0-1 + nla_get_s64@Base 3.5.0-1 + nla_get_s64@libnl_3_2_27 3.5.0-1 + nla_get_s8@Base 3.5.0-1 + nla_get_s8@libnl_3_2_27 3.5.0-1 + nla_get_string@Base 3.5.0-1 + nla_get_string@libnl_3 3.5.0-1 + nla_get_u16@Base 3.5.0-1 + nla_get_u16@libnl_3 3.5.0-1 + nla_get_u32@Base 3.5.0-1 + nla_get_u32@libnl_3 3.5.0-1 + nla_get_u64@Base 3.5.0-1 + nla_get_u64@libnl_3 3.5.0-1 + nla_get_u8@Base 3.5.0-1 + nla_get_u8@libnl_3 3.5.0-1 + nla_is_nested@Base 3.5.0-1 + nla_is_nested@libnl_3 3.5.0-1 + nla_len@Base 3.5.0-1 + nla_len@libnl_3 3.5.0-1 + nla_memcmp@Base 3.5.0-1 + nla_memcmp@libnl_3 3.5.0-1 + nla_memcpy@Base 3.5.0-1 + nla_memcpy@libnl_3 3.5.0-1 + nla_nest_cancel@Base 3.5.0-1 + nla_nest_cancel@libnl_3 3.5.0-1 + nla_nest_end@Base 3.5.0-1 + nla_nest_end@libnl_3 3.5.0-1 + nla_nest_end_keep_empty@libnl_3_5 3.5.0-1 + nla_nest_start@Base 3.5.0-1 + nla_nest_start@libnl_3 3.5.0-1 + nla_next@Base 3.5.0-1 + nla_next@libnl_3 3.5.0-1 + nla_ok@Base 3.5.0-1 + nla_ok@libnl_3 3.5.0-1 + nla_padlen@Base 3.5.0-1 + nla_padlen@libnl_3 3.5.0-1 + nla_parse@Base 3.5.0-1 + nla_parse@libnl_3 3.5.0-1 + nla_parse_nested@Base 3.5.0-1 + nla_parse_nested@libnl_3 3.5.0-1 + nla_put@Base 3.5.0-1 + nla_put@libnl_3 3.5.0-1 + nla_put_addr@Base 3.5.0-1 + nla_put_addr@libnl_3 3.5.0-1 + nla_put_data@Base 3.5.0-1 + nla_put_data@libnl_3 3.5.0-1 + nla_put_flag@Base 3.5.0-1 + nla_put_flag@libnl_3 3.5.0-1 + nla_put_msecs@Base 3.5.0-1 + nla_put_msecs@libnl_3 3.5.0-1 + nla_put_nested@Base 3.5.0-1 + nla_put_nested@libnl_3 3.5.0-1 + nla_put_s16@Base 3.5.0-1 + nla_put_s16@libnl_3_2_27 3.5.0-1 + nla_put_s32@Base 3.5.0-1 + nla_put_s32@libnl_3_2_27 3.5.0-1 + nla_put_s64@Base 3.5.0-1 + nla_put_s64@libnl_3_2_27 3.5.0-1 + nla_put_s8@Base 3.5.0-1 + nla_put_s8@libnl_3_2_27 3.5.0-1 + nla_put_string@Base 3.5.0-1 + nla_put_string@libnl_3 3.5.0-1 + nla_put_u16@Base 3.5.0-1 + nla_put_u16@libnl_3 3.5.0-1 + nla_put_u32@Base 3.5.0-1 + nla_put_u32@libnl_3 3.5.0-1 + nla_put_u64@Base 3.5.0-1 + nla_put_u64@libnl_3 3.5.0-1 + nla_put_u8@Base 3.5.0-1 + nla_put_u8@libnl_3 3.5.0-1 + nla_reserve@Base 3.5.0-1 + nla_reserve@libnl_3 3.5.0-1 + nla_strcmp@Base 3.5.0-1 + nla_strcmp@libnl_3 3.5.0-1 + nla_strdup@Base 3.5.0-1 + nla_strdup@libnl_3 3.5.0-1 + nla_strlcpy@Base 3.5.0-1 + nla_strlcpy@libnl_3 3.5.0-1 + nla_total_size@Base 3.5.0-1 + nla_total_size@libnl_3 3.5.0-1 + nla_type@Base 3.5.0-1 + nla_type@libnl_3 3.5.0-1 + nla_validate@Base 3.5.0-1 + nla_validate@libnl_3 3.5.0-1 + nlmsg_alloc@Base 3.5.0-1 + nlmsg_alloc@libnl_3 3.5.0-1 + nlmsg_alloc_simple@Base 3.5.0-1 + nlmsg_alloc_simple@libnl_3 3.5.0-1 + nlmsg_alloc_size@Base 3.5.0-1 + nlmsg_alloc_size@libnl_3 3.5.0-1 + nlmsg_append@Base 3.5.0-1 + nlmsg_append@libnl_3 3.5.0-1 + nlmsg_attrdata@Base 3.5.0-1 + nlmsg_attrdata@libnl_3 3.5.0-1 + nlmsg_attrlen@Base 3.5.0-1 + nlmsg_attrlen@libnl_3 3.5.0-1 + nlmsg_convert@Base 3.5.0-1 + nlmsg_convert@libnl_3 3.5.0-1 + nlmsg_data@Base 3.5.0-1 + nlmsg_data@libnl_3 3.5.0-1 + nlmsg_datalen@Base 3.5.0-1 + nlmsg_datalen@libnl_3 3.5.0-1 + nlmsg_expand@Base 3.5.0-1 + nlmsg_expand@libnl_3 3.5.0-1 + nlmsg_find_attr@Base 3.5.0-1 + nlmsg_find_attr@libnl_3 3.5.0-1 + nlmsg_free@Base 3.5.0-1 + nlmsg_free@libnl_3 3.5.0-1 + nlmsg_get@Base 3.5.0-1 + nlmsg_get@libnl_3 3.5.0-1 + nlmsg_get_creds@Base 3.5.0-1 + nlmsg_get_creds@libnl_3 3.5.0-1 + nlmsg_get_dst@Base 3.5.0-1 + nlmsg_get_dst@libnl_3 3.5.0-1 + nlmsg_get_max_size@Base 3.5.0-1 + nlmsg_get_max_size@libnl_3 3.5.0-1 + nlmsg_get_proto@Base 3.5.0-1 + nlmsg_get_proto@libnl_3 3.5.0-1 + nlmsg_get_src@Base 3.5.0-1 + nlmsg_get_src@libnl_3 3.5.0-1 + nlmsg_hdr@Base 3.5.0-1 + nlmsg_hdr@libnl_3 3.5.0-1 + nlmsg_inherit@Base 3.5.0-1 + nlmsg_inherit@libnl_3 3.5.0-1 + nlmsg_next@Base 3.5.0-1 + nlmsg_next@libnl_3 3.5.0-1 + nlmsg_ok@Base 3.5.0-1 + nlmsg_ok@libnl_3 3.5.0-1 + nlmsg_padlen@Base 3.5.0-1 + nlmsg_padlen@libnl_3 3.5.0-1 + nlmsg_parse@Base 3.5.0-1 + nlmsg_parse@libnl_3 3.5.0-1 + nlmsg_put@Base 3.5.0-1 + nlmsg_put@libnl_3 3.5.0-1 + nlmsg_reserve@Base 3.5.0-1 + nlmsg_reserve@libnl_3 3.5.0-1 + nlmsg_set_creds@Base 3.5.0-1 + nlmsg_set_creds@libnl_3 3.5.0-1 + nlmsg_set_default_size@Base 3.5.0-1 + nlmsg_set_default_size@libnl_3 3.5.0-1 + nlmsg_set_dst@Base 3.5.0-1 + nlmsg_set_dst@libnl_3 3.5.0-1 + nlmsg_set_proto@Base 3.5.0-1 + nlmsg_set_proto@libnl_3 3.5.0-1 + nlmsg_set_src@Base 3.5.0-1 + nlmsg_set_src@libnl_3 3.5.0-1 + nlmsg_size@Base 3.5.0-1 + nlmsg_size@libnl_3 3.5.0-1 + nlmsg_tail@Base 3.5.0-1 + nlmsg_tail@libnl_3 3.5.0-1 + nlmsg_total_size@Base 3.5.0-1 + nlmsg_total_size@libnl_3 3.5.0-1 + nlmsg_valid_hdr@Base 3.5.0-1 + nlmsg_valid_hdr@libnl_3 3.5.0-1 + nlmsg_validate@Base 3.5.0-1 + nlmsg_validate@libnl_3 3.5.0-1 diff --git a/src/libnl3/debian/libnl-3-dev.install b/src/libnl3/debian/libnl-3-dev.install new file mode 100755 index 000000000000..3715b8b22bbd --- /dev/null +++ b/src/libnl3/debian/libnl-3-dev.install @@ -0,0 +1,5 @@ +#!/usr/bin/dh-exec +debian/tmp/usr/include/* +debian/tmp/usr/lib/*/pkgconfig/libnl-3* +debian/tmp/usr/lib/${DEB_HOST_MULTIARCH}/libnl-3.so lib/${DEB_HOST_MULTIARCH}/ +debian/tmp/usr/lib/${DEB_HOST_MULTIARCH}/libnl-3.a lib/${DEB_HOST_MULTIARCH}/ diff --git a/src/libnl3/debian/libnl-cli-3-200.install b/src/libnl3/debian/libnl-cli-3-200.install new file mode 100755 index 000000000000..6735ec9d14b1 --- /dev/null +++ b/src/libnl3/debian/libnl-cli-3-200.install @@ -0,0 +1,4 @@ +#!/usr/bin/dh-exec +debian/tmp/usr/lib/${DEB_HOST_MULTIARCH}/libnl-cli-3*.so.* +debian/tmp/usr/lib/${DEB_HOST_MULTIARCH}/libnl/cli/cls/*.so usr/lib/${DEB_HOST_MULTIARCH}/libnl-3/cli/cls +debian/tmp/usr/lib/${DEB_HOST_MULTIARCH}/libnl/cli/qdisc/*.so usr/lib/${DEB_HOST_MULTIARCH}/libnl-3/cli/qdisc diff --git a/src/libnl3/debian/libnl-cli-3-200.symbols b/src/libnl3/debian/libnl-cli-3-200.symbols new file mode 100644 index 000000000000..2d21c139623c --- /dev/null +++ b/src/libnl3/debian/libnl-cli-3-200.symbols @@ -0,0 +1,226 @@ +basic.so libnl-cli-3-200 #MINVER# +bfifo.so libnl-cli-3-200 #MINVER# +blackhole.so libnl-cli-3-200 #MINVER# +cgroup.so libnl-cli-3-200 #MINVER# +fq_codel.so libnl-cli-3-200 #MINVER# +hfsc.so libnl-cli-3-200 #MINVER# +htb.so libnl-cli-3-200 #MINVER# +ingress.so libnl-cli-3-200 #MINVER# +libnl-cli-3.so.200 libnl-cli-3-200 #MINVER# + libnl_3@libnl_3 3.5.0-1 + libnl_3_2_28@libnl_3_2_28 3.5.0-1 + nl_cli_addr_alloc@Base 3.5.0-1 + nl_cli_addr_alloc@libnl_3 3.5.0-1 + nl_cli_addr_parse@Base 3.5.0-1 + nl_cli_addr_parse@libnl_3 3.5.0-1 + nl_cli_addr_parse_broadcast@Base 3.5.0-1 + nl_cli_addr_parse_broadcast@libnl_3 3.5.0-1 + nl_cli_addr_parse_dev@Base 3.5.0-1 + nl_cli_addr_parse_dev@libnl_3 3.5.0-1 + nl_cli_addr_parse_family@Base 3.5.0-1 + nl_cli_addr_parse_family@libnl_3 3.5.0-1 + nl_cli_addr_parse_label@Base 3.5.0-1 + nl_cli_addr_parse_label@libnl_3 3.5.0-1 + nl_cli_addr_parse_local@Base 3.5.0-1 + nl_cli_addr_parse_local@libnl_3 3.5.0-1 + nl_cli_addr_parse_peer@Base 3.5.0-1 + nl_cli_addr_parse_peer@libnl_3 3.5.0-1 + nl_cli_addr_parse_preferred@Base 3.5.0-1 + nl_cli_addr_parse_preferred@libnl_3 3.5.0-1 + nl_cli_addr_parse_scope@Base 3.5.0-1 + nl_cli_addr_parse_scope@libnl_3 3.5.0-1 + nl_cli_addr_parse_valid@Base 3.5.0-1 + nl_cli_addr_parse_valid@libnl_3 3.5.0-1 + nl_cli_alloc_cache@Base 3.5.0-1 + nl_cli_alloc_cache@libnl_3 3.5.0-1 + nl_cli_alloc_cache_flags@libnl_3_2_28 3.5.0-1 + nl_cli_alloc_socket@Base 3.5.0-1 + nl_cli_alloc_socket@libnl_3 3.5.0-1 + nl_cli_class_alloc@Base 3.5.0-1 + nl_cli_class_alloc@libnl_3 3.5.0-1 + nl_cli_class_alloc_cache@Base 3.5.0-1 + nl_cli_class_alloc_cache@libnl_3 3.5.0-1 + nl_cli_cls_alloc@Base 3.5.0-1 + nl_cli_cls_alloc@libnl_3 3.5.0-1 + nl_cli_cls_alloc_cache@Base 3.5.0-1 + nl_cli_cls_alloc_cache@libnl_3 3.5.0-1 + nl_cli_cls_parse_ematch@Base 3.5.0-1 + nl_cli_cls_parse_ematch@libnl_3 3.5.0-1 + nl_cli_cls_parse_proto@Base 3.5.0-1 + nl_cli_cls_parse_proto@libnl_3 3.5.0-1 + nl_cli_confirm@Base 3.5.0-1 + nl_cli_confirm@libnl_3 3.5.0-1 + nl_cli_connect@Base 3.5.0-1 + nl_cli_connect@libnl_3 3.5.0-1 + nl_cli_ct_alloc@Base 3.5.0-1 + nl_cli_ct_alloc@libnl_3 3.5.0-1 + nl_cli_ct_alloc_cache@Base 3.5.0-1 + nl_cli_ct_alloc_cache@libnl_3 3.5.0-1 + nl_cli_ct_parse_dst@Base 3.5.0-1 + nl_cli_ct_parse_dst@libnl_3 3.5.0-1 + nl_cli_ct_parse_dst_port@Base 3.5.0-1 + nl_cli_ct_parse_dst_port@libnl_3 3.5.0-1 + nl_cli_ct_parse_family@Base 3.5.0-1 + nl_cli_ct_parse_family@libnl_3 3.5.0-1 + nl_cli_ct_parse_id@Base 3.5.0-1 + nl_cli_ct_parse_id@libnl_3 3.5.0-1 + nl_cli_ct_parse_mark@Base 3.5.0-1 + nl_cli_ct_parse_mark@libnl_3 3.5.0-1 + nl_cli_ct_parse_protocol@Base 3.5.0-1 + nl_cli_ct_parse_protocol@libnl_3 3.5.0-1 + nl_cli_ct_parse_src@Base 3.5.0-1 + nl_cli_ct_parse_src@libnl_3 3.5.0-1 + nl_cli_ct_parse_src_port@Base 3.5.0-1 + nl_cli_ct_parse_src_port@libnl_3 3.5.0-1 + nl_cli_ct_parse_status@Base 3.5.0-1 + nl_cli_ct_parse_status@libnl_3 3.5.0-1 + nl_cli_ct_parse_tcp_state@Base 3.5.0-1 + nl_cli_ct_parse_tcp_state@libnl_3 3.5.0-1 + nl_cli_ct_parse_timeout@Base 3.5.0-1 + nl_cli_ct_parse_timeout@libnl_3 3.5.0-1 + nl_cli_ct_parse_use@Base 3.5.0-1 + nl_cli_ct_parse_use@libnl_3 3.5.0-1 + nl_cli_ct_parse_zone@Base 3.5.0-1 + nl_cli_ct_parse_zone@libnl_3 3.5.0-1 + nl_cli_exp_alloc@Base 3.5.0-1 + nl_cli_exp_alloc@libnl_3 3.5.0-1 + nl_cli_exp_alloc_cache@Base 3.5.0-1 + nl_cli_exp_alloc_cache@libnl_3 3.5.0-1 + nl_cli_exp_parse_class@Base 3.5.0-1 + nl_cli_exp_parse_class@libnl_3 3.5.0-1 + nl_cli_exp_parse_dst@Base 3.5.0-1 + nl_cli_exp_parse_dst@libnl_3 3.5.0-1 + nl_cli_exp_parse_dst_port@Base 3.5.0-1 + nl_cli_exp_parse_dst_port@libnl_3 3.5.0-1 + nl_cli_exp_parse_family@Base 3.5.0-1 + nl_cli_exp_parse_family@libnl_3 3.5.0-1 + nl_cli_exp_parse_flags@Base 3.5.0-1 + nl_cli_exp_parse_flags@libnl_3 3.5.0-1 + nl_cli_exp_parse_fn@Base 3.5.0-1 + nl_cli_exp_parse_fn@libnl_3 3.5.0-1 + nl_cli_exp_parse_helper_name@Base 3.5.0-1 + nl_cli_exp_parse_helper_name@libnl_3 3.5.0-1 + nl_cli_exp_parse_icmp_code@Base 3.5.0-1 + nl_cli_exp_parse_icmp_code@libnl_3 3.5.0-1 + nl_cli_exp_parse_icmp_id@Base 3.5.0-1 + nl_cli_exp_parse_icmp_id@libnl_3 3.5.0-1 + nl_cli_exp_parse_icmp_type@Base 3.5.0-1 + nl_cli_exp_parse_icmp_type@libnl_3 3.5.0-1 + nl_cli_exp_parse_id@Base 3.5.0-1 + nl_cli_exp_parse_id@libnl_3 3.5.0-1 + nl_cli_exp_parse_l4protonum@Base 3.5.0-1 + nl_cli_exp_parse_l4protonum@libnl_3 3.5.0-1 + nl_cli_exp_parse_nat_dir@Base 3.5.0-1 + nl_cli_exp_parse_nat_dir@libnl_3 3.5.0-1 + nl_cli_exp_parse_src@Base 3.5.0-1 + nl_cli_exp_parse_src@libnl_3 3.5.0-1 + nl_cli_exp_parse_src_port@Base 3.5.0-1 + nl_cli_exp_parse_src_port@libnl_3 3.5.0-1 + nl_cli_exp_parse_timeout@Base 3.5.0-1 + nl_cli_exp_parse_timeout@libnl_3 3.5.0-1 + nl_cli_exp_parse_zone@Base 3.5.0-1 + nl_cli_exp_parse_zone@libnl_3 3.5.0-1 + nl_cli_fatal@Base 3.5.0-1 + nl_cli_fatal@libnl_3 3.5.0-1 + nl_cli_link_alloc@Base 3.5.0-1 + nl_cli_link_alloc@libnl_3 3.5.0-1 + nl_cli_link_alloc_cache@Base 3.5.0-1 + nl_cli_link_alloc_cache@libnl_3 3.5.0-1 + nl_cli_link_alloc_cache_family@Base 3.5.0-1 + nl_cli_link_alloc_cache_family@libnl_3 3.5.0-1 + nl_cli_link_alloc_cache_family_flags@libnl_3_2_28 3.5.0-1 + nl_cli_link_alloc_cache_flags@libnl_3_2_28 3.5.0-1 + nl_cli_link_parse_family@Base 3.5.0-1 + nl_cli_link_parse_family@libnl_3 3.5.0-1 + nl_cli_link_parse_ifalias@Base 3.5.0-1 + nl_cli_link_parse_ifalias@libnl_3 3.5.0-1 + nl_cli_link_parse_ifindex@Base 3.5.0-1 + nl_cli_link_parse_ifindex@libnl_3 3.5.0-1 + nl_cli_link_parse_mtu@Base 3.5.0-1 + nl_cli_link_parse_mtu@libnl_3 3.5.0-1 + nl_cli_link_parse_name@Base 3.5.0-1 + nl_cli_link_parse_name@libnl_3 3.5.0-1 + nl_cli_link_parse_txqlen@Base 3.5.0-1 + nl_cli_link_parse_txqlen@libnl_3 3.5.0-1 + nl_cli_link_parse_weight@Base 3.5.0-1 + nl_cli_link_parse_weight@libnl_3 3.5.0-1 + nl_cli_load_module@Base 3.5.0-1 + nl_cli_load_module@libnl_3 3.5.0-1 + nl_cli_neigh_alloc@Base 3.5.0-1 + nl_cli_neigh_alloc@libnl_3 3.5.0-1 + nl_cli_neigh_parse_dev@Base 3.5.0-1 + nl_cli_neigh_parse_dev@libnl_3 3.5.0-1 + nl_cli_neigh_parse_dst@Base 3.5.0-1 + nl_cli_neigh_parse_dst@libnl_3 3.5.0-1 + nl_cli_neigh_parse_family@Base 3.5.0-1 + nl_cli_neigh_parse_family@libnl_3 3.5.0-1 + nl_cli_neigh_parse_lladdr@Base 3.5.0-1 + nl_cli_neigh_parse_lladdr@libnl_3 3.5.0-1 + nl_cli_neigh_parse_state@Base 3.5.0-1 + nl_cli_neigh_parse_state@libnl_3 3.5.0-1 + nl_cli_parse_dumptype@Base 3.5.0-1 + nl_cli_parse_dumptype@libnl_3 3.5.0-1 + nl_cli_parse_u32@Base 3.5.0-1 + nl_cli_parse_u32@libnl_3 3.5.0-1 + nl_cli_print_version@Base 3.5.0-1 + nl_cli_print_version@libnl_3 3.5.0-1 + nl_cli_qdisc_alloc@Base 3.5.0-1 + nl_cli_qdisc_alloc@libnl_3 3.5.0-1 + nl_cli_route_alloc@Base 3.5.0-1 + nl_cli_route_alloc@libnl_3 3.5.0-1 + nl_cli_route_alloc_cache@Base 3.5.0-1 + nl_cli_route_alloc_cache@libnl_3 3.5.0-1 + nl_cli_route_parse_dst@Base 3.5.0-1 + nl_cli_route_parse_dst@libnl_3 3.5.0-1 + nl_cli_route_parse_family@Base 3.5.0-1 + nl_cli_route_parse_family@libnl_3 3.5.0-1 + nl_cli_route_parse_iif@Base 3.5.0-1 + nl_cli_route_parse_iif@libnl_3 3.5.0-1 + nl_cli_route_parse_metric@Base 3.5.0-1 + nl_cli_route_parse_metric@libnl_3 3.5.0-1 + nl_cli_route_parse_nexthop@Base 3.5.0-1 + nl_cli_route_parse_nexthop@libnl_3 3.5.0-1 + nl_cli_route_parse_pref_src@Base 3.5.0-1 + nl_cli_route_parse_pref_src@libnl_3 3.5.0-1 + nl_cli_route_parse_prio@Base 3.5.0-1 + nl_cli_route_parse_prio@libnl_3 3.5.0-1 + nl_cli_route_parse_protocol@Base 3.5.0-1 + nl_cli_route_parse_protocol@libnl_3 3.5.0-1 + nl_cli_route_parse_scope@Base 3.5.0-1 + nl_cli_route_parse_scope@libnl_3 3.5.0-1 + nl_cli_route_parse_src@Base 3.5.0-1 + nl_cli_route_parse_src@libnl_3 3.5.0-1 + nl_cli_route_parse_table@Base 3.5.0-1 + nl_cli_route_parse_table@libnl_3 3.5.0-1 + nl_cli_route_parse_type@Base 3.5.0-1 + nl_cli_route_parse_type@libnl_3 3.5.0-1 + nl_cli_rule_alloc@Base 3.5.0-1 + nl_cli_rule_alloc@libnl_3 3.5.0-1 + nl_cli_rule_alloc_cache@Base 3.5.0-1 + nl_cli_rule_alloc_cache@libnl_3 3.5.0-1 + nl_cli_rule_parse_family@Base 3.5.0-1 + nl_cli_rule_parse_family@libnl_3 3.5.0-1 + nl_cli_tc_lookup@Base 3.5.0-1 + nl_cli_tc_lookup@libnl_3 3.5.0-1 + nl_cli_tc_parse_dev@Base 3.5.0-1 + nl_cli_tc_parse_dev@libnl_3 3.5.0-1 + nl_cli_tc_parse_handle@Base 3.5.0-1 + nl_cli_tc_parse_handle@libnl_3 3.5.0-1 + nl_cli_tc_parse_kind@Base 3.5.0-1 + nl_cli_tc_parse_kind@libnl_3 3.5.0-1 + nl_cli_tc_parse_linktype@Base 3.5.0-1 + nl_cli_tc_parse_linktype@libnl_3 3.5.0-1 + nl_cli_tc_parse_mpu@Base 3.5.0-1 + nl_cli_tc_parse_mpu@libnl_3 3.5.0-1 + nl_cli_tc_parse_mtu@Base 3.5.0-1 + nl_cli_tc_parse_mtu@libnl_3 3.5.0-1 + nl_cli_tc_parse_overhead@Base 3.5.0-1 + nl_cli_tc_parse_overhead@libnl_3 3.5.0-1 + nl_cli_tc_parse_parent@Base 3.5.0-1 + nl_cli_tc_parse_parent@libnl_3 3.5.0-1 + nl_cli_tc_register@Base 3.5.0-1 + nl_cli_tc_register@libnl_3 3.5.0-1 + nl_cli_tc_unregister@Base 3.5.0-1 + nl_cli_tc_unregister@libnl_3 3.5.0-1 +pfifo.so libnl-cli-3-200 #MINVER# +plug.so libnl-cli-3-200 #MINVER# diff --git a/src/libnl3/debian/libnl-cli-3-dev.install b/src/libnl3/debian/libnl-cli-3-dev.install new file mode 100644 index 000000000000..66aa3b3d9457 --- /dev/null +++ b/src/libnl3/debian/libnl-cli-3-dev.install @@ -0,0 +1,3 @@ +debian/tmp/usr/lib/*/pkgconfig/libnl-cli-3* +debian/tmp/usr/lib/*/libnl-cli-3*.so +debian/tmp/usr/lib/*/libnl-cli-3*.a diff --git a/src/libnl3/debian/libnl-genl-3-200-udeb.install b/src/libnl3/debian/libnl-genl-3-200-udeb.install new file mode 100755 index 000000000000..cb5597bf74da --- /dev/null +++ b/src/libnl3/debian/libnl-genl-3-200-udeb.install @@ -0,0 +1,2 @@ +#!/usr/bin/dh-exec +usr/lib/${DEB_HOST_MULTIARCH}/libnl-genl-3.so.* lib/${DEB_HOST_MULTIARCH}/ diff --git a/src/libnl3/debian/libnl-genl-3-200.install b/src/libnl3/debian/libnl-genl-3-200.install new file mode 100755 index 000000000000..d9d6fae40b21 --- /dev/null +++ b/src/libnl3/debian/libnl-genl-3-200.install @@ -0,0 +1,2 @@ +#!/usr/bin/dh-exec +debian/tmp/usr/lib/${DEB_HOST_MULTIARCH}/libnl-genl-3*.so.* lib/${DEB_HOST_MULTIARCH}/ diff --git a/src/libnl3/debian/libnl-genl-3-200.symbols b/src/libnl3/debian/libnl-genl-3-200.symbols new file mode 100644 index 000000000000..0eb2e3be4460 --- /dev/null +++ b/src/libnl3/debian/libnl-genl-3-200.symbols @@ -0,0 +1,88 @@ +libnl-genl-3.so.200 libnl-genl-3-200 #MINVER# + genl_connect@Base 3.5.0-1 + genl_connect@libnl_3 3.5.0-1 + genl_ctrl_alloc_cache@Base 3.5.0-1 + genl_ctrl_alloc_cache@libnl_3 3.5.0-1 + genl_ctrl_resolve@Base 3.5.0-1 + genl_ctrl_resolve@libnl_3 3.5.0-1 + genl_ctrl_resolve_grp@Base 3.5.0-1 + genl_ctrl_resolve_grp@libnl_3 3.5.0-1 + genl_ctrl_search@Base 3.5.0-1 + genl_ctrl_search@libnl_3 3.5.0-1 + genl_ctrl_search_by_name@Base 3.5.0-1 + genl_ctrl_search_by_name@libnl_3 3.5.0-1 + genl_family_add_grp@Base 3.5.0-1 + genl_family_add_grp@libnl_3 3.5.0-1 + genl_family_add_op@Base 3.5.0-1 + genl_family_add_op@libnl_3 3.5.0-1 + genl_family_alloc@Base 3.5.0-1 + genl_family_alloc@libnl_3 3.5.0-1 + genl_family_get_hdrsize@Base 3.5.0-1 + genl_family_get_hdrsize@libnl_3 3.5.0-1 + genl_family_get_id@Base 3.5.0-1 + genl_family_get_id@libnl_3 3.5.0-1 + genl_family_get_maxattr@Base 3.5.0-1 + genl_family_get_maxattr@libnl_3 3.5.0-1 + genl_family_get_name@Base 3.5.0-1 + genl_family_get_name@libnl_3 3.5.0-1 + genl_family_get_version@Base 3.5.0-1 + genl_family_get_version@libnl_3 3.5.0-1 + genl_family_ops@Base 3.5.0-1 + genl_family_ops@libnl_3 3.5.0-1 + genl_family_put@Base 3.5.0-1 + genl_family_put@libnl_3 3.5.0-1 + genl_family_set_hdrsize@Base 3.5.0-1 + genl_family_set_hdrsize@libnl_3 3.5.0-1 + genl_family_set_id@Base 3.5.0-1 + genl_family_set_id@libnl_3 3.5.0-1 + genl_family_set_maxattr@Base 3.5.0-1 + genl_family_set_maxattr@libnl_3 3.5.0-1 + genl_family_set_name@Base 3.5.0-1 + genl_family_set_name@libnl_3 3.5.0-1 + genl_family_set_version@Base 3.5.0-1 + genl_family_set_version@libnl_3 3.5.0-1 + genl_handle_msg@Base 3.5.0-1 + genl_handle_msg@libnl_3 3.5.0-1 + genl_mngt_resolve@Base 3.5.0-1 + genl_mngt_resolve@libnl_3 3.5.0-1 + genl_op2name@Base 3.5.0-1 + genl_op2name@libnl_3 3.5.0-1 + genl_ops_resolve@Base 3.5.0-1 + genl_ops_resolve@libnl_3 3.5.0-1 + genl_register@Base 3.5.0-1 + genl_register@libnl_3 3.5.0-1 + genl_register_family@Base 3.5.0-1 + genl_register_family@libnl_3 3.5.0-1 + genl_resolve_id@Base 3.5.0-1 + genl_resolve_id@libnl_3 3.5.0-1 + genl_send_simple@Base 3.5.0-1 + genl_send_simple@libnl_3 3.5.0-1 + genl_unregister@Base 3.5.0-1 + genl_unregister@libnl_3 3.5.0-1 + genl_unregister_family@Base 3.5.0-1 + genl_unregister_family@libnl_3 3.5.0-1 + genlmsg_attrdata@Base 3.5.0-1 + genlmsg_attrdata@libnl_3 3.5.0-1 + genlmsg_attrlen@Base 3.5.0-1 + genlmsg_attrlen@libnl_3 3.5.0-1 + genlmsg_data@Base 3.5.0-1 + genlmsg_data@libnl_3 3.5.0-1 + genlmsg_hdr@Base 3.5.0-1 + genlmsg_hdr@libnl_3 3.5.0-1 + genlmsg_len@Base 3.5.0-1 + genlmsg_len@libnl_3 3.5.0-1 + genlmsg_parse@Base 3.5.0-1 + genlmsg_parse@libnl_3 3.5.0-1 + genlmsg_put@Base 3.5.0-1 + genlmsg_put@libnl_3 3.5.0-1 + genlmsg_user_data@Base 3.5.0-1 + genlmsg_user_data@libnl_3 3.5.0-1 + genlmsg_user_datalen@Base 3.5.0-1 + genlmsg_user_datalen@libnl_3 3.5.0-1 + genlmsg_user_hdr@Base 3.5.0-1 + genlmsg_user_hdr@libnl_3 3.5.0-1 + genlmsg_valid_hdr@Base 3.5.0-1 + genlmsg_valid_hdr@libnl_3 3.5.0-1 + genlmsg_validate@Base 3.5.0-1 + genlmsg_validate@libnl_3 3.5.0-1 + libnl_3@libnl_3 3.5.0-1 diff --git a/src/libnl3/debian/libnl-genl-3-dev.install b/src/libnl3/debian/libnl-genl-3-dev.install new file mode 100755 index 000000000000..cbc6b51ef474 --- /dev/null +++ b/src/libnl3/debian/libnl-genl-3-dev.install @@ -0,0 +1,4 @@ +#!/usr/bin/dh-exec +debian/tmp/usr/lib/*/pkgconfig/libnl-genl-3* +debian/tmp/usr/lib/${DEB_HOST_MULTIARCH}/libnl-genl-3*.so lib/${DEB_HOST_MULTIARCH}/ +debian/tmp/usr/lib/${DEB_HOST_MULTIARCH}/libnl-genl-3*.a lib/${DEB_HOST_MULTIARCH}/ diff --git a/src/libnl3/debian/libnl-idiag-3-200.install b/src/libnl3/debian/libnl-idiag-3-200.install new file mode 100644 index 000000000000..f6d6b8064e5f --- /dev/null +++ b/src/libnl3/debian/libnl-idiag-3-200.install @@ -0,0 +1 @@ +debian/tmp/usr/lib/*/libnl-idiag-3*.so.* diff --git a/src/libnl3/debian/libnl-idiag-3-200.symbols b/src/libnl3/debian/libnl-idiag-3-200.symbols new file mode 100644 index 000000000000..13cf27c7c8ac --- /dev/null +++ b/src/libnl3/debian/libnl-idiag-3-200.symbols @@ -0,0 +1,206 @@ +libnl-idiag-3.so.200 libnl-idiag-3-200 #MINVER# + idiagnl_attrs2str@Base 3.5.0-1 + idiagnl_attrs2str@libnl_3 3.5.0-1 + idiagnl_connect@Base 3.5.0-1 + idiagnl_connect@libnl_3 3.5.0-1 + idiagnl_exts2str@Base 3.5.0-1 + idiagnl_exts2str@libnl_3 3.5.0-1 + idiagnl_meminfo_alloc@Base 3.5.0-1 + idiagnl_meminfo_alloc@libnl_3 3.5.0-1 + idiagnl_meminfo_get@Base 3.5.0-1 + idiagnl_meminfo_get@libnl_3 3.5.0-1 + idiagnl_meminfo_get_fmem@Base 3.5.0-1 + idiagnl_meminfo_get_fmem@libnl_3 3.5.0-1 + idiagnl_meminfo_get_rmem@Base 3.5.0-1 + idiagnl_meminfo_get_rmem@libnl_3 3.5.0-1 + idiagnl_meminfo_get_tmem@Base 3.5.0-1 + idiagnl_meminfo_get_tmem@libnl_3 3.5.0-1 + idiagnl_meminfo_get_wmem@Base 3.5.0-1 + idiagnl_meminfo_get_wmem@libnl_3 3.5.0-1 + idiagnl_meminfo_obj_ops@Base 3.5.0-1 + idiagnl_meminfo_obj_ops@libnl_3 3.5.0-1 + idiagnl_meminfo_put@Base 3.5.0-1 + idiagnl_meminfo_put@libnl_3 3.5.0-1 + idiagnl_meminfo_set_fmem@Base 3.5.0-1 + idiagnl_meminfo_set_fmem@libnl_3 3.5.0-1 + idiagnl_meminfo_set_rmem@Base 3.5.0-1 + idiagnl_meminfo_set_rmem@libnl_3 3.5.0-1 + idiagnl_meminfo_set_tmem@Base 3.5.0-1 + idiagnl_meminfo_set_tmem@libnl_3 3.5.0-1 + idiagnl_meminfo_set_wmem@Base 3.5.0-1 + idiagnl_meminfo_set_wmem@libnl_3 3.5.0-1 + idiagnl_msg_alloc@Base 3.5.0-1 + idiagnl_msg_alloc@libnl_3 3.5.0-1 + idiagnl_msg_alloc_cache@Base 3.5.0-1 + idiagnl_msg_alloc_cache@libnl_3 3.5.0-1 + idiagnl_msg_get@Base 3.5.0-1 + idiagnl_msg_get@libnl_3 3.5.0-1 + idiagnl_msg_get_cong@Base 3.5.0-1 + idiagnl_msg_get_cong@libnl_3 3.5.0-1 + idiagnl_msg_get_dport@Base 3.5.0-1 + idiagnl_msg_get_dport@libnl_3 3.5.0-1 + idiagnl_msg_get_dst@Base 3.5.0-1 + idiagnl_msg_get_dst@libnl_3 3.5.0-1 + idiagnl_msg_get_expires@Base 3.5.0-1 + idiagnl_msg_get_expires@libnl_3 3.5.0-1 + idiagnl_msg_get_family@Base 3.5.0-1 + idiagnl_msg_get_family@libnl_3 3.5.0-1 + idiagnl_msg_get_ifindex@Base 3.5.0-1 + idiagnl_msg_get_ifindex@libnl_3 3.5.0-1 + idiagnl_msg_get_inode@Base 3.5.0-1 + idiagnl_msg_get_inode@libnl_3 3.5.0-1 + idiagnl_msg_get_meminfo@Base 3.5.0-1 + idiagnl_msg_get_meminfo@libnl_3 3.5.0-1 + idiagnl_msg_get_retrans@Base 3.5.0-1 + idiagnl_msg_get_retrans@libnl_3 3.5.0-1 + idiagnl_msg_get_rqueue@Base 3.5.0-1 + idiagnl_msg_get_rqueue@libnl_3 3.5.0-1 + idiagnl_msg_get_shutdown@Base 3.5.0-1 + idiagnl_msg_get_shutdown@libnl_3 3.5.0-1 + idiagnl_msg_get_sport@Base 3.5.0-1 + idiagnl_msg_get_sport@libnl_3 3.5.0-1 + idiagnl_msg_get_src@Base 3.5.0-1 + idiagnl_msg_get_src@libnl_3 3.5.0-1 + idiagnl_msg_get_state@Base 3.5.0-1 + idiagnl_msg_get_state@libnl_3 3.5.0-1 + idiagnl_msg_get_tclass@Base 3.5.0-1 + idiagnl_msg_get_tclass@libnl_3 3.5.0-1 + idiagnl_msg_get_tcpinfo@Base 3.5.0-1 + idiagnl_msg_get_tcpinfo@libnl_3 3.5.0-1 + idiagnl_msg_get_timer@Base 3.5.0-1 + idiagnl_msg_get_timer@libnl_3 3.5.0-1 + idiagnl_msg_get_tos@Base 3.5.0-1 + idiagnl_msg_get_tos@libnl_3 3.5.0-1 + idiagnl_msg_get_uid@Base 3.5.0-1 + idiagnl_msg_get_uid@libnl_3 3.5.0-1 + idiagnl_msg_get_vegasinfo@Base 3.5.0-1 + idiagnl_msg_get_vegasinfo@libnl_3 3.5.0-1 + idiagnl_msg_get_wqueue@Base 3.5.0-1 + idiagnl_msg_get_wqueue@libnl_3 3.5.0-1 + idiagnl_msg_obj_ops@Base 3.5.0-1 + idiagnl_msg_obj_ops@libnl_3 3.5.0-1 + idiagnl_msg_parse@Base 3.5.0-1 + idiagnl_msg_parse@libnl_3 3.5.0-1 + idiagnl_msg_put@Base 3.5.0-1 + idiagnl_msg_put@libnl_3 3.5.0-1 + idiagnl_msg_set_cong@Base 3.5.0-1 + idiagnl_msg_set_cong@libnl_3 3.5.0-1 + idiagnl_msg_set_dport@Base 3.5.0-1 + idiagnl_msg_set_dport@libnl_3 3.5.0-1 + idiagnl_msg_set_dst@Base 3.5.0-1 + idiagnl_msg_set_dst@libnl_3 3.5.0-1 + idiagnl_msg_set_expires@Base 3.5.0-1 + idiagnl_msg_set_expires@libnl_3 3.5.0-1 + idiagnl_msg_set_family@Base 3.5.0-1 + idiagnl_msg_set_family@libnl_3 3.5.0-1 + idiagnl_msg_set_ifindex@Base 3.5.0-1 + idiagnl_msg_set_ifindex@libnl_3 3.5.0-1 + idiagnl_msg_set_inode@Base 3.5.0-1 + idiagnl_msg_set_inode@libnl_3 3.5.0-1 + idiagnl_msg_set_meminfo@Base 3.5.0-1 + idiagnl_msg_set_meminfo@libnl_3 3.5.0-1 + idiagnl_msg_set_retrans@Base 3.5.0-1 + idiagnl_msg_set_retrans@libnl_3 3.5.0-1 + idiagnl_msg_set_rqueue@Base 3.5.0-1 + idiagnl_msg_set_rqueue@libnl_3 3.5.0-1 + idiagnl_msg_set_shutdown@Base 3.5.0-1 + idiagnl_msg_set_shutdown@libnl_3 3.5.0-1 + idiagnl_msg_set_sport@Base 3.5.0-1 + idiagnl_msg_set_sport@libnl_3 3.5.0-1 + idiagnl_msg_set_src@Base 3.5.0-1 + idiagnl_msg_set_src@libnl_3 3.5.0-1 + idiagnl_msg_set_state@Base 3.5.0-1 + idiagnl_msg_set_state@libnl_3 3.5.0-1 + idiagnl_msg_set_tclass@Base 3.5.0-1 + idiagnl_msg_set_tclass@libnl_3 3.5.0-1 + idiagnl_msg_set_tcpinfo@Base 3.5.0-1 + idiagnl_msg_set_tcpinfo@libnl_3 3.5.0-1 + idiagnl_msg_set_timer@Base 3.5.0-1 + idiagnl_msg_set_timer@libnl_3 3.5.0-1 + idiagnl_msg_set_tos@Base 3.5.0-1 + idiagnl_msg_set_tos@libnl_3 3.5.0-1 + idiagnl_msg_set_uid@Base 3.5.0-1 + idiagnl_msg_set_uid@libnl_3 3.5.0-1 + idiagnl_msg_set_vegasinfo@Base 3.5.0-1 + idiagnl_msg_set_vegasinfo@libnl_3 3.5.0-1 + idiagnl_msg_set_wqueue@Base 3.5.0-1 + idiagnl_msg_set_wqueue@libnl_3 3.5.0-1 + idiagnl_req_alloc@Base 3.5.0-1 + idiagnl_req_alloc@libnl_3 3.5.0-1 + idiagnl_req_get@Base 3.5.0-1 + idiagnl_req_get@libnl_3 3.5.0-1 + idiagnl_req_get_dbs@Base 3.5.0-1 + idiagnl_req_get_dbs@libnl_3 3.5.0-1 + idiagnl_req_get_dst@Base 3.5.0-1 + idiagnl_req_get_dst@libnl_3 3.5.0-1 + idiagnl_req_get_ext@Base 3.5.0-1 + idiagnl_req_get_ext@libnl_3 3.5.0-1 + idiagnl_req_get_family@Base 3.5.0-1 + idiagnl_req_get_family@libnl_3 3.5.0-1 + idiagnl_req_get_ifindex@Base 3.5.0-1 + idiagnl_req_get_ifindex@libnl_3 3.5.0-1 + idiagnl_req_get_src@Base 3.5.0-1 + idiagnl_req_get_src@libnl_3 3.5.0-1 + idiagnl_req_get_states@Base 3.5.0-1 + idiagnl_req_get_states@libnl_3 3.5.0-1 + idiagnl_req_obj_ops@Base 3.5.0-1 + idiagnl_req_obj_ops@libnl_3 3.5.0-1 + idiagnl_req_parse@Base 3.5.0-1 + idiagnl_req_parse@libnl_3 3.5.0-1 + idiagnl_req_put@Base 3.5.0-1 + idiagnl_req_put@libnl_3 3.5.0-1 + idiagnl_req_set_dbs@Base 3.5.0-1 + idiagnl_req_set_dbs@libnl_3 3.5.0-1 + idiagnl_req_set_dst@Base 3.5.0-1 + idiagnl_req_set_dst@libnl_3 3.5.0-1 + idiagnl_req_set_ext@Base 3.5.0-1 + idiagnl_req_set_ext@libnl_3 3.5.0-1 + idiagnl_req_set_family@Base 3.5.0-1 + idiagnl_req_set_family@libnl_3 3.5.0-1 + idiagnl_req_set_ifindex@Base 3.5.0-1 + idiagnl_req_set_ifindex@libnl_3 3.5.0-1 + idiagnl_req_set_src@Base 3.5.0-1 + idiagnl_req_set_src@libnl_3 3.5.0-1 + idiagnl_req_set_states@Base 3.5.0-1 + idiagnl_req_set_states@libnl_3 3.5.0-1 + idiagnl_send_simple@Base 3.5.0-1 + idiagnl_send_simple@libnl_3 3.5.0-1 + idiagnl_shutdown2str@Base 3.5.0-1 + idiagnl_shutdown2str@libnl_3 3.5.0-1 + idiagnl_state2str@Base 3.5.0-1 + idiagnl_state2str@libnl_3 3.5.0-1 + idiagnl_str2state@Base 3.5.0-1 + idiagnl_str2state@libnl_3 3.5.0-1 + idiagnl_str2timer@Base 3.5.0-1 + idiagnl_str2timer@libnl_3 3.5.0-1 + idiagnl_tcpopts2str@Base 3.5.0-1 + idiagnl_tcpopts2str@libnl_3 3.5.0-1 + idiagnl_tcpstate2str@Base 3.5.0-1 + idiagnl_tcpstate2str@libnl_3 3.5.0-1 + idiagnl_timer2str@Base 3.5.0-1 + idiagnl_timer2str@libnl_3 3.5.0-1 + idiagnl_vegasinfo_alloc@Base 3.5.0-1 + idiagnl_vegasinfo_alloc@libnl_3 3.5.0-1 + idiagnl_vegasinfo_get@Base 3.5.0-1 + idiagnl_vegasinfo_get@libnl_3 3.5.0-1 + idiagnl_vegasinfo_get_enabled@Base 3.5.0-1 + idiagnl_vegasinfo_get_enabled@libnl_3 3.5.0-1 + idiagnl_vegasinfo_get_minrtt@Base 3.5.0-1 + idiagnl_vegasinfo_get_minrtt@libnl_3 3.5.0-1 + idiagnl_vegasinfo_get_rtt@Base 3.5.0-1 + idiagnl_vegasinfo_get_rtt@libnl_3 3.5.0-1 + idiagnl_vegasinfo_get_rttcnt@Base 3.5.0-1 + idiagnl_vegasinfo_get_rttcnt@libnl_3 3.5.0-1 + idiagnl_vegasinfo_obj_ops@Base 3.5.0-1 + idiagnl_vegasinfo_obj_ops@libnl_3 3.5.0-1 + idiagnl_vegasinfo_put@Base 3.5.0-1 + idiagnl_vegasinfo_put@libnl_3 3.5.0-1 + idiagnl_vegasinfo_set_enabled@Base 3.5.0-1 + idiagnl_vegasinfo_set_enabled@libnl_3 3.5.0-1 + idiagnl_vegasinfo_set_minrtt@Base 3.5.0-1 + idiagnl_vegasinfo_set_minrtt@libnl_3 3.5.0-1 + idiagnl_vegasinfo_set_rtt@Base 3.5.0-1 + idiagnl_vegasinfo_set_rtt@libnl_3 3.5.0-1 + idiagnl_vegasinfo_set_rttcnt@Base 3.5.0-1 + idiagnl_vegasinfo_set_rttcnt@libnl_3 3.5.0-1 + libnl_3@libnl_3 3.5.0-1 diff --git a/src/libnl3/debian/libnl-idiag-3-dev.install b/src/libnl3/debian/libnl-idiag-3-dev.install new file mode 100644 index 000000000000..6f19a6e83d61 --- /dev/null +++ b/src/libnl3/debian/libnl-idiag-3-dev.install @@ -0,0 +1,3 @@ +debian/tmp/usr/lib/*/pkgconfig/libnl-idiag-3* +debian/tmp/usr/lib/*/libnl-idiag-3*.so +debian/tmp/usr/lib/*/libnl-idiag-3*.a diff --git a/src/libnl3/debian/libnl-nf-3-200.install b/src/libnl3/debian/libnl-nf-3-200.install new file mode 100644 index 000000000000..6d65611ed34e --- /dev/null +++ b/src/libnl3/debian/libnl-nf-3-200.install @@ -0,0 +1 @@ +debian/tmp/usr/lib/*/libnl-nf-3*.so.* diff --git a/src/libnl3/debian/libnl-nf-3-200.symbols b/src/libnl3/debian/libnl-nf-3-200.symbols new file mode 100644 index 000000000000..2ce4d2ad0ffc --- /dev/null +++ b/src/libnl3/debian/libnl-nf-3-200.symbols @@ -0,0 +1,620 @@ +libnl-nf-3.so.200 libnl-nf-3-200 #MINVER# + ct_obj_ops@Base 3.5.0-1 + ct_obj_ops@libnl_3 3.5.0-1 + exp_obj_ops@Base 3.5.0-1 + exp_obj_ops@libnl_3 3.5.0-1 + libnl_3@libnl_3 3.5.0-1 + log_msg_obj_ops@Base 3.5.0-1 + log_msg_obj_ops@libnl_3 3.5.0-1 + log_obj_ops@Base 3.5.0-1 + log_obj_ops@libnl_3 3.5.0-1 + nfnl_connect@Base 3.5.0-1 + nfnl_connect@libnl_3 3.5.0-1 + nfnl_ct_add@Base 3.5.0-1 + nfnl_ct_add@libnl_3 3.5.0-1 + nfnl_ct_alloc@Base 3.5.0-1 + nfnl_ct_alloc@libnl_3 3.5.0-1 + nfnl_ct_alloc_cache@Base 3.5.0-1 + nfnl_ct_alloc_cache@libnl_3 3.5.0-1 + nfnl_ct_build_add_request@Base 3.5.0-1 + nfnl_ct_build_add_request@libnl_3 3.5.0-1 + nfnl_ct_build_delete_request@Base 3.5.0-1 + nfnl_ct_build_delete_request@libnl_3 3.5.0-1 + nfnl_ct_build_query_request@Base 3.5.0-1 + nfnl_ct_build_query_request@libnl_3 3.5.0-1 + nfnl_ct_del@Base 3.5.0-1 + nfnl_ct_del@libnl_3 3.5.0-1 + nfnl_ct_dump_request@Base 3.5.0-1 + nfnl_ct_dump_request@libnl_3 3.5.0-1 + nfnl_ct_get@Base 3.5.0-1 + nfnl_ct_get@libnl_3 3.5.0-1 + nfnl_ct_get_bytes@Base 3.5.0-1 + nfnl_ct_get_bytes@libnl_3 3.5.0-1 + nfnl_ct_get_dst@Base 3.5.0-1 + nfnl_ct_get_dst@libnl_3 3.5.0-1 + nfnl_ct_get_dst_port@Base 3.5.0-1 + nfnl_ct_get_dst_port@libnl_3 3.5.0-1 + nfnl_ct_get_family@Base 3.5.0-1 + nfnl_ct_get_family@libnl_3 3.5.0-1 + nfnl_ct_get_icmp_code@Base 3.5.0-1 + nfnl_ct_get_icmp_code@libnl_3 3.5.0-1 + nfnl_ct_get_icmp_id@Base 3.5.0-1 + nfnl_ct_get_icmp_id@libnl_3 3.5.0-1 + nfnl_ct_get_icmp_type@Base 3.5.0-1 + nfnl_ct_get_icmp_type@libnl_3 3.5.0-1 + nfnl_ct_get_id@Base 3.5.0-1 + nfnl_ct_get_id@libnl_3 3.5.0-1 + nfnl_ct_get_mark@Base 3.5.0-1 + nfnl_ct_get_mark@libnl_3 3.5.0-1 + nfnl_ct_get_packets@Base 3.5.0-1 + nfnl_ct_get_packets@libnl_3 3.5.0-1 + nfnl_ct_get_proto@Base 3.5.0-1 + nfnl_ct_get_proto@libnl_3 3.5.0-1 + nfnl_ct_get_src@Base 3.5.0-1 + nfnl_ct_get_src@libnl_3 3.5.0-1 + nfnl_ct_get_src_port@Base 3.5.0-1 + nfnl_ct_get_src_port@libnl_3 3.5.0-1 + nfnl_ct_get_status@Base 3.5.0-1 + nfnl_ct_get_status@libnl_3 3.5.0-1 + nfnl_ct_get_tcp_state@Base 3.5.0-1 + nfnl_ct_get_tcp_state@libnl_3 3.5.0-1 + nfnl_ct_get_timeout@Base 3.5.0-1 + nfnl_ct_get_timeout@libnl_3 3.5.0-1 + nfnl_ct_get_timestamp@Base 3.5.0-1 + nfnl_ct_get_timestamp@libnl_3 3.5.0-1 + nfnl_ct_get_use@Base 3.5.0-1 + nfnl_ct_get_use@libnl_3 3.5.0-1 + nfnl_ct_get_zone@Base 3.5.0-1 + nfnl_ct_get_zone@libnl_3 3.5.0-1 + nfnl_ct_put@Base 3.5.0-1 + nfnl_ct_put@libnl_3 3.5.0-1 + nfnl_ct_query@Base 3.5.0-1 + nfnl_ct_query@libnl_3 3.5.0-1 + nfnl_ct_set_bytes@Base 3.5.0-1 + nfnl_ct_set_bytes@libnl_3 3.5.0-1 + nfnl_ct_set_dst@Base 3.5.0-1 + nfnl_ct_set_dst@libnl_3 3.5.0-1 + nfnl_ct_set_dst_port@Base 3.5.0-1 + nfnl_ct_set_dst_port@libnl_3 3.5.0-1 + nfnl_ct_set_family@Base 3.5.0-1 + nfnl_ct_set_family@libnl_3 3.5.0-1 + nfnl_ct_set_icmp_code@Base 3.5.0-1 + nfnl_ct_set_icmp_code@libnl_3 3.5.0-1 + nfnl_ct_set_icmp_id@Base 3.5.0-1 + nfnl_ct_set_icmp_id@libnl_3 3.5.0-1 + nfnl_ct_set_icmp_type@Base 3.5.0-1 + nfnl_ct_set_icmp_type@libnl_3 3.5.0-1 + nfnl_ct_set_id@Base 3.5.0-1 + nfnl_ct_set_id@libnl_3 3.5.0-1 + nfnl_ct_set_mark@Base 3.5.0-1 + nfnl_ct_set_mark@libnl_3 3.5.0-1 + nfnl_ct_set_packets@Base 3.5.0-1 + nfnl_ct_set_packets@libnl_3 3.5.0-1 + nfnl_ct_set_proto@Base 3.5.0-1 + nfnl_ct_set_proto@libnl_3 3.5.0-1 + nfnl_ct_set_src@Base 3.5.0-1 + nfnl_ct_set_src@libnl_3 3.5.0-1 + nfnl_ct_set_src_port@Base 3.5.0-1 + nfnl_ct_set_src_port@libnl_3 3.5.0-1 + nfnl_ct_set_status@Base 3.5.0-1 + nfnl_ct_set_status@libnl_3 3.5.0-1 + nfnl_ct_set_tcp_state@Base 3.5.0-1 + nfnl_ct_set_tcp_state@libnl_3 3.5.0-1 + nfnl_ct_set_timeout@Base 3.5.0-1 + nfnl_ct_set_timeout@libnl_3 3.5.0-1 + nfnl_ct_set_timestamp@Base 3.5.0-1 + nfnl_ct_set_timestamp@libnl_3 3.5.0-1 + nfnl_ct_set_use@Base 3.5.0-1 + nfnl_ct_set_use@libnl_3 3.5.0-1 + nfnl_ct_set_zone@Base 3.5.0-1 + nfnl_ct_set_zone@libnl_3 3.5.0-1 + nfnl_ct_status2str@Base 3.5.0-1 + nfnl_ct_status2str@libnl_3 3.5.0-1 + nfnl_ct_str2status@Base 3.5.0-1 + nfnl_ct_str2status@libnl_3 3.5.0-1 + nfnl_ct_str2tcp_state@Base 3.5.0-1 + nfnl_ct_str2tcp_state@libnl_3 3.5.0-1 + nfnl_ct_tcp_state2str@Base 3.5.0-1 + nfnl_ct_tcp_state2str@libnl_3 3.5.0-1 + nfnl_ct_test_bytes@Base 3.5.0-1 + nfnl_ct_test_bytes@libnl_3 3.5.0-1 + nfnl_ct_test_dst_port@Base 3.5.0-1 + nfnl_ct_test_dst_port@libnl_3 3.5.0-1 + nfnl_ct_test_icmp_code@Base 3.5.0-1 + nfnl_ct_test_icmp_code@libnl_3 3.5.0-1 + nfnl_ct_test_icmp_id@Base 3.5.0-1 + nfnl_ct_test_icmp_id@libnl_3 3.5.0-1 + nfnl_ct_test_icmp_type@Base 3.5.0-1 + nfnl_ct_test_icmp_type@libnl_3 3.5.0-1 + nfnl_ct_test_id@Base 3.5.0-1 + nfnl_ct_test_id@libnl_3 3.5.0-1 + nfnl_ct_test_mark@Base 3.5.0-1 + nfnl_ct_test_mark@libnl_3 3.5.0-1 + nfnl_ct_test_packets@Base 3.5.0-1 + nfnl_ct_test_packets@libnl_3 3.5.0-1 + nfnl_ct_test_proto@Base 3.5.0-1 + nfnl_ct_test_proto@libnl_3 3.5.0-1 + nfnl_ct_test_src_port@Base 3.5.0-1 + nfnl_ct_test_src_port@libnl_3 3.5.0-1 + nfnl_ct_test_status@Base 3.5.0-1 + nfnl_ct_test_status@libnl_3 3.5.0-1 + nfnl_ct_test_tcp_state@Base 3.5.0-1 + nfnl_ct_test_tcp_state@libnl_3 3.5.0-1 + nfnl_ct_test_timeout@Base 3.5.0-1 + nfnl_ct_test_timeout@libnl_3 3.5.0-1 + nfnl_ct_test_timestamp@Base 3.5.0-1 + nfnl_ct_test_timestamp@libnl_3 3.5.0-1 + nfnl_ct_test_use@Base 3.5.0-1 + nfnl_ct_test_use@libnl_3 3.5.0-1 + nfnl_ct_test_zone@Base 3.5.0-1 + nfnl_ct_test_zone@libnl_3 3.5.0-1 + nfnl_ct_unset_status@Base 3.5.0-1 + nfnl_ct_unset_status@libnl_3 3.5.0-1 + nfnl_exp_add@Base 3.5.0-1 + nfnl_exp_add@libnl_3 3.5.0-1 + nfnl_exp_alloc@Base 3.5.0-1 + nfnl_exp_alloc@libnl_3 3.5.0-1 + nfnl_exp_alloc_cache@Base 3.5.0-1 + nfnl_exp_alloc_cache@libnl_3 3.5.0-1 + nfnl_exp_build_add_request@Base 3.5.0-1 + nfnl_exp_build_add_request@libnl_3 3.5.0-1 + nfnl_exp_build_delete_request@Base 3.5.0-1 + nfnl_exp_build_delete_request@libnl_3 3.5.0-1 + nfnl_exp_build_query_request@Base 3.5.0-1 + nfnl_exp_build_query_request@libnl_3 3.5.0-1 + nfnl_exp_del@Base 3.5.0-1 + nfnl_exp_del@libnl_3 3.5.0-1 + nfnl_exp_dump_request@Base 3.5.0-1 + nfnl_exp_dump_request@libnl_3 3.5.0-1 + nfnl_exp_flags2str@Base 3.5.0-1 + nfnl_exp_flags2str@libnl_3 3.5.0-1 + nfnl_exp_get@Base 3.5.0-1 + nfnl_exp_get@libnl_3 3.5.0-1 + nfnl_exp_get_class@Base 3.5.0-1 + nfnl_exp_get_class@libnl_3 3.5.0-1 + nfnl_exp_get_dst@Base 3.5.0-1 + nfnl_exp_get_dst@libnl_3 3.5.0-1 + nfnl_exp_get_dst_port@Base 3.5.0-1 + nfnl_exp_get_dst_port@libnl_3 3.5.0-1 + nfnl_exp_get_family@Base 3.5.0-1 + nfnl_exp_get_family@libnl_3 3.5.0-1 + nfnl_exp_get_flags@Base 3.5.0-1 + nfnl_exp_get_flags@libnl_3 3.5.0-1 + nfnl_exp_get_fn@Base 3.5.0-1 + nfnl_exp_get_fn@libnl_3 3.5.0-1 + nfnl_exp_get_helper_name@Base 3.5.0-1 + nfnl_exp_get_helper_name@libnl_3 3.5.0-1 + nfnl_exp_get_icmp_code@Base 3.5.0-1 + nfnl_exp_get_icmp_code@libnl_3 3.5.0-1 + nfnl_exp_get_icmp_id@Base 3.5.0-1 + nfnl_exp_get_icmp_id@libnl_3 3.5.0-1 + nfnl_exp_get_icmp_type@Base 3.5.0-1 + nfnl_exp_get_icmp_type@libnl_3 3.5.0-1 + nfnl_exp_get_id@Base 3.5.0-1 + nfnl_exp_get_id@libnl_3 3.5.0-1 + nfnl_exp_get_l4protonum@Base 3.5.0-1 + nfnl_exp_get_l4protonum@libnl_3 3.5.0-1 + nfnl_exp_get_nat_dir@Base 3.5.0-1 + nfnl_exp_get_nat_dir@libnl_3 3.5.0-1 + nfnl_exp_get_src@Base 3.5.0-1 + nfnl_exp_get_src@libnl_3 3.5.0-1 + nfnl_exp_get_src_port@Base 3.5.0-1 + nfnl_exp_get_src_port@libnl_3 3.5.0-1 + nfnl_exp_get_timeout@Base 3.5.0-1 + nfnl_exp_get_timeout@libnl_3 3.5.0-1 + nfnl_exp_get_zone@Base 3.5.0-1 + nfnl_exp_get_zone@libnl_3 3.5.0-1 + nfnl_exp_put@Base 3.5.0-1 + nfnl_exp_put@libnl_3 3.5.0-1 + nfnl_exp_query@Base 3.5.0-1 + nfnl_exp_query@libnl_3 3.5.0-1 + nfnl_exp_set_class@Base 3.5.0-1 + nfnl_exp_set_class@libnl_3 3.5.0-1 + nfnl_exp_set_dst@Base 3.5.0-1 + nfnl_exp_set_dst@libnl_3 3.5.0-1 + nfnl_exp_set_family@Base 3.5.0-1 + nfnl_exp_set_family@libnl_3 3.5.0-1 + nfnl_exp_set_flags@Base 3.5.0-1 + nfnl_exp_set_flags@libnl_3 3.5.0-1 + nfnl_exp_set_fn@Base 3.5.0-1 + nfnl_exp_set_fn@libnl_3 3.5.0-1 + nfnl_exp_set_helper_name@Base 3.5.0-1 + nfnl_exp_set_helper_name@libnl_3 3.5.0-1 + nfnl_exp_set_icmp@Base 3.5.0-1 + nfnl_exp_set_icmp@libnl_3 3.5.0-1 + nfnl_exp_set_id@Base 3.5.0-1 + nfnl_exp_set_id@libnl_3 3.5.0-1 + nfnl_exp_set_l4protonum@Base 3.5.0-1 + nfnl_exp_set_l4protonum@libnl_3 3.5.0-1 + nfnl_exp_set_nat_dir@Base 3.5.0-1 + nfnl_exp_set_nat_dir@libnl_3 3.5.0-1 + nfnl_exp_set_ports@Base 3.5.0-1 + nfnl_exp_set_ports@libnl_3 3.5.0-1 + nfnl_exp_set_src@Base 3.5.0-1 + nfnl_exp_set_src@libnl_3 3.5.0-1 + nfnl_exp_set_timeout@Base 3.5.0-1 + nfnl_exp_set_timeout@libnl_3 3.5.0-1 + nfnl_exp_set_zone@Base 3.5.0-1 + nfnl_exp_set_zone@libnl_3 3.5.0-1 + nfnl_exp_str2flags@Base 3.5.0-1 + nfnl_exp_str2flags@libnl_3 3.5.0-1 + nfnl_exp_test_class@Base 3.5.0-1 + nfnl_exp_test_class@libnl_3 3.5.0-1 + nfnl_exp_test_dst@Base 3.5.0-1 + nfnl_exp_test_dst@libnl_3 3.5.0-1 + nfnl_exp_test_flags@Base 3.5.0-1 + nfnl_exp_test_flags@libnl_3 3.5.0-1 + nfnl_exp_test_fn@Base 3.5.0-1 + nfnl_exp_test_fn@libnl_3 3.5.0-1 + nfnl_exp_test_helper_name@Base 3.5.0-1 + nfnl_exp_test_helper_name@libnl_3 3.5.0-1 + nfnl_exp_test_icmp@Base 3.5.0-1 + nfnl_exp_test_icmp@libnl_3 3.5.0-1 + nfnl_exp_test_id@Base 3.5.0-1 + nfnl_exp_test_id@libnl_3 3.5.0-1 + nfnl_exp_test_l4protonum@Base 3.5.0-1 + nfnl_exp_test_l4protonum@libnl_3 3.5.0-1 + nfnl_exp_test_nat_dir@Base 3.5.0-1 + nfnl_exp_test_nat_dir@libnl_3 3.5.0-1 + nfnl_exp_test_ports@Base 3.5.0-1 + nfnl_exp_test_ports@libnl_3 3.5.0-1 + nfnl_exp_test_src@Base 3.5.0-1 + nfnl_exp_test_src@libnl_3 3.5.0-1 + nfnl_exp_test_timeout@Base 3.5.0-1 + nfnl_exp_test_timeout@libnl_3 3.5.0-1 + nfnl_exp_test_zone@Base 3.5.0-1 + nfnl_exp_test_zone@libnl_3 3.5.0-1 + nfnl_exp_unset_flags@Base 3.5.0-1 + nfnl_exp_unset_flags@libnl_3 3.5.0-1 + nfnl_inet_hook2str@Base 3.5.0-1 + nfnl_inet_hook2str@libnl_3 3.5.0-1 + nfnl_log_alloc@Base 3.5.0-1 + nfnl_log_alloc@libnl_3 3.5.0-1 + nfnl_log_build_change_request@Base 3.5.0-1 + nfnl_log_build_change_request@libnl_3 3.5.0-1 + nfnl_log_build_create_request@Base 3.5.0-1 + nfnl_log_build_create_request@libnl_3 3.5.0-1 + nfnl_log_build_delete_request@Base 3.5.0-1 + nfnl_log_build_delete_request@libnl_3 3.5.0-1 + nfnl_log_build_pf_bind@Base 3.5.0-1 + nfnl_log_build_pf_bind@libnl_3 3.5.0-1 + nfnl_log_build_pf_unbind@Base 3.5.0-1 + nfnl_log_build_pf_unbind@libnl_3 3.5.0-1 + nfnl_log_change@Base 3.5.0-1 + nfnl_log_change@libnl_3 3.5.0-1 + nfnl_log_copy_mode2str@Base 3.5.0-1 + nfnl_log_copy_mode2str@libnl_3 3.5.0-1 + nfnl_log_create@Base 3.5.0-1 + nfnl_log_create@libnl_3 3.5.0-1 + nfnl_log_delete@Base 3.5.0-1 + nfnl_log_delete@libnl_3 3.5.0-1 + nfnl_log_flags2str@Base 3.5.0-1 + nfnl_log_flags2str@libnl_3 3.5.0-1 + nfnl_log_get@Base 3.5.0-1 + nfnl_log_get@libnl_3 3.5.0-1 + nfnl_log_get_alloc_size@Base 3.5.0-1 + nfnl_log_get_alloc_size@libnl_3 3.5.0-1 + nfnl_log_get_copy_mode@Base 3.5.0-1 + nfnl_log_get_copy_mode@libnl_3 3.5.0-1 + nfnl_log_get_copy_range@Base 3.5.0-1 + nfnl_log_get_copy_range@libnl_3 3.5.0-1 + nfnl_log_get_flush_timeout@Base 3.5.0-1 + nfnl_log_get_flush_timeout@libnl_3 3.5.0-1 + nfnl_log_get_group@Base 3.5.0-1 + nfnl_log_get_group@libnl_3 3.5.0-1 + nfnl_log_get_queue_threshold@Base 3.5.0-1 + nfnl_log_get_queue_threshold@libnl_3 3.5.0-1 + nfnl_log_msg_alloc@Base 3.5.0-1 + nfnl_log_msg_alloc@libnl_3 3.5.0-1 + nfnl_log_msg_get@Base 3.5.0-1 + nfnl_log_msg_get@libnl_3 3.5.0-1 + nfnl_log_msg_get_family@Base 3.5.0-1 + nfnl_log_msg_get_family@libnl_3 3.5.0-1 + nfnl_log_msg_get_gid@Base 3.5.0-1 + nfnl_log_msg_get_gid@libnl_3 3.5.0-1 + nfnl_log_msg_get_hook@Base 3.5.0-1 + nfnl_log_msg_get_hook@libnl_3 3.5.0-1 + nfnl_log_msg_get_hwaddr@Base 3.5.0-1 + nfnl_log_msg_get_hwaddr@libnl_3 3.5.0-1 + nfnl_log_msg_get_hwproto@Base 3.5.0-1 + nfnl_log_msg_get_hwproto@libnl_3 3.5.0-1 + nfnl_log_msg_get_indev@Base 3.5.0-1 + nfnl_log_msg_get_indev@libnl_3 3.5.0-1 + nfnl_log_msg_get_mark@Base 3.5.0-1 + nfnl_log_msg_get_mark@libnl_3 3.5.0-1 + nfnl_log_msg_get_outdev@Base 3.5.0-1 + nfnl_log_msg_get_outdev@libnl_3 3.5.0-1 + nfnl_log_msg_get_payload@Base 3.5.0-1 + nfnl_log_msg_get_payload@libnl_3 3.5.0-1 + nfnl_log_msg_get_physindev@Base 3.5.0-1 + nfnl_log_msg_get_physindev@libnl_3 3.5.0-1 + nfnl_log_msg_get_physoutdev@Base 3.5.0-1 + nfnl_log_msg_get_physoutdev@libnl_3 3.5.0-1 + nfnl_log_msg_get_prefix@Base 3.5.0-1 + nfnl_log_msg_get_prefix@libnl_3 3.5.0-1 + nfnl_log_msg_get_seq@Base 3.5.0-1 + nfnl_log_msg_get_seq@libnl_3 3.5.0-1 + nfnl_log_msg_get_seq_global@Base 3.5.0-1 + nfnl_log_msg_get_seq_global@libnl_3 3.5.0-1 + nfnl_log_msg_get_timestamp@Base 3.5.0-1 + nfnl_log_msg_get_timestamp@libnl_3 3.5.0-1 + nfnl_log_msg_get_uid@Base 3.5.0-1 + nfnl_log_msg_get_uid@libnl_3 3.5.0-1 + nfnl_log_msg_put@Base 3.5.0-1 + nfnl_log_msg_put@libnl_3 3.5.0-1 + nfnl_log_msg_set_family@Base 3.5.0-1 + nfnl_log_msg_set_family@libnl_3 3.5.0-1 + nfnl_log_msg_set_gid@Base 3.5.0-1 + nfnl_log_msg_set_gid@libnl_3 3.5.0-1 + nfnl_log_msg_set_hook@Base 3.5.0-1 + nfnl_log_msg_set_hook@libnl_3 3.5.0-1 + nfnl_log_msg_set_hwaddr@Base 3.5.0-1 + nfnl_log_msg_set_hwaddr@libnl_3 3.5.0-1 + nfnl_log_msg_set_hwproto@Base 3.5.0-1 + nfnl_log_msg_set_hwproto@libnl_3 3.5.0-1 + nfnl_log_msg_set_indev@Base 3.5.0-1 + nfnl_log_msg_set_indev@libnl_3 3.5.0-1 + nfnl_log_msg_set_mark@Base 3.5.0-1 + nfnl_log_msg_set_mark@libnl_3 3.5.0-1 + nfnl_log_msg_set_outdev@Base 3.5.0-1 + nfnl_log_msg_set_outdev@libnl_3 3.5.0-1 + nfnl_log_msg_set_payload@Base 3.5.0-1 + nfnl_log_msg_set_payload@libnl_3 3.5.0-1 + nfnl_log_msg_set_physindev@Base 3.5.0-1 + nfnl_log_msg_set_physindev@libnl_3 3.5.0-1 + nfnl_log_msg_set_physoutdev@Base 3.5.0-1 + nfnl_log_msg_set_physoutdev@libnl_3 3.5.0-1 + nfnl_log_msg_set_prefix@Base 3.5.0-1 + nfnl_log_msg_set_prefix@libnl_3 3.5.0-1 + nfnl_log_msg_set_seq@Base 3.5.0-1 + nfnl_log_msg_set_seq@libnl_3 3.5.0-1 + nfnl_log_msg_set_seq_global@Base 3.5.0-1 + nfnl_log_msg_set_seq_global@libnl_3 3.5.0-1 + nfnl_log_msg_set_timestamp@Base 3.5.0-1 + nfnl_log_msg_set_timestamp@libnl_3 3.5.0-1 + nfnl_log_msg_set_uid@Base 3.5.0-1 + nfnl_log_msg_set_uid@libnl_3 3.5.0-1 + nfnl_log_msg_test_gid@Base 3.5.0-1 + nfnl_log_msg_test_gid@libnl_3 3.5.0-1 + nfnl_log_msg_test_hook@Base 3.5.0-1 + nfnl_log_msg_test_hook@libnl_3 3.5.0-1 + nfnl_log_msg_test_hwproto@Base 3.5.0-1 + nfnl_log_msg_test_hwproto@libnl_3 3.5.0-1 + nfnl_log_msg_test_mark@Base 3.5.0-1 + nfnl_log_msg_test_mark@libnl_3 3.5.0-1 + nfnl_log_msg_test_seq@Base 3.5.0-1 + nfnl_log_msg_test_seq@libnl_3 3.5.0-1 + nfnl_log_msg_test_seq_global@Base 3.5.0-1 + nfnl_log_msg_test_seq_global@libnl_3 3.5.0-1 + nfnl_log_msg_test_uid@Base 3.5.0-1 + nfnl_log_msg_test_uid@libnl_3 3.5.0-1 + nfnl_log_pf_bind@Base 3.5.0-1 + nfnl_log_pf_bind@libnl_3 3.5.0-1 + nfnl_log_pf_unbind@Base 3.5.0-1 + nfnl_log_pf_unbind@libnl_3 3.5.0-1 + nfnl_log_put@Base 3.5.0-1 + nfnl_log_put@libnl_3 3.5.0-1 + nfnl_log_set_alloc_size@Base 3.5.0-1 + nfnl_log_set_alloc_size@libnl_3 3.5.0-1 + nfnl_log_set_copy_mode@Base 3.5.0-1 + nfnl_log_set_copy_mode@libnl_3 3.5.0-1 + nfnl_log_set_copy_range@Base 3.5.0-1 + nfnl_log_set_copy_range@libnl_3 3.5.0-1 + nfnl_log_set_flags@Base 3.5.0-1 + nfnl_log_set_flags@libnl_3 3.5.0-1 + nfnl_log_set_flush_timeout@Base 3.5.0-1 + nfnl_log_set_flush_timeout@libnl_3 3.5.0-1 + nfnl_log_set_group@Base 3.5.0-1 + nfnl_log_set_group@libnl_3 3.5.0-1 + nfnl_log_set_queue_threshold@Base 3.5.0-1 + nfnl_log_set_queue_threshold@libnl_3 3.5.0-1 + nfnl_log_str2copy_mode@Base 3.5.0-1 + nfnl_log_str2copy_mode@libnl_3 3.5.0-1 + nfnl_log_str2flags@Base 3.5.0-1 + nfnl_log_str2flags@libnl_3 3.5.0-1 + nfnl_log_test_alloc_size@Base 3.5.0-1 + nfnl_log_test_alloc_size@libnl_3 3.5.0-1 + nfnl_log_test_copy_mode@Base 3.5.0-1 + nfnl_log_test_copy_mode@libnl_3 3.5.0-1 + nfnl_log_test_copy_range@Base 3.5.0-1 + nfnl_log_test_copy_range@libnl_3 3.5.0-1 + nfnl_log_test_flush_timeout@Base 3.5.0-1 + nfnl_log_test_flush_timeout@libnl_3 3.5.0-1 + nfnl_log_test_group@Base 3.5.0-1 + nfnl_log_test_group@libnl_3 3.5.0-1 + nfnl_log_test_queue_threshold@Base 3.5.0-1 + nfnl_log_test_queue_threshold@libnl_3 3.5.0-1 + nfnl_log_unset_flags@Base 3.5.0-1 + nfnl_log_unset_flags@libnl_3 3.5.0-1 + nfnl_queue_alloc@Base 3.5.0-1 + nfnl_queue_alloc@libnl_3 3.5.0-1 + nfnl_queue_build_change_request@Base 3.5.0-1 + nfnl_queue_build_change_request@libnl_3 3.5.0-1 + nfnl_queue_build_create_request@Base 3.5.0-1 + nfnl_queue_build_create_request@libnl_3 3.5.0-1 + nfnl_queue_build_delete_request@Base 3.5.0-1 + nfnl_queue_build_delete_request@libnl_3 3.5.0-1 + nfnl_queue_build_pf_bind@Base 3.5.0-1 + nfnl_queue_build_pf_bind@libnl_3 3.5.0-1 + nfnl_queue_build_pf_unbind@Base 3.5.0-1 + nfnl_queue_build_pf_unbind@libnl_3 3.5.0-1 + nfnl_queue_change@Base 3.5.0-1 + nfnl_queue_change@libnl_3 3.5.0-1 + nfnl_queue_copy_mode2str@Base 3.5.0-1 + nfnl_queue_copy_mode2str@libnl_3 3.5.0-1 + nfnl_queue_create@Base 3.5.0-1 + nfnl_queue_create@libnl_3 3.5.0-1 + nfnl_queue_delete@Base 3.5.0-1 + nfnl_queue_delete@libnl_3 3.5.0-1 + nfnl_queue_get@Base 3.5.0-1 + nfnl_queue_get@libnl_3 3.5.0-1 + nfnl_queue_get_copy_mode@Base 3.5.0-1 + nfnl_queue_get_copy_mode@libnl_3 3.5.0-1 + nfnl_queue_get_copy_range@Base 3.5.0-1 + nfnl_queue_get_copy_range@libnl_3 3.5.0-1 + nfnl_queue_get_group@Base 3.5.0-1 + nfnl_queue_get_group@libnl_3 3.5.0-1 + nfnl_queue_get_maxlen@Base 3.5.0-1 + nfnl_queue_get_maxlen@libnl_3 3.5.0-1 + nfnl_queue_msg_alloc@Base 3.5.0-1 + nfnl_queue_msg_alloc@libnl_3 3.5.0-1 + nfnl_queue_msg_build_verdict@Base 3.5.0-1 + nfnl_queue_msg_build_verdict@libnl_3 3.5.0-1 + nfnl_queue_msg_build_verdict_batch@Base 3.5.0-1 + nfnl_queue_msg_build_verdict_batch@libnl_3 3.5.0-1 + nfnl_queue_msg_get@Base 3.5.0-1 + nfnl_queue_msg_get@libnl_3 3.5.0-1 + nfnl_queue_msg_get_family@Base 3.5.0-1 + nfnl_queue_msg_get_family@libnl_3 3.5.0-1 + nfnl_queue_msg_get_group@Base 3.5.0-1 + nfnl_queue_msg_get_group@libnl_3 3.5.0-1 + nfnl_queue_msg_get_hook@Base 3.5.0-1 + nfnl_queue_msg_get_hook@libnl_3 3.5.0-1 + nfnl_queue_msg_get_hwaddr@Base 3.5.0-1 + nfnl_queue_msg_get_hwaddr@libnl_3 3.5.0-1 + nfnl_queue_msg_get_hwproto@Base 3.5.0-1 + nfnl_queue_msg_get_hwproto@libnl_3 3.5.0-1 + nfnl_queue_msg_get_indev@Base 3.5.0-1 + nfnl_queue_msg_get_indev@libnl_3 3.5.0-1 + nfnl_queue_msg_get_mark@Base 3.5.0-1 + nfnl_queue_msg_get_mark@libnl_3 3.5.0-1 + nfnl_queue_msg_get_outdev@Base 3.5.0-1 + nfnl_queue_msg_get_outdev@libnl_3 3.5.0-1 + nfnl_queue_msg_get_packetid@Base 3.5.0-1 + nfnl_queue_msg_get_packetid@libnl_3 3.5.0-1 + nfnl_queue_msg_get_payload@Base 3.5.0-1 + nfnl_queue_msg_get_payload@libnl_3 3.5.0-1 + nfnl_queue_msg_get_physindev@Base 3.5.0-1 + nfnl_queue_msg_get_physindev@libnl_3 3.5.0-1 + nfnl_queue_msg_get_physoutdev@Base 3.5.0-1 + nfnl_queue_msg_get_physoutdev@libnl_3 3.5.0-1 + nfnl_queue_msg_get_timestamp@Base 3.5.0-1 + nfnl_queue_msg_get_timestamp@libnl_3 3.5.0-1 + nfnl_queue_msg_get_verdict@Base 3.5.0-1 + nfnl_queue_msg_get_verdict@libnl_3 3.5.0-1 + nfnl_queue_msg_put@Base 3.5.0-1 + nfnl_queue_msg_put@libnl_3 3.5.0-1 + nfnl_queue_msg_send_verdict@Base 3.5.0-1 + nfnl_queue_msg_send_verdict@libnl_3 3.5.0-1 + nfnl_queue_msg_send_verdict_batch@Base 3.5.0-1 + nfnl_queue_msg_send_verdict_batch@libnl_3 3.5.0-1 + nfnl_queue_msg_send_verdict_payload@Base 3.5.0-1 + nfnl_queue_msg_send_verdict_payload@libnl_3 3.5.0-1 + nfnl_queue_msg_set_family@Base 3.5.0-1 + nfnl_queue_msg_set_family@libnl_3 3.5.0-1 + nfnl_queue_msg_set_group@Base 3.5.0-1 + nfnl_queue_msg_set_group@libnl_3 3.5.0-1 + nfnl_queue_msg_set_hook@Base 3.5.0-1 + nfnl_queue_msg_set_hook@libnl_3 3.5.0-1 + nfnl_queue_msg_set_hwaddr@Base 3.5.0-1 + nfnl_queue_msg_set_hwaddr@libnl_3 3.5.0-1 + nfnl_queue_msg_set_hwproto@Base 3.5.0-1 + nfnl_queue_msg_set_hwproto@libnl_3 3.5.0-1 + nfnl_queue_msg_set_indev@Base 3.5.0-1 + nfnl_queue_msg_set_indev@libnl_3 3.5.0-1 + nfnl_queue_msg_set_mark@Base 3.5.0-1 + nfnl_queue_msg_set_mark@libnl_3 3.5.0-1 + nfnl_queue_msg_set_outdev@Base 3.5.0-1 + nfnl_queue_msg_set_outdev@libnl_3 3.5.0-1 + nfnl_queue_msg_set_packetid@Base 3.5.0-1 + nfnl_queue_msg_set_packetid@libnl_3 3.5.0-1 + nfnl_queue_msg_set_payload@Base 3.5.0-1 + nfnl_queue_msg_set_payload@libnl_3 3.5.0-1 + nfnl_queue_msg_set_physindev@Base 3.5.0-1 + nfnl_queue_msg_set_physindev@libnl_3 3.5.0-1 + nfnl_queue_msg_set_physoutdev@Base 3.5.0-1 + nfnl_queue_msg_set_physoutdev@libnl_3 3.5.0-1 + nfnl_queue_msg_set_timestamp@Base 3.5.0-1 + nfnl_queue_msg_set_timestamp@libnl_3 3.5.0-1 + nfnl_queue_msg_set_verdict@Base 3.5.0-1 + nfnl_queue_msg_set_verdict@libnl_3 3.5.0-1 + nfnl_queue_msg_test_family@Base 3.5.0-1 + nfnl_queue_msg_test_family@libnl_3 3.5.0-1 + nfnl_queue_msg_test_group@Base 3.5.0-1 + nfnl_queue_msg_test_group@libnl_3 3.5.0-1 + nfnl_queue_msg_test_hook@Base 3.5.0-1 + nfnl_queue_msg_test_hook@libnl_3 3.5.0-1 + nfnl_queue_msg_test_hwaddr@Base 3.5.0-1 + nfnl_queue_msg_test_hwaddr@libnl_3 3.5.0-1 + nfnl_queue_msg_test_hwproto@Base 3.5.0-1 + nfnl_queue_msg_test_hwproto@libnl_3 3.5.0-1 + nfnl_queue_msg_test_indev@Base 3.5.0-1 + nfnl_queue_msg_test_indev@libnl_3 3.5.0-1 + nfnl_queue_msg_test_mark@Base 3.5.0-1 + nfnl_queue_msg_test_mark@libnl_3 3.5.0-1 + nfnl_queue_msg_test_outdev@Base 3.5.0-1 + nfnl_queue_msg_test_outdev@libnl_3 3.5.0-1 + nfnl_queue_msg_test_packetid@Base 3.5.0-1 + nfnl_queue_msg_test_packetid@libnl_3 3.5.0-1 + nfnl_queue_msg_test_payload@Base 3.5.0-1 + nfnl_queue_msg_test_payload@libnl_3 3.5.0-1 + nfnl_queue_msg_test_physindev@Base 3.5.0-1 + nfnl_queue_msg_test_physindev@libnl_3 3.5.0-1 + nfnl_queue_msg_test_physoutdev@Base 3.5.0-1 + nfnl_queue_msg_test_physoutdev@libnl_3 3.5.0-1 + nfnl_queue_msg_test_timestamp@Base 3.5.0-1 + nfnl_queue_msg_test_timestamp@libnl_3 3.5.0-1 + nfnl_queue_msg_test_verdict@Base 3.5.0-1 + nfnl_queue_msg_test_verdict@libnl_3 3.5.0-1 + nfnl_queue_pf_bind@Base 3.5.0-1 + nfnl_queue_pf_bind@libnl_3 3.5.0-1 + nfnl_queue_pf_unbind@Base 3.5.0-1 + nfnl_queue_pf_unbind@libnl_3 3.5.0-1 + nfnl_queue_put@Base 3.5.0-1 + nfnl_queue_put@libnl_3 3.5.0-1 + nfnl_queue_set_copy_mode@Base 3.5.0-1 + nfnl_queue_set_copy_mode@libnl_3 3.5.0-1 + nfnl_queue_set_copy_range@Base 3.5.0-1 + nfnl_queue_set_copy_range@libnl_3 3.5.0-1 + nfnl_queue_set_group@Base 3.5.0-1 + nfnl_queue_set_group@libnl_3 3.5.0-1 + nfnl_queue_set_maxlen@Base 3.5.0-1 + nfnl_queue_set_maxlen@libnl_3 3.5.0-1 + nfnl_queue_socket_alloc@Base 3.5.0-1 + nfnl_queue_socket_alloc@libnl_3 3.5.0-1 + nfnl_queue_str2copy_mode@Base 3.5.0-1 + nfnl_queue_str2copy_mode@libnl_3 3.5.0-1 + nfnl_queue_test_copy_mode@Base 3.5.0-1 + nfnl_queue_test_copy_mode@libnl_3 3.5.0-1 + nfnl_queue_test_copy_range@Base 3.5.0-1 + nfnl_queue_test_copy_range@libnl_3 3.5.0-1 + nfnl_queue_test_group@Base 3.5.0-1 + nfnl_queue_test_group@libnl_3 3.5.0-1 + nfnl_queue_test_maxlen@Base 3.5.0-1 + nfnl_queue_test_maxlen@libnl_3 3.5.0-1 + nfnl_send_simple@Base 3.5.0-1 + nfnl_send_simple@libnl_3 3.5.0-1 + nfnl_str2inet_hook@Base 3.5.0-1 + nfnl_str2inet_hook@libnl_3 3.5.0-1 + nfnl_str2verdict@Base 3.5.0-1 + nfnl_str2verdict@libnl_3 3.5.0-1 + nfnl_verdict2str@Base 3.5.0-1 + nfnl_verdict2str@libnl_3 3.5.0-1 + nfnlmsg_alloc_simple@Base 3.5.0-1 + nfnlmsg_alloc_simple@libnl_3 3.5.0-1 + nfnlmsg_ct_group@Base 3.5.0-1 + nfnlmsg_ct_group@libnl_3 3.5.0-1 + nfnlmsg_ct_parse@Base 3.5.0-1 + nfnlmsg_ct_parse@libnl_3 3.5.0-1 + nfnlmsg_exp_group@Base 3.5.0-1 + nfnlmsg_exp_group@libnl_3 3.5.0-1 + nfnlmsg_exp_parse@Base 3.5.0-1 + nfnlmsg_exp_parse@libnl_3 3.5.0-1 + nfnlmsg_family@Base 3.5.0-1 + nfnlmsg_family@libnl_3 3.5.0-1 + nfnlmsg_log_msg_parse@Base 3.5.0-1 + nfnlmsg_log_msg_parse@libnl_3 3.5.0-1 + nfnlmsg_put@Base 3.5.0-1 + nfnlmsg_put@libnl_3 3.5.0-1 + nfnlmsg_queue_msg_parse@Base 3.5.0-1 + nfnlmsg_queue_msg_parse@libnl_3 3.5.0-1 + nfnlmsg_res_id@Base 3.5.0-1 + nfnlmsg_res_id@libnl_3 3.5.0-1 + nfnlmsg_subsys@Base 3.5.0-1 + nfnlmsg_subsys@libnl_3 3.5.0-1 + nfnlmsg_subtype@Base 3.5.0-1 + nfnlmsg_subtype@libnl_3 3.5.0-1 + queue_msg_obj_ops@Base 3.5.0-1 + queue_msg_obj_ops@libnl_3 3.5.0-1 + queue_obj_ops@Base 3.5.0-1 + queue_obj_ops@libnl_3 3.5.0-1 diff --git a/src/libnl3/debian/libnl-nf-3-dev.install b/src/libnl3/debian/libnl-nf-3-dev.install new file mode 100644 index 000000000000..d1307c751b84 --- /dev/null +++ b/src/libnl3/debian/libnl-nf-3-dev.install @@ -0,0 +1,3 @@ +debian/tmp/usr/lib/*/pkgconfig/libnl-nf-3* +debian/tmp/usr/lib/*/libnl-nf-3*.so +debian/tmp/usr/lib/*/libnl-nf-3*.a diff --git a/src/libnl3/debian/libnl-route-3-200.install b/src/libnl3/debian/libnl-route-3-200.install new file mode 100644 index 000000000000..44c7ec8cdfad --- /dev/null +++ b/src/libnl3/debian/libnl-route-3-200.install @@ -0,0 +1 @@ +debian/tmp/usr/lib/*/libnl-route-3*.so.* diff --git a/src/libnl3/debian/libnl-route-3-200.symbols b/src/libnl3/debian/libnl-route-3-200.symbols new file mode 100644 index 000000000000..e11157ba4e88 --- /dev/null +++ b/src/libnl3/debian/libnl-route-3-200.symbols @@ -0,0 +1,2051 @@ +libnl-route-3.so.200 libnl-route-3-200 #MINVER# + ematch__create_buffer@Base 3.5.0-1 + ematch__delete_buffer@Base 3.5.0-1 + ematch__flush_buffer@Base 3.5.0-1 + ematch__scan_buffer@Base 3.5.0-1 + ematch__scan_bytes@Base 3.5.0-1 + ematch__scan_string@Base 3.5.0-1 + ematch__switch_to_buffer@Base 3.5.0-1 + ematch_alloc@Base 3.5.0-1 + ematch_free@Base 3.5.0-1 + ematch_get_column@Base 3.5.0-1 + ematch_get_debug@Base 3.5.0-1 + ematch_get_extra@Base 3.5.0-1 + ematch_get_in@Base 3.5.0-1 + ematch_get_leng@Base 3.5.0-1 + ematch_get_lineno@Base 3.5.0-1 + ematch_get_lval@Base 3.5.0-1 + ematch_get_out@Base 3.5.0-1 + ematch_get_text@Base 3.5.0-1 + ematch_lex@Base 3.5.0-1 + ematch_lex_destroy@Base 3.5.0-1 + ematch_lex_init@Base 3.5.0-1 + ematch_lex_init_extra@Base 3.5.0-1 + ematch_parse@Base 3.5.0-1 + ematch_pop_buffer_state@Base 3.5.0-1 + ematch_push_buffer_state@Base 3.5.0-1 + ematch_realloc@Base 3.5.0-1 + ematch_restart@Base 3.5.0-1 + ematch_set_column@Base 3.5.0-1 + ematch_set_debug@Base 3.5.0-1 + ematch_set_extra@Base 3.5.0-1 + ematch_set_in@Base 3.5.0-1 + ematch_set_lineno@Base 3.5.0-1 + ematch_set_lval@Base 3.5.0-1 + ematch_set_out@Base 3.5.0-1 + flnl_lookup@Base 3.5.0-1 + flnl_lookup@libnl_3 3.5.0-1 + flnl_lookup_build_request@Base 3.5.0-1 + flnl_lookup_build_request@libnl_3 3.5.0-1 + flnl_request_alloc@Base 3.5.0-1 + flnl_request_alloc@libnl_3 3.5.0-1 + flnl_request_get_addr@Base 3.5.0-1 + flnl_request_get_addr@libnl_3 3.5.0-1 + flnl_request_get_fwmark@Base 3.5.0-1 + flnl_request_get_fwmark@libnl_3 3.5.0-1 + flnl_request_get_scope@Base 3.5.0-1 + flnl_request_get_scope@libnl_3 3.5.0-1 + flnl_request_get_table@Base 3.5.0-1 + flnl_request_get_table@libnl_3 3.5.0-1 + flnl_request_get_tos@Base 3.5.0-1 + flnl_request_get_tos@libnl_3 3.5.0-1 + flnl_request_set_addr@Base 3.5.0-1 + flnl_request_set_addr@libnl_3 3.5.0-1 + flnl_request_set_fwmark@Base 3.5.0-1 + flnl_request_set_fwmark@libnl_3 3.5.0-1 + flnl_request_set_scope@Base 3.5.0-1 + flnl_request_set_scope@libnl_3 3.5.0-1 + flnl_request_set_table@Base 3.5.0-1 + flnl_request_set_table@libnl_3 3.5.0-1 + flnl_request_set_tos@Base 3.5.0-1 + flnl_request_set_tos@libnl_3 3.5.0-1 + flnl_result_alloc@Base 3.5.0-1 + flnl_result_alloc@libnl_3 3.5.0-1 + flnl_result_alloc_cache@Base 3.5.0-1 + flnl_result_alloc_cache@libnl_3 3.5.0-1 + flnl_result_get_error@Base 3.5.0-1 + flnl_result_get_error@libnl_3 3.5.0-1 + flnl_result_get_nexthop_sel@Base 3.5.0-1 + flnl_result_get_nexthop_sel@libnl_3 3.5.0-1 + flnl_result_get_prefixlen@Base 3.5.0-1 + flnl_result_get_prefixlen@libnl_3 3.5.0-1 + flnl_result_get_scope@Base 3.5.0-1 + flnl_result_get_scope@libnl_3 3.5.0-1 + flnl_result_get_table_id@Base 3.5.0-1 + flnl_result_get_table_id@libnl_3 3.5.0-1 + flnl_result_get_type@Base 3.5.0-1 + flnl_result_get_type@libnl_3 3.5.0-1 + flnl_result_put@Base 3.5.0-1 + flnl_result_put@libnl_3 3.5.0-1 + libnl_3@libnl_3 3.5.0-1 + libnl_3_2_26@libnl_3_2_26 3.5.0-1 + libnl_3_2_27@libnl_3_2_27 3.5.0-1 + libnl_3_2_28@libnl_3_2_28 3.5.0-1 + libnl_3_2_29@libnl_3_2_29 3.5.0-1 + libnl_3_4@libnl_3_4 3.5.0-1 + libnl_3_5@libnl_3_5 3.5.0-1 + nl_ovl_strategy2str@Base 3.5.0-1 + nl_ovl_strategy2str@libnl_3 3.5.0-1 + nl_police2str@Base 3.5.0-1 + nl_police2str@libnl_3 3.5.0-1 + nl_rtgen_request@Base 3.5.0-1 + nl_rtgen_request@libnl_3 3.5.0-1 + nl_rtntype2str@Base 3.5.0-1 + nl_rtntype2str@libnl_3 3.5.0-1 + nl_str2ovl_strategy@Base 3.5.0-1 + nl_str2ovl_strategy@libnl_3 3.5.0-1 + nl_str2police@Base 3.5.0-1 + nl_str2police@libnl_3 3.5.0-1 + nl_str2rtntype@Base 3.5.0-1 + nl_str2rtntype@libnl_3 3.5.0-1 + pktloc__create_buffer@Base 3.5.0-1 + pktloc__delete_buffer@Base 3.5.0-1 + pktloc__flush_buffer@Base 3.5.0-1 + pktloc__scan_buffer@Base 3.5.0-1 + pktloc__scan_bytes@Base 3.5.0-1 + pktloc__scan_string@Base 3.5.0-1 + pktloc__switch_to_buffer@Base 3.5.0-1 + pktloc_alloc@Base 3.5.0-1 + pktloc_free@Base 3.5.0-1 + pktloc_get_column@Base 3.5.0-1 + pktloc_get_debug@Base 3.5.0-1 + pktloc_get_extra@Base 3.5.0-1 + pktloc_get_in@Base 3.5.0-1 + pktloc_get_leng@Base 3.5.0-1 + pktloc_get_lineno@Base 3.5.0-1 + pktloc_get_lloc@Base 3.5.0-1 + pktloc_get_lval@Base 3.5.0-1 + pktloc_get_out@Base 3.5.0-1 + pktloc_get_text@Base 3.5.0-1 + pktloc_lex@Base 3.5.0-1 + pktloc_lex_destroy@Base 3.5.0-1 + pktloc_lex_init@Base 3.5.0-1 + pktloc_lex_init_extra@Base 3.5.0-1 + pktloc_parse@Base 3.5.0-1 + pktloc_pop_buffer_state@Base 3.5.0-1 + pktloc_push_buffer_state@Base 3.5.0-1 + pktloc_realloc@Base 3.5.0-1 + pktloc_restart@Base 3.5.0-1 + pktloc_set_column@Base 3.5.0-1 + pktloc_set_debug@Base 3.5.0-1 + pktloc_set_extra@Base 3.5.0-1 + pktloc_set_in@Base 3.5.0-1 + pktloc_set_lineno@Base 3.5.0-1 + pktloc_set_lloc@Base 3.5.0-1 + + pktloc_set_lval@Base 3.5.0-1 + pktloc_set_out@Base 3.5.0-1 + route_obj_ops@Base 3.5.0-1 + route_obj_ops@libnl_3 3.5.0-1 + rtln_link_policy@Base 3.5.0-1 + rtln_link_policy@libnl_3 3.5.0-1 + rtnl_act_add@Base 3.5.0-1 + rtnl_act_add@libnl_3 3.5.0-1 + rtnl_act_alloc@Base 3.5.0-1 + rtnl_act_alloc@libnl_3 3.5.0-1 + rtnl_act_append@Base 3.5.0-1 + rtnl_act_append@libnl_3 3.5.0-1 + rtnl_act_build_add_request@Base 3.5.0-1 + rtnl_act_build_add_request@libnl_3 3.5.0-1 + rtnl_act_build_change_request@Base 3.5.0-1 + rtnl_act_build_change_request@libnl_3 3.5.0-1 + rtnl_act_build_delete_request@Base 3.5.0-1 + rtnl_act_build_delete_request@libnl_3 3.5.0-1 + rtnl_act_change@Base 3.5.0-1 + rtnl_act_change@libnl_3 3.5.0-1 + rtnl_act_delete@Base 3.5.0-1 + rtnl_act_delete@libnl_3 3.5.0-1 + rtnl_act_fill@Base 3.5.0-1 + rtnl_act_fill@libnl_3 3.5.0-1 + rtnl_act_get@Base 3.5.0-1 + rtnl_act_get@libnl_3 3.5.0-1 + rtnl_act_next@libnl_3_4 3.5.0-1 + rtnl_act_parse@Base 3.5.0-1 + rtnl_act_parse@libnl_3 3.5.0-1 + rtnl_act_put@Base 3.5.0-1 + rtnl_act_put@libnl_3 3.5.0-1 + rtnl_act_put_all@Base 3.5.0-1 + rtnl_act_put_all@libnl_3 3.5.0-1 + rtnl_act_remove@Base 3.5.0-1 + rtnl_act_remove@libnl_3 3.5.0-1 + rtnl_addr_add@Base 3.5.0-1 + rtnl_addr_add@libnl_3 3.5.0-1 + rtnl_addr_alloc@Base 3.5.0-1 + rtnl_addr_alloc@libnl_3 3.5.0-1 + rtnl_addr_alloc_cache@Base 3.5.0-1 + rtnl_addr_alloc_cache@libnl_3 3.5.0-1 + rtnl_addr_build_add_request@Base 3.5.0-1 + rtnl_addr_build_add_request@libnl_3 3.5.0-1 + rtnl_addr_build_delete_request@Base 3.5.0-1 + rtnl_addr_build_delete_request@libnl_3 3.5.0-1 + rtnl_addr_delete@Base 3.5.0-1 + rtnl_addr_delete@libnl_3 3.5.0-1 + rtnl_addr_flags2str@Base 3.5.0-1 + rtnl_addr_flags2str@libnl_3 3.5.0-1 + rtnl_addr_get@Base 3.5.0-1 + rtnl_addr_get@libnl_3 3.5.0-1 + rtnl_addr_get_anycast@Base 3.5.0-1 + rtnl_addr_get_anycast@libnl_3 3.5.0-1 + rtnl_addr_get_broadcast@Base 3.5.0-1 + rtnl_addr_get_broadcast@libnl_3 3.5.0-1 + rtnl_addr_get_create_time@Base 3.5.0-1 + rtnl_addr_get_create_time@libnl_3 3.5.0-1 + rtnl_addr_get_family@Base 3.5.0-1 + rtnl_addr_get_family@libnl_3 3.5.0-1 + rtnl_addr_get_flags@Base 3.5.0-1 + rtnl_addr_get_flags@libnl_3 3.5.0-1 + rtnl_addr_get_ifindex@Base 3.5.0-1 + rtnl_addr_get_ifindex@libnl_3 3.5.0-1 + rtnl_addr_get_label@Base 3.5.0-1 + rtnl_addr_get_label@libnl_3 3.5.0-1 + rtnl_addr_get_last_update_time@Base 3.5.0-1 + rtnl_addr_get_last_update_time@libnl_3 3.5.0-1 + rtnl_addr_get_link@Base 3.5.0-1 + rtnl_addr_get_link@libnl_3 3.5.0-1 + rtnl_addr_get_local@Base 3.5.0-1 + rtnl_addr_get_local@libnl_3 3.5.0-1 + rtnl_addr_get_multicast@Base 3.5.0-1 + rtnl_addr_get_multicast@libnl_3 3.5.0-1 + rtnl_addr_get_peer@Base 3.5.0-1 + rtnl_addr_get_peer@libnl_3 3.5.0-1 + rtnl_addr_get_preferred_lifetime@Base 3.5.0-1 + rtnl_addr_get_preferred_lifetime@libnl_3 3.5.0-1 + rtnl_addr_get_prefixlen@Base 3.5.0-1 + rtnl_addr_get_prefixlen@libnl_3 3.5.0-1 + rtnl_addr_get_scope@Base 3.5.0-1 + rtnl_addr_get_scope@libnl_3 3.5.0-1 + rtnl_addr_get_valid_lifetime@Base 3.5.0-1 + rtnl_addr_get_valid_lifetime@libnl_3 3.5.0-1 + rtnl_addr_put@Base 3.5.0-1 + rtnl_addr_put@libnl_3 3.5.0-1 + rtnl_addr_set_anycast@Base 3.5.0-1 + rtnl_addr_set_anycast@libnl_3 3.5.0-1 + rtnl_addr_set_broadcast@Base 3.5.0-1 + rtnl_addr_set_broadcast@libnl_3 3.5.0-1 + rtnl_addr_set_family@Base 3.5.0-1 + rtnl_addr_set_family@libnl_3 3.5.0-1 + rtnl_addr_set_flags@Base 3.5.0-1 + rtnl_addr_set_flags@libnl_3 3.5.0-1 + rtnl_addr_set_ifindex@Base 3.5.0-1 + rtnl_addr_set_ifindex@libnl_3 3.5.0-1 + rtnl_addr_set_label@Base 3.5.0-1 + rtnl_addr_set_label@libnl_3 3.5.0-1 + rtnl_addr_set_link@Base 3.5.0-1 + rtnl_addr_set_link@libnl_3 3.5.0-1 + rtnl_addr_set_local@Base 3.5.0-1 + rtnl_addr_set_local@libnl_3 3.5.0-1 + rtnl_addr_set_multicast@Base 3.5.0-1 + rtnl_addr_set_multicast@libnl_3 3.5.0-1 + rtnl_addr_set_peer@Base 3.5.0-1 + rtnl_addr_set_peer@libnl_3 3.5.0-1 + rtnl_addr_set_preferred_lifetime@Base 3.5.0-1 + rtnl_addr_set_preferred_lifetime@libnl_3 3.5.0-1 + rtnl_addr_set_prefixlen@Base 3.5.0-1 + rtnl_addr_set_prefixlen@libnl_3 3.5.0-1 + rtnl_addr_set_scope@Base 3.5.0-1 + rtnl_addr_set_scope@libnl_3 3.5.0-1 + rtnl_addr_set_valid_lifetime@Base 3.5.0-1 + rtnl_addr_set_valid_lifetime@libnl_3 3.5.0-1 + rtnl_addr_str2flags@Base 3.5.0-1 + rtnl_addr_str2flags@libnl_3 3.5.0-1 + rtnl_addr_unset_flags@Base 3.5.0-1 + rtnl_addr_unset_flags@libnl_3 3.5.0-1 + rtnl_basic_add_action@Base 3.5.0-1 + rtnl_basic_add_action@libnl_3 3.5.0-1 + rtnl_basic_del_action@Base 3.5.0-1 + rtnl_basic_del_action@libnl_3 3.5.0-1 + rtnl_basic_get_action@libnl_3_4 3.5.0-1 + rtnl_basic_get_ematch@Base 3.5.0-1 + rtnl_basic_get_ematch@libnl_3 3.5.0-1 + rtnl_basic_get_target@Base 3.5.0-1 + rtnl_basic_get_target@libnl_3 3.5.0-1 + rtnl_basic_set_ematch@Base 3.5.0-1 + rtnl_basic_set_ematch@libnl_3 3.5.0-1 + rtnl_basic_set_target@Base 3.5.0-1 + rtnl_basic_set_target@libnl_3 3.5.0-1 + rtnl_cgroup_get_ematch@Base 3.5.0-1 + rtnl_cgroup_get_ematch@libnl_3 3.5.0-1 + rtnl_cgroup_set_ematch@Base 3.5.0-1 + rtnl_cgroup_set_ematch@libnl_3 3.5.0-1 + rtnl_class_add@Base 3.5.0-1 + rtnl_class_add@libnl_3 3.5.0-1 + rtnl_class_alloc@Base 3.5.0-1 + rtnl_class_alloc@libnl_3 3.5.0-1 + rtnl_class_alloc_cache@Base 3.5.0-1 + rtnl_class_alloc_cache@libnl_3 3.5.0-1 + rtnl_class_build_add_request@Base 3.5.0-1 + rtnl_class_build_add_request@libnl_3 3.5.0-1 + rtnl_class_build_delete_request@Base 3.5.0-1 + rtnl_class_build_delete_request@libnl_3 3.5.0-1 + rtnl_class_delete@Base 3.5.0-1 + rtnl_class_delete@libnl_3 3.5.0-1 + rtnl_class_dsmark_get_bitmask@Base 3.5.0-1 + rtnl_class_dsmark_get_bitmask@libnl_3 3.5.0-1 + rtnl_class_dsmark_get_value@Base 3.5.0-1 + rtnl_class_dsmark_get_value@libnl_3 3.5.0-1 + rtnl_class_dsmark_set_bitmask@Base 3.5.0-1 + rtnl_class_dsmark_set_bitmask@libnl_3 3.5.0-1 + rtnl_class_dsmark_set_value@Base 3.5.0-1 + rtnl_class_dsmark_set_value@libnl_3 3.5.0-1 + rtnl_class_foreach_child@Base 3.5.0-1 + rtnl_class_foreach_child@libnl_3 3.5.0-1 + rtnl_class_foreach_cls@Base 3.5.0-1 + rtnl_class_foreach_cls@libnl_3 3.5.0-1 + rtnl_class_get@Base 3.5.0-1 + rtnl_class_get@libnl_3 3.5.0-1 + rtnl_class_get_by_parent@libnl_3_5 3.5.0-1 + rtnl_class_hfsc_get_fsc@Base 3.5.0-1 + rtnl_class_hfsc_get_fsc@libnl_3 3.5.0-1 + rtnl_class_hfsc_get_rsc@Base 3.5.0-1 + rtnl_class_hfsc_get_rsc@libnl_3 3.5.0-1 + rtnl_class_hfsc_get_usc@Base 3.5.0-1 + rtnl_class_hfsc_get_usc@libnl_3 3.5.0-1 + rtnl_class_hfsc_set_fsc@Base 3.5.0-1 + rtnl_class_hfsc_set_fsc@libnl_3 3.5.0-1 + rtnl_class_hfsc_set_rsc@Base 3.5.0-1 + rtnl_class_hfsc_set_rsc@libnl_3 3.5.0-1 + rtnl_class_hfsc_set_usc@Base 3.5.0-1 + rtnl_class_hfsc_set_usc@libnl_3 3.5.0-1 + rtnl_class_leaf_qdisc@Base 3.5.0-1 + rtnl_class_leaf_qdisc@libnl_3 3.5.0-1 + rtnl_class_put@Base 3.5.0-1 + rtnl_class_put@libnl_3 3.5.0-1 + rtnl_classid_generate@Base 3.5.0-1 + rtnl_classid_generate@libnl_3 3.5.0-1 + rtnl_cls_add@Base 3.5.0-1 + rtnl_cls_add@libnl_3 3.5.0-1 + rtnl_cls_alloc@Base 3.5.0-1 + rtnl_cls_alloc@libnl_3 3.5.0-1 + rtnl_cls_alloc_cache@Base 3.5.0-1 + rtnl_cls_alloc_cache@libnl_3 3.5.0-1 + rtnl_cls_build_add_request@Base 3.5.0-1 + rtnl_cls_build_add_request@libnl_3 3.5.0-1 + rtnl_cls_build_change_request@Base 3.5.0-1 + rtnl_cls_build_change_request@libnl_3 3.5.0-1 + rtnl_cls_build_delete_request@Base 3.5.0-1 + rtnl_cls_build_delete_request@libnl_3 3.5.0-1 + rtnl_cls_cache_set_tc_params@libnl_3_5 3.5.0-1 + rtnl_cls_change@Base 3.5.0-1 + rtnl_cls_change@libnl_3 3.5.0-1 + rtnl_cls_delete@Base 3.5.0-1 + rtnl_cls_delete@libnl_3 3.5.0-1 + rtnl_cls_get_prio@Base 3.5.0-1 + rtnl_cls_get_prio@libnl_3 3.5.0-1 + rtnl_cls_get_protocol@Base 3.5.0-1 + rtnl_cls_get_protocol@libnl_3 3.5.0-1 + rtnl_cls_put@Base 3.5.0-1 + rtnl_cls_put@libnl_3 3.5.0-1 + rtnl_cls_set_prio@Base 3.5.0-1 + rtnl_cls_set_prio@libnl_3 3.5.0-1 + rtnl_cls_set_protocol@Base 3.5.0-1 + rtnl_cls_set_protocol@libnl_3 3.5.0-1 + rtnl_ematch_add_child@Base 3.5.0-1 + rtnl_ematch_add_child@libnl_3 3.5.0-1 + rtnl_ematch_alloc@Base 3.5.0-1 + rtnl_ematch_alloc@libnl_3 3.5.0-1 + rtnl_ematch_cmp_get@Base 3.5.0-1 + rtnl_ematch_cmp_get@libnl_3 3.5.0-1 + rtnl_ematch_cmp_set@Base 3.5.0-1 + rtnl_ematch_cmp_set@libnl_3 3.5.0-1 + rtnl_ematch_data@Base 3.5.0-1 + rtnl_ematch_data@libnl_3 3.5.0-1 + rtnl_ematch_fill_attr@Base 3.5.0-1 + rtnl_ematch_fill_attr@libnl_3 3.5.0-1 + rtnl_ematch_free@Base 3.5.0-1 + rtnl_ematch_free@libnl_3 3.5.0-1 + rtnl_ematch_get_flags@Base 3.5.0-1 + rtnl_ematch_get_flags@libnl_3 3.5.0-1 + rtnl_ematch_lookup_ops@Base 3.5.0-1 + rtnl_ematch_lookup_ops@libnl_3 3.5.0-1 + rtnl_ematch_lookup_ops_by_name@Base 3.5.0-1 + rtnl_ematch_lookup_ops_by_name@libnl_3 3.5.0-1 + rtnl_ematch_meta_set_lvalue@Base 3.5.0-1 + rtnl_ematch_meta_set_lvalue@libnl_3 3.5.0-1 + rtnl_ematch_meta_set_operand@Base 3.5.0-1 + rtnl_ematch_meta_set_operand@libnl_3 3.5.0-1 + rtnl_ematch_meta_set_rvalue@Base 3.5.0-1 + rtnl_ematch_meta_set_rvalue@libnl_3 3.5.0-1 + rtnl_ematch_nbyte_get_layer@Base 3.5.0-1 + rtnl_ematch_nbyte_get_layer@libnl_3 3.5.0-1 + rtnl_ematch_nbyte_get_len@Base 3.5.0-1 + rtnl_ematch_nbyte_get_len@libnl_3 3.5.0-1 + rtnl_ematch_nbyte_get_offset@Base 3.5.0-1 + rtnl_ematch_nbyte_get_offset@libnl_3 3.5.0-1 + rtnl_ematch_nbyte_get_pattern@Base 3.5.0-1 + rtnl_ematch_nbyte_get_pattern@libnl_3 3.5.0-1 + rtnl_ematch_nbyte_set_offset@Base 3.5.0-1 + rtnl_ematch_nbyte_set_offset@libnl_3 3.5.0-1 + rtnl_ematch_nbyte_set_pattern@Base 3.5.0-1 + rtnl_ematch_nbyte_set_pattern@libnl_3 3.5.0-1 + rtnl_ematch_offset2txt@Base 3.5.0-1 + rtnl_ematch_offset2txt@libnl_3 3.5.0-1 + rtnl_ematch_opnd2txt@Base 3.5.0-1 + rtnl_ematch_opnd2txt@libnl_3 3.5.0-1 + rtnl_ematch_parse_attr@Base 3.5.0-1 + rtnl_ematch_parse_attr@libnl_3 3.5.0-1 + rtnl_ematch_parse_expr@Base 3.5.0-1 + rtnl_ematch_parse_expr@libnl_3 3.5.0-1 + rtnl_ematch_register@Base 3.5.0-1 + rtnl_ematch_register@libnl_3 3.5.0-1 + rtnl_ematch_set_flags@Base 3.5.0-1 + rtnl_ematch_set_flags@libnl_3 3.5.0-1 + rtnl_ematch_set_kind@Base 3.5.0-1 + rtnl_ematch_set_kind@libnl_3 3.5.0-1 + rtnl_ematch_set_name@Base 3.5.0-1 + rtnl_ematch_set_name@libnl_3 3.5.0-1 + rtnl_ematch_set_ops@Base 3.5.0-1 + rtnl_ematch_set_ops@libnl_3 3.5.0-1 + rtnl_ematch_text_get_algo@Base 3.5.0-1 + rtnl_ematch_text_get_algo@libnl_3 3.5.0-1 + rtnl_ematch_text_get_from_layer@Base 3.5.0-1 + rtnl_ematch_text_get_from_layer@libnl_3 3.5.0-1 + rtnl_ematch_text_get_from_offset@Base 3.5.0-1 + rtnl_ematch_text_get_from_offset@libnl_3 3.5.0-1 + rtnl_ematch_text_get_len@Base 3.5.0-1 + rtnl_ematch_text_get_len@libnl_3 3.5.0-1 + rtnl_ematch_text_get_pattern@Base 3.5.0-1 + rtnl_ematch_text_get_pattern@libnl_3 3.5.0-1 + rtnl_ematch_text_get_to_layer@Base 3.5.0-1 + rtnl_ematch_text_get_to_layer@libnl_3 3.5.0-1 + rtnl_ematch_text_get_to_offset@Base 3.5.0-1 + rtnl_ematch_text_get_to_offset@libnl_3 3.5.0-1 + rtnl_ematch_text_set_algo@Base 3.5.0-1 + rtnl_ematch_text_set_algo@libnl_3 3.5.0-1 + rtnl_ematch_text_set_from@Base 3.5.0-1 + rtnl_ematch_text_set_from@libnl_3 3.5.0-1 + rtnl_ematch_text_set_pattern@Base 3.5.0-1 + rtnl_ematch_text_set_pattern@libnl_3 3.5.0-1 + rtnl_ematch_text_set_to@Base 3.5.0-1 + rtnl_ematch_text_set_to@libnl_3 3.5.0-1 + rtnl_ematch_tree_add@Base 3.5.0-1 + rtnl_ematch_tree_add@libnl_3 3.5.0-1 + rtnl_ematch_tree_alloc@Base 3.5.0-1 + rtnl_ematch_tree_alloc@libnl_3 3.5.0-1 + rtnl_ematch_tree_clone@libnl_3_5 3.5.0-1 + rtnl_ematch_tree_dump@Base 3.5.0-1 + rtnl_ematch_tree_dump@libnl_3 3.5.0-1 + rtnl_ematch_tree_free@Base 3.5.0-1 + rtnl_ematch_tree_free@libnl_3 3.5.0-1 + rtnl_ematch_unlink@Base 3.5.0-1 + rtnl_ematch_unlink@libnl_3 3.5.0-1 + rtnl_ematch_unset_flags@Base 3.5.0-1 + rtnl_ematch_unset_flags@libnl_3 3.5.0-1 + rtnl_fw_set_classid@Base 3.5.0-1 + rtnl_fw_set_classid@libnl_3 3.5.0-1 + rtnl_fw_set_mask@Base 3.5.0-1 + rtnl_fw_set_mask@libnl_3 3.5.0-1 + rtnl_gact_get_action@libnl_3_2_29 3.5.0-1 + rtnl_gact_set_action@libnl_3_2_29 3.5.0-1 + rtnl_htb_get_cbuffer@Base 3.5.0-1 + rtnl_htb_get_cbuffer@libnl_3 3.5.0-1 + rtnl_htb_get_ceil64@libnl_3_5 3.5.0-1 + rtnl_htb_get_ceil@Base 3.5.0-1 + rtnl_htb_get_ceil@libnl_3 3.5.0-1 + rtnl_htb_get_defcls@Base 3.5.0-1 + rtnl_htb_get_defcls@libnl_3 3.5.0-1 + rtnl_htb_get_level@Base 3.5.0-1 + rtnl_htb_get_level@libnl_3 3.5.0-1 + rtnl_htb_get_prio@Base 3.5.0-1 + rtnl_htb_get_prio@libnl_3 3.5.0-1 + rtnl_htb_get_quantum@Base 3.5.0-1 + rtnl_htb_get_quantum@libnl_3 3.5.0-1 + rtnl_htb_get_rate2quantum@Base 3.5.0-1 + rtnl_htb_get_rate2quantum@libnl_3 3.5.0-1 + rtnl_htb_get_rate64@libnl_3_5 3.5.0-1 + rtnl_htb_get_rate@Base 3.5.0-1 + rtnl_htb_get_rate@libnl_3 3.5.0-1 + rtnl_htb_get_rbuffer@Base 3.5.0-1 + rtnl_htb_get_rbuffer@libnl_3 3.5.0-1 + rtnl_htb_set_cbuffer@Base 3.5.0-1 + rtnl_htb_set_cbuffer@libnl_3 3.5.0-1 + rtnl_htb_set_ceil64@libnl_3_5 3.5.0-1 + rtnl_htb_set_ceil@Base 3.5.0-1 + rtnl_htb_set_ceil@libnl_3 3.5.0-1 + rtnl_htb_set_defcls@Base 3.5.0-1 + rtnl_htb_set_defcls@libnl_3 3.5.0-1 + rtnl_htb_set_level@Base 3.5.0-1 + rtnl_htb_set_level@libnl_3 3.5.0-1 + rtnl_htb_set_prio@Base 3.5.0-1 + rtnl_htb_set_prio@libnl_3 3.5.0-1 + rtnl_htb_set_quantum@Base 3.5.0-1 + rtnl_htb_set_quantum@libnl_3 3.5.0-1 + rtnl_htb_set_rate2quantum@Base 3.5.0-1 + rtnl_htb_set_rate2quantum@libnl_3 3.5.0-1 + rtnl_htb_set_rate64@libnl_3_5 3.5.0-1 + rtnl_htb_set_rate@Base 3.5.0-1 + rtnl_htb_set_rate@libnl_3 3.5.0-1 + rtnl_htb_set_rbuffer@Base 3.5.0-1 + rtnl_htb_set_rbuffer@libnl_3 3.5.0-1 + rtnl_link_add@Base 3.5.0-1 + rtnl_link_add@libnl_3 3.5.0-1 + rtnl_link_af_alloc@Base 3.5.0-1 + rtnl_link_af_alloc@libnl_3 3.5.0-1 + rtnl_link_af_data@Base 3.5.0-1 + rtnl_link_af_data@libnl_3 3.5.0-1 + rtnl_link_af_data_compare@Base 3.5.0-1 + rtnl_link_af_data_compare@libnl_3 3.5.0-1 + rtnl_link_af_ops_lookup@Base 3.5.0-1 + rtnl_link_af_ops_lookup@libnl_3 3.5.0-1 + rtnl_link_af_ops_put@Base 3.5.0-1 + rtnl_link_af_ops_put@libnl_3 3.5.0-1 + rtnl_link_af_register@Base 3.5.0-1 + rtnl_link_af_register@libnl_3 3.5.0-1 + rtnl_link_af_unregister@Base 3.5.0-1 + rtnl_link_af_unregister@libnl_3 3.5.0-1 + rtnl_link_alloc@Base 3.5.0-1 + rtnl_link_alloc@libnl_3 3.5.0-1 + rtnl_link_alloc_cache@Base 3.5.0-1 + rtnl_link_alloc_cache@libnl_3 3.5.0-1 + rtnl_link_alloc_cache_flags@libnl_3_2_28 3.5.0-1 + rtnl_link_bond_add@Base 3.5.0-1 + rtnl_link_bond_add@libnl_3 3.5.0-1 + rtnl_link_bond_alloc@Base 3.5.0-1 + rtnl_link_bond_alloc@libnl_3 3.5.0-1 + rtnl_link_bond_enslave@Base 3.5.0-1 + rtnl_link_bond_enslave@libnl_3 3.5.0-1 + rtnl_link_bond_enslave_ifindex@Base 3.5.0-1 + rtnl_link_bond_enslave_ifindex@libnl_3 3.5.0-1 + rtnl_link_bond_release@Base 3.5.0-1 + rtnl_link_bond_release@libnl_3 3.5.0-1 + rtnl_link_bond_release_ifindex@Base 3.5.0-1 + rtnl_link_bond_release_ifindex@libnl_3 3.5.0-1 + rtnl_link_bridge_add@Base 3.5.0-1 + rtnl_link_bridge_add@libnl_3 3.5.0-1 + rtnl_link_bridge_alloc@Base 3.5.0-1 + rtnl_link_bridge_alloc@libnl_3 3.5.0-1 + rtnl_link_bridge_flags2str@Base 3.5.0-1 + rtnl_link_bridge_flags2str@libnl_3 3.5.0-1 + rtnl_link_bridge_get_cost@Base 3.5.0-1 + rtnl_link_bridge_get_cost@libnl_3 3.5.0-1 + rtnl_link_bridge_get_flags@Base 3.5.0-1 + rtnl_link_bridge_get_flags@libnl_3 3.5.0-1 + rtnl_link_bridge_get_hwmode@libnl_3_2_29 3.5.0-1 + rtnl_link_bridge_get_port_state@Base 3.5.0-1 + rtnl_link_bridge_get_port_state@libnl_3 3.5.0-1 + rtnl_link_bridge_get_port_vlan@libnl_3_2_28 3.5.0-1 + rtnl_link_bridge_get_priority@Base 3.5.0-1 + rtnl_link_bridge_get_priority@libnl_3 3.5.0-1 + rtnl_link_bridge_has_ext_info@Base 3.5.0-1 + rtnl_link_bridge_has_ext_info@libnl_3 3.5.0-1 + rtnl_link_bridge_has_vlan@libnl_3_2_28 3.5.0-1 + rtnl_link_bridge_hwmode2str@libnl_3_2_29 3.5.0-1 + rtnl_link_bridge_portstate2str@libnl_3_2_29 3.5.0-1 + rtnl_link_bridge_pvid@libnl_3_2_28 3.5.0-1 + rtnl_link_bridge_set_cost@Base 3.5.0-1 + rtnl_link_bridge_set_cost@libnl_3 3.5.0-1 + rtnl_link_bridge_set_flags@Base 3.5.0-1 + rtnl_link_bridge_set_flags@libnl_3 3.5.0-1 + rtnl_link_bridge_set_hwmode@libnl_3_2_29 3.5.0-1 + rtnl_link_bridge_set_port_state@Base 3.5.0-1 + rtnl_link_bridge_set_port_state@libnl_3 3.5.0-1 + rtnl_link_bridge_set_priority@Base 3.5.0-1 + rtnl_link_bridge_set_priority@libnl_3 3.5.0-1 + rtnl_link_bridge_set_self@libnl_3_2_29 3.5.0-1 + rtnl_link_bridge_str2flags@Base 3.5.0-1 + rtnl_link_bridge_str2flags@libnl_3 3.5.0-1 + rtnl_link_bridge_str2hwmode@libnl_3_2_29 3.5.0-1 + rtnl_link_bridge_str2portstate@libnl_3_2_29 3.5.0-1 + rtnl_link_bridge_unset_flags@Base 3.5.0-1 + rtnl_link_bridge_unset_flags@libnl_3 3.5.0-1 + rtnl_link_build_add_request@Base 3.5.0-1 + rtnl_link_build_add_request@libnl_3 3.5.0-1 + rtnl_link_build_change_request@Base 3.5.0-1 + rtnl_link_build_change_request@libnl_3 3.5.0-1 + rtnl_link_build_delete_request@Base 3.5.0-1 + rtnl_link_build_delete_request@libnl_3 3.5.0-1 + rtnl_link_build_get_request@Base 3.5.0-1 + rtnl_link_build_get_request@libnl_3 3.5.0-1 + rtnl_link_can_berr@Base 3.5.0-1 + rtnl_link_can_berr@libnl_3 3.5.0-1 + rtnl_link_can_berr_rx@Base 3.5.0-1 + rtnl_link_can_berr_rx@libnl_3 3.5.0-1 + rtnl_link_can_berr_tx@Base 3.5.0-1 + rtnl_link_can_berr_tx@libnl_3 3.5.0-1 + rtnl_link_can_ctrlmode2str@Base 3.5.0-1 + rtnl_link_can_ctrlmode2str@libnl_3 3.5.0-1 + rtnl_link_can_freq@Base 3.5.0-1 + rtnl_link_can_freq@libnl_3 3.5.0-1 + rtnl_link_can_get_bitrate@Base 3.5.0-1 + rtnl_link_can_get_bitrate@libnl_3 3.5.0-1 + rtnl_link_can_get_bittiming@Base 3.5.0-1 + rtnl_link_can_get_bittiming@libnl_3 3.5.0-1 + rtnl_link_can_get_bt_const@Base 3.5.0-1 + rtnl_link_can_get_bt_const@libnl_3 3.5.0-1 + rtnl_link_can_get_ctrlmode@Base 3.5.0-1 + rtnl_link_can_get_ctrlmode@libnl_3 3.5.0-1 + rtnl_link_can_get_restart_ms@Base 3.5.0-1 + rtnl_link_can_get_restart_ms@libnl_3 3.5.0-1 + rtnl_link_can_get_sample_point@Base 3.5.0-1 + rtnl_link_can_get_sample_point@libnl_3 3.5.0-1 + rtnl_link_can_restart@Base 3.5.0-1 + rtnl_link_can_restart@libnl_3 3.5.0-1 + rtnl_link_can_set_bitrate@Base 3.5.0-1 + rtnl_link_can_set_bitrate@libnl_3 3.5.0-1 + rtnl_link_can_set_bittiming@Base 3.5.0-1 + rtnl_link_can_set_bittiming@libnl_3 3.5.0-1 + rtnl_link_can_set_ctrlmode@Base 3.5.0-1 + rtnl_link_can_set_ctrlmode@libnl_3 3.5.0-1 + rtnl_link_can_set_restart_ms@Base 3.5.0-1 + rtnl_link_can_set_restart_ms@libnl_3 3.5.0-1 + rtnl_link_can_set_sample_point@Base 3.5.0-1 + rtnl_link_can_set_sample_point@libnl_3 3.5.0-1 + rtnl_link_can_state@Base 3.5.0-1 + rtnl_link_can_state@libnl_3 3.5.0-1 + rtnl_link_can_str2ctrlmode@Base 3.5.0-1 + rtnl_link_can_str2ctrlmode@libnl_3 3.5.0-1 + rtnl_link_can_unset_ctrlmode@Base 3.5.0-1 + rtnl_link_can_unset_ctrlmode@libnl_3 3.5.0-1 + rtnl_link_carrier2str@Base 3.5.0-1 + rtnl_link_carrier2str@libnl_3 3.5.0-1 + rtnl_link_change@Base 3.5.0-1 + rtnl_link_change@libnl_3 3.5.0-1 + rtnl_link_delete@Base 3.5.0-1 + rtnl_link_delete@libnl_3 3.5.0-1 + rtnl_link_enslave@Base 3.5.0-1 + rtnl_link_enslave@libnl_3 3.5.0-1 + rtnl_link_enslave_ifindex@Base 3.5.0-1 + rtnl_link_enslave_ifindex@libnl_3 3.5.0-1 + rtnl_link_fill_info@Base 3.5.0-1 + rtnl_link_fill_info@libnl_3 3.5.0-1 + rtnl_link_flags2str@Base 3.5.0-1 + rtnl_link_flags2str@libnl_3 3.5.0-1 + rtnl_link_geneve_alloc@libnl_3_5 3.5.0-1 + rtnl_link_geneve_get_flags@libnl_3_5 3.5.0-1 + rtnl_link_geneve_get_id@libnl_3_5 3.5.0-1 + rtnl_link_geneve_get_label@libnl_3_5 3.5.0-1 + rtnl_link_geneve_get_port@libnl_3_5 3.5.0-1 + rtnl_link_geneve_get_remote@libnl_3_5 3.5.0-1 + rtnl_link_geneve_get_tos@libnl_3_5 3.5.0-1 + rtnl_link_geneve_get_ttl@libnl_3_5 3.5.0-1 + rtnl_link_geneve_get_udp_csum@libnl_3_5 3.5.0-1 + rtnl_link_geneve_get_udp_zero_csum6_rx@libnl_3_5 3.5.0-1 + rtnl_link_geneve_get_udp_zero_csum6_tx@libnl_3_5 3.5.0-1 + rtnl_link_geneve_set_flags@libnl_3_5 3.5.0-1 + rtnl_link_geneve_set_id@libnl_3_5 3.5.0-1 + rtnl_link_geneve_set_label@libnl_3_5 3.5.0-1 + rtnl_link_geneve_set_port@libnl_3_5 3.5.0-1 + rtnl_link_geneve_set_remote@libnl_3_5 3.5.0-1 + rtnl_link_geneve_set_tos@libnl_3_5 3.5.0-1 + rtnl_link_geneve_set_ttl@libnl_3_5 3.5.0-1 + rtnl_link_geneve_set_udp_csum@libnl_3_5 3.5.0-1 + rtnl_link_geneve_set_udp_zero_csum6_rx@libnl_3_5 3.5.0-1 + rtnl_link_geneve_set_udp_zero_csum6_tx@libnl_3_5 3.5.0-1 + rtnl_link_get@Base 3.5.0-1 + rtnl_link_get@libnl_3 3.5.0-1 + rtnl_link_get_addr@Base 3.5.0-1 + rtnl_link_get_addr@libnl_3 3.5.0-1 + rtnl_link_get_arptype@Base 3.5.0-1 + rtnl_link_get_arptype@libnl_3 3.5.0-1 + rtnl_link_get_broadcast@Base 3.5.0-1 + rtnl_link_get_broadcast@libnl_3 3.5.0-1 + rtnl_link_get_by_name@Base 3.5.0-1 + rtnl_link_get_by_name@libnl_3 3.5.0-1 + rtnl_link_get_carrier@Base 3.5.0-1 + rtnl_link_get_carrier@libnl_3 3.5.0-1 + rtnl_link_get_carrier_changes@libnl_3_2_29 3.5.0-1 + rtnl_link_get_family@Base 3.5.0-1 + rtnl_link_get_family@libnl_3 3.5.0-1 + rtnl_link_get_flags@Base 3.5.0-1 + rtnl_link_get_flags@libnl_3 3.5.0-1 + rtnl_link_get_group@Base 3.5.0-1 + rtnl_link_get_group@libnl_3 3.5.0-1 + rtnl_link_get_gso_max_segs@libnl_3_2_29 3.5.0-1 + rtnl_link_get_gso_max_size@libnl_3_2_29 3.5.0-1 + rtnl_link_get_ifalias@Base 3.5.0-1 + rtnl_link_get_ifalias@libnl_3 3.5.0-1 + rtnl_link_get_ifindex@Base 3.5.0-1 + rtnl_link_get_ifindex@libnl_3 3.5.0-1 + rtnl_link_get_info_type@Base 3.5.0-1 + rtnl_link_get_info_type@libnl_3 3.5.0-1 + rtnl_link_get_kernel@Base 3.5.0-1 + rtnl_link_get_kernel@libnl_3 3.5.0-1 + rtnl_link_get_link@Base 3.5.0-1 + rtnl_link_get_link@libnl_3 3.5.0-1 + rtnl_link_get_link_netnsid@Base 3.5.0-1 + rtnl_link_get_link_netnsid@libnl_3_2_27 3.5.0-1 + rtnl_link_get_linkmode@Base 3.5.0-1 + rtnl_link_get_linkmode@libnl_3 3.5.0-1 + rtnl_link_get_master@Base 3.5.0-1 + rtnl_link_get_master@libnl_3 3.5.0-1 + rtnl_link_get_mtu@Base 3.5.0-1 + rtnl_link_get_mtu@libnl_3 3.5.0-1 + rtnl_link_get_name@Base 3.5.0-1 + rtnl_link_get_name@libnl_3 3.5.0-1 + rtnl_link_get_ns_fd@Base 3.5.0-1 + rtnl_link_get_ns_fd@libnl_3 3.5.0-1 + rtnl_link_get_ns_pid@Base 3.5.0-1 + rtnl_link_get_ns_pid@libnl_3 3.5.0-1 + rtnl_link_get_num_rx_queues@Base 3.5.0-1 + rtnl_link_get_num_rx_queues@libnl_3 3.5.0-1 + rtnl_link_get_num_tx_queues@Base 3.5.0-1 + rtnl_link_get_num_tx_queues@libnl_3 3.5.0-1 + rtnl_link_get_num_vf@Base 3.5.0-1 + rtnl_link_get_num_vf@libnl_3 3.5.0-1 + rtnl_link_get_operstate@Base 3.5.0-1 + rtnl_link_get_operstate@libnl_3 3.5.0-1 + rtnl_link_get_phys_port_id@Base 3.5.0-1 + rtnl_link_get_phys_port_id@libnl_3 3.5.0-1 + rtnl_link_get_phys_port_name@libnl_3_2_29 3.5.0-1 + rtnl_link_get_phys_switch_id@libnl_3_2_29 3.5.0-1 + rtnl_link_get_pmtudisc@Base 3.5.0-1 + rtnl_link_get_pmtudisc@libnl_3 3.5.0-1 + rtnl_link_get_promiscuity@Base 3.5.0-1 + rtnl_link_get_promiscuity@libnl_3 3.5.0-1 + rtnl_link_get_qdisc@Base 3.5.0-1 + rtnl_link_get_qdisc@libnl_3 3.5.0-1 + rtnl_link_get_slave_type@libnl_3_5 3.5.0-1 + rtnl_link_get_stat@Base 3.5.0-1 + rtnl_link_get_stat@libnl_3 3.5.0-1 + rtnl_link_get_txqlen@Base 3.5.0-1 + rtnl_link_get_txqlen@libnl_3 3.5.0-1 + rtnl_link_get_type@Base 3.5.0-1 + rtnl_link_get_type@libnl_3 3.5.0-1 + rtnl_link_get_weight@Base 3.5.0-1 + rtnl_link_get_weight@libnl_3 3.5.0-1 + rtnl_link_has_vf_list@libnl_3_2_29 3.5.0-1 + rtnl_link_i2name@Base 3.5.0-1 + rtnl_link_i2name@libnl_3 3.5.0-1 + rtnl_link_inet6_addrgenmode2str@Base 3.5.0-1 + rtnl_link_inet6_addrgenmode2str@libnl_3 3.5.0-1 + rtnl_link_inet6_flags2str@libnl_3_4 3.5.0-1 + rtnl_link_inet6_get_addr_gen_mode@Base 3.5.0-1 + rtnl_link_inet6_get_addr_gen_mode@libnl_3 3.5.0-1 + rtnl_link_inet6_get_flags@libnl_3_4 3.5.0-1 + rtnl_link_inet6_get_token@Base 3.5.0-1 + rtnl_link_inet6_get_token@libnl_3 3.5.0-1 + rtnl_link_inet6_set_addr_gen_mode@Base 3.5.0-1 + rtnl_link_inet6_set_addr_gen_mode@libnl_3 3.5.0-1 + rtnl_link_inet6_set_flags@libnl_3_4 3.5.0-1 + rtnl_link_inet6_set_token@Base 3.5.0-1 + rtnl_link_inet6_set_token@libnl_3 3.5.0-1 + rtnl_link_inet6_str2addrgenmode@Base 3.5.0-1 + rtnl_link_inet6_str2addrgenmode@libnl_3 3.5.0-1 + rtnl_link_inet6_str2flags@libnl_3_4 3.5.0-1 + rtnl_link_inet_devconf2str@Base 3.5.0-1 + rtnl_link_inet_devconf2str@libnl_3 3.5.0-1 + rtnl_link_inet_get_conf@Base 3.5.0-1 + rtnl_link_inet_get_conf@libnl_3 3.5.0-1 + rtnl_link_inet_set_conf@Base 3.5.0-1 + rtnl_link_inet_set_conf@libnl_3 3.5.0-1 + rtnl_link_inet_str2devconf@Base 3.5.0-1 + rtnl_link_inet_str2devconf@libnl_3 3.5.0-1 + rtnl_link_info_ops_lookup@Base 3.5.0-1 + rtnl_link_info_ops_lookup@libnl_3 3.5.0-1 + rtnl_link_info_ops_put@Base 3.5.0-1 + rtnl_link_info_ops_put@libnl_3 3.5.0-1 + rtnl_link_info_parse@Base 3.5.0-1 + rtnl_link_info_parse@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_add@Base 3.5.0-1 + rtnl_link_ip6_tnl_add@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_alloc@Base 3.5.0-1 + rtnl_link_ip6_tnl_alloc@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_get_encaplimit@Base 3.5.0-1 + rtnl_link_ip6_tnl_get_encaplimit@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_get_flags@Base 3.5.0-1 + rtnl_link_ip6_tnl_get_flags@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_get_flowinfo@Base 3.5.0-1 + rtnl_link_ip6_tnl_get_flowinfo@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_get_link@Base 3.5.0-1 + rtnl_link_ip6_tnl_get_link@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_get_local@Base 3.5.0-1 + rtnl_link_ip6_tnl_get_local@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_get_proto@Base 3.5.0-1 + rtnl_link_ip6_tnl_get_proto@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_get_remote@Base 3.5.0-1 + rtnl_link_ip6_tnl_get_remote@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_get_tos@Base 3.5.0-1 + rtnl_link_ip6_tnl_get_tos@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_get_ttl@Base 3.5.0-1 + rtnl_link_ip6_tnl_get_ttl@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_set_encaplimit@Base 3.5.0-1 + rtnl_link_ip6_tnl_set_encaplimit@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_set_flags@Base 3.5.0-1 + rtnl_link_ip6_tnl_set_flags@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_set_flowinfo@Base 3.5.0-1 + rtnl_link_ip6_tnl_set_flowinfo@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_set_link@Base 3.5.0-1 + rtnl_link_ip6_tnl_set_link@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_set_local@Base 3.5.0-1 + rtnl_link_ip6_tnl_set_local@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_set_proto@Base 3.5.0-1 + rtnl_link_ip6_tnl_set_proto@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_set_remote@Base 3.5.0-1 + rtnl_link_ip6_tnl_set_remote@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_set_tos@Base 3.5.0-1 + rtnl_link_ip6_tnl_set_tos@libnl_3 3.5.0-1 + rtnl_link_ip6_tnl_set_ttl@Base 3.5.0-1 + rtnl_link_ip6_tnl_set_ttl@libnl_3 3.5.0-1 + rtnl_link_ipgre_add@Base 3.5.0-1 + rtnl_link_ipgre_add@libnl_3 3.5.0-1 + rtnl_link_ipgre_alloc@Base 3.5.0-1 + rtnl_link_ipgre_alloc@libnl_3 3.5.0-1 + rtnl_link_ipgre_get_iflags@Base 3.5.0-1 + rtnl_link_ipgre_get_iflags@libnl_3 3.5.0-1 + rtnl_link_ipgre_get_ikey@Base 3.5.0-1 + rtnl_link_ipgre_get_ikey@libnl_3 3.5.0-1 + rtnl_link_ipgre_get_link@Base 3.5.0-1 + rtnl_link_ipgre_get_link@libnl_3 3.5.0-1 + rtnl_link_ipgre_get_local@Base 3.5.0-1 + rtnl_link_ipgre_get_local@libnl_3 3.5.0-1 + rtnl_link_ipgre_get_oflags@Base 3.5.0-1 + rtnl_link_ipgre_get_oflags@libnl_3 3.5.0-1 + rtnl_link_ipgre_get_okey@Base 3.5.0-1 + rtnl_link_ipgre_get_okey@libnl_3 3.5.0-1 + rtnl_link_ipgre_get_pmtudisc@libnl_3_2_29 3.5.0-1 + rtnl_link_ipgre_get_remote@Base 3.5.0-1 + rtnl_link_ipgre_get_remote@libnl_3 3.5.0-1 + rtnl_link_ipgre_get_tos@Base 3.5.0-1 + rtnl_link_ipgre_get_tos@libnl_3 3.5.0-1 + rtnl_link_ipgre_get_ttl@Base 3.5.0-1 + rtnl_link_ipgre_get_ttl@libnl_3 3.5.0-1 + rtnl_link_ipgre_set_iflags@Base 3.5.0-1 + rtnl_link_ipgre_set_iflags@libnl_3 3.5.0-1 + rtnl_link_ipgre_set_ikey@Base 3.5.0-1 + rtnl_link_ipgre_set_ikey@libnl_3 3.5.0-1 + rtnl_link_ipgre_set_link@Base 3.5.0-1 + rtnl_link_ipgre_set_link@libnl_3 3.5.0-1 + rtnl_link_ipgre_set_local@Base 3.5.0-1 + rtnl_link_ipgre_set_local@libnl_3 3.5.0-1 + rtnl_link_ipgre_set_oflags@Base 3.5.0-1 + rtnl_link_ipgre_set_oflags@libnl_3 3.5.0-1 + rtnl_link_ipgre_set_okey@Base 3.5.0-1 + rtnl_link_ipgre_set_okey@libnl_3 3.5.0-1 + rtnl_link_ipgre_set_pmtudisc@Base 3.5.0-1 + rtnl_link_ipgre_set_pmtudisc@libnl_3 3.5.0-1 + rtnl_link_ipgre_set_remote@Base 3.5.0-1 + rtnl_link_ipgre_set_remote@libnl_3 3.5.0-1 + rtnl_link_ipgre_set_tos@Base 3.5.0-1 + rtnl_link_ipgre_set_tos@libnl_3 3.5.0-1 + rtnl_link_ipgre_set_ttl@Base 3.5.0-1 + rtnl_link_ipgre_set_ttl@libnl_3 3.5.0-1 + rtnl_link_ipgretap_add@libnl_3_2_28 3.5.0-1 + rtnl_link_ipgretap_alloc@libnl_3_2_28 3.5.0-1 + rtnl_link_ipip_add@Base 3.5.0-1 + rtnl_link_ipip_add@libnl_3 3.5.0-1 + rtnl_link_ipip_alloc@Base 3.5.0-1 + rtnl_link_ipip_alloc@libnl_3 3.5.0-1 + rtnl_link_ipip_get_link@Base 3.5.0-1 + rtnl_link_ipip_get_link@libnl_3 3.5.0-1 + rtnl_link_ipip_get_local@Base 3.5.0-1 + rtnl_link_ipip_get_local@libnl_3 3.5.0-1 + rtnl_link_ipip_get_pmtudisc@Base 3.5.0-1 + rtnl_link_ipip_get_pmtudisc@libnl_3 3.5.0-1 + rtnl_link_ipip_get_remote@Base 3.5.0-1 + rtnl_link_ipip_get_remote@libnl_3 3.5.0-1 + rtnl_link_ipip_get_tos@Base 3.5.0-1 + rtnl_link_ipip_get_tos@libnl_3 3.5.0-1 + rtnl_link_ipip_get_ttl@Base 3.5.0-1 + rtnl_link_ipip_get_ttl@libnl_3 3.5.0-1 + rtnl_link_ipip_set_link@Base 3.5.0-1 + rtnl_link_ipip_set_link@libnl_3 3.5.0-1 + rtnl_link_ipip_set_local@Base 3.5.0-1 + rtnl_link_ipip_set_local@libnl_3 3.5.0-1 + rtnl_link_ipip_set_pmtudisc@Base 3.5.0-1 + rtnl_link_ipip_set_pmtudisc@libnl_3 3.5.0-1 + rtnl_link_ipip_set_remote@Base 3.5.0-1 + rtnl_link_ipip_set_remote@libnl_3 3.5.0-1 + rtnl_link_ipip_set_tos@Base 3.5.0-1 + rtnl_link_ipip_set_tos@libnl_3 3.5.0-1 + rtnl_link_ipip_set_ttl@Base 3.5.0-1 + rtnl_link_ipip_set_ttl@libnl_3 3.5.0-1 + rtnl_link_ipvlan_alloc@Base 3.5.0-1 + rtnl_link_ipvlan_alloc@libnl_3_2_27 3.5.0-1 + rtnl_link_ipvlan_get_mode@Base 3.5.0-1 + rtnl_link_ipvlan_get_mode@libnl_3_2_27 3.5.0-1 + rtnl_link_ipvlan_mode2str@Base 3.5.0-1 + rtnl_link_ipvlan_mode2str@libnl_3_2_27 3.5.0-1 + rtnl_link_ipvlan_set_mode@Base 3.5.0-1 + rtnl_link_ipvlan_set_mode@libnl_3_2_27 3.5.0-1 + rtnl_link_ipvlan_str2mode@Base 3.5.0-1 + rtnl_link_ipvlan_str2mode@libnl_3_2_27 3.5.0-1 + rtnl_link_ipvti_add@Base 3.5.0-1 + rtnl_link_ipvti_add@libnl_3 3.5.0-1 + rtnl_link_ipvti_alloc@Base 3.5.0-1 + rtnl_link_ipvti_alloc@libnl_3 3.5.0-1 + rtnl_link_ipvti_get_ikey@Base 3.5.0-1 + rtnl_link_ipvti_get_ikey@libnl_3 3.5.0-1 + rtnl_link_ipvti_get_link@Base 3.5.0-1 + rtnl_link_ipvti_get_link@libnl_3 3.5.0-1 + rtnl_link_ipvti_get_local@Base 3.5.0-1 + rtnl_link_ipvti_get_local@libnl_3 3.5.0-1 + rtnl_link_ipvti_get_okey@Base 3.5.0-1 + rtnl_link_ipvti_get_okey@libnl_3 3.5.0-1 + rtnl_link_ipvti_get_remote@Base 3.5.0-1 + rtnl_link_ipvti_get_remote@libnl_3 3.5.0-1 + rtnl_link_ipvti_set_ikey@Base 3.5.0-1 + rtnl_link_ipvti_set_ikey@libnl_3 3.5.0-1 + rtnl_link_ipvti_set_link@Base 3.5.0-1 + rtnl_link_ipvti_set_link@libnl_3 3.5.0-1 + rtnl_link_ipvti_set_local@Base 3.5.0-1 + rtnl_link_ipvti_set_local@libnl_3 3.5.0-1 + rtnl_link_ipvti_set_okey@Base 3.5.0-1 + rtnl_link_ipvti_set_okey@libnl_3 3.5.0-1 + rtnl_link_ipvti_set_remote@Base 3.5.0-1 + rtnl_link_ipvti_set_remote@libnl_3 3.5.0-1 + rtnl_link_is_bridge@Base 3.5.0-1 + rtnl_link_is_bridge@libnl_3 3.5.0-1 + rtnl_link_is_can@Base 3.5.0-1 + rtnl_link_is_can@libnl_3 3.5.0-1 + rtnl_link_is_geneve@libnl_3_5 3.5.0-1 + rtnl_link_is_ip6_tnl@Base 3.5.0-1 + rtnl_link_is_ip6_tnl@libnl_3 3.5.0-1 + rtnl_link_is_ipgre@Base 3.5.0-1 + rtnl_link_is_ipgre@libnl_3 3.5.0-1 + rtnl_link_is_ipgretap@libnl_3_2_29 3.5.0-1 + rtnl_link_is_ipip@Base 3.5.0-1 + rtnl_link_is_ipip@libnl_3 3.5.0-1 + rtnl_link_is_ipvlan@Base 3.5.0-1 + rtnl_link_is_ipvlan@libnl_3_2_27 3.5.0-1 + rtnl_link_is_ipvti@Base 3.5.0-1 + rtnl_link_is_ipvti@libnl_3 3.5.0-1 + rtnl_link_is_macvlan@Base 3.5.0-1 + rtnl_link_is_macvlan@libnl_3 3.5.0-1 + rtnl_link_is_macvtap@libnl_3_2_28 3.5.0-1 + rtnl_link_is_sit@Base 3.5.0-1 + rtnl_link_is_sit@libnl_3 3.5.0-1 + rtnl_link_is_veth@Base 3.5.0-1 + rtnl_link_is_veth@libnl_3 3.5.0-1 + rtnl_link_is_vlan@Base 3.5.0-1 + rtnl_link_is_vlan@libnl_3 3.5.0-1 + rtnl_link_is_vrf@libnl_3_2_28 3.5.0-1 + rtnl_link_is_vxlan@Base 3.5.0-1 + rtnl_link_is_vxlan@libnl_3 3.5.0-1 + rtnl_link_is_xfrmi@libnl_3_5 3.5.0-1 + rtnl_link_macsec_alloc@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_cipher_suite@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_encoding_sa@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_encrypt@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_end_station@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_icv_len@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_port@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_protect@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_replay_protect@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_scb@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_sci@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_send_sci@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_validation_type@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_get_window@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_cipher_suite@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_encoding_sa@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_encrypt@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_end_station@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_icv_len@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_port@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_protect@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_replay_protect@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_scb@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_sci@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_send_sci@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_validation_type@libnl_3_2_28 3.5.0-1 + rtnl_link_macsec_set_window@libnl_3_2_28 3.5.0-1 + rtnl_link_macvlan_add_macaddr@libnl_3_2_29 3.5.0-1 + rtnl_link_macvlan_alloc@Base 3.5.0-1 + rtnl_link_macvlan_alloc@libnl_3 3.5.0-1 + rtnl_link_macvlan_count_macaddr@libnl_3_2_29 3.5.0-1 + rtnl_link_macvlan_del_macaddr@libnl_3_2_29 3.5.0-1 + rtnl_link_macvlan_flags2str@Base 3.5.0-1 + rtnl_link_macvlan_flags2str@libnl_3 3.5.0-1 + rtnl_link_macvlan_get_flags@Base 3.5.0-1 + rtnl_link_macvlan_get_flags@libnl_3 3.5.0-1 + rtnl_link_macvlan_get_macaddr@libnl_3_2_29 3.5.0-1 + rtnl_link_macvlan_get_macmode@libnl_3_2_29 3.5.0-1 + rtnl_link_macvlan_get_mode@Base 3.5.0-1 + rtnl_link_macvlan_get_mode@libnl_3 3.5.0-1 + rtnl_link_macvlan_macmode2str@libnl_3_2_29 3.5.0-1 + rtnl_link_macvlan_mode2str@Base 3.5.0-1 + rtnl_link_macvlan_mode2str@libnl_3 3.5.0-1 + rtnl_link_macvlan_set_flags@Base 3.5.0-1 + rtnl_link_macvlan_set_flags@libnl_3 3.5.0-1 + rtnl_link_macvlan_set_macmode@libnl_3_2_29 3.5.0-1 + rtnl_link_macvlan_set_mode@Base 3.5.0-1 + rtnl_link_macvlan_set_mode@libnl_3 3.5.0-1 + rtnl_link_macvlan_str2flags@Base 3.5.0-1 + rtnl_link_macvlan_str2flags@libnl_3 3.5.0-1 + rtnl_link_macvlan_str2macmode@libnl_3_2_29 3.5.0-1 + rtnl_link_macvlan_str2mode@Base 3.5.0-1 + rtnl_link_macvlan_str2mode@libnl_3 3.5.0-1 + rtnl_link_macvlan_unset_flags@Base 3.5.0-1 + rtnl_link_macvlan_unset_flags@libnl_3 3.5.0-1 + rtnl_link_macvtap_alloc@libnl_3_2_28 3.5.0-1 + rtnl_link_macvtap_flags2str@libnl_3_2_28 3.5.0-1 + rtnl_link_macvtap_get_flags@libnl_3_2_28 3.5.0-1 + rtnl_link_macvtap_get_mode@libnl_3_2_28 3.5.0-1 + rtnl_link_macvtap_mode2str@libnl_3_2_28 3.5.0-1 + rtnl_link_macvtap_set_flags@libnl_3_2_28 3.5.0-1 + rtnl_link_macvtap_set_mode@libnl_3_2_28 3.5.0-1 + rtnl_link_macvtap_str2flags@libnl_3_2_28 3.5.0-1 + rtnl_link_macvtap_str2mode@libnl_3_2_28 3.5.0-1 + rtnl_link_macvtap_unset_flags@libnl_3_2_28 3.5.0-1 + rtnl_link_mode2str@Base 3.5.0-1 + rtnl_link_mode2str@libnl_3 3.5.0-1 + rtnl_link_name2i@Base 3.5.0-1 + rtnl_link_name2i@libnl_3 3.5.0-1 + rtnl_link_operstate2str@Base 3.5.0-1 + rtnl_link_operstate2str@libnl_3 3.5.0-1 + rtnl_link_ppp_alloc@libnl_3_2_29 3.5.0-1 + rtnl_link_ppp_get_fd@libnl_3_2_29 3.5.0-1 + rtnl_link_ppp_set_fd@libnl_3_2_29 3.5.0-1 + rtnl_link_put@Base 3.5.0-1 + rtnl_link_put@libnl_3 3.5.0-1 + rtnl_link_register_info@Base 3.5.0-1 + rtnl_link_register_info@libnl_3 3.5.0-1 + rtnl_link_release@Base 3.5.0-1 + rtnl_link_release@libnl_3 3.5.0-1 + rtnl_link_release_ifindex@Base 3.5.0-1 + rtnl_link_release_ifindex@libnl_3 3.5.0-1 + rtnl_link_set_addr@Base 3.5.0-1 + rtnl_link_set_addr@libnl_3 3.5.0-1 + rtnl_link_set_arptype@Base 3.5.0-1 + rtnl_link_set_arptype@libnl_3 3.5.0-1 + rtnl_link_set_broadcast@Base 3.5.0-1 + rtnl_link_set_broadcast@libnl_3 3.5.0-1 + rtnl_link_set_carrier@Base 3.5.0-1 + rtnl_link_set_carrier@libnl_3 3.5.0-1 + rtnl_link_set_family@Base 3.5.0-1 + rtnl_link_set_family@libnl_3 3.5.0-1 + rtnl_link_set_flags@Base 3.5.0-1 + rtnl_link_set_flags@libnl_3 3.5.0-1 + rtnl_link_set_group@Base 3.5.0-1 + rtnl_link_set_group@libnl_3 3.5.0-1 + rtnl_link_set_ifalias@Base 3.5.0-1 + rtnl_link_set_ifalias@libnl_3 3.5.0-1 + rtnl_link_set_ifindex@Base 3.5.0-1 + rtnl_link_set_ifindex@libnl_3 3.5.0-1 + rtnl_link_set_info_type@Base 3.5.0-1 + rtnl_link_set_info_type@libnl_3 3.5.0-1 + rtnl_link_set_link@Base 3.5.0-1 + rtnl_link_set_link@libnl_3 3.5.0-1 + rtnl_link_set_link_netnsid@Base 3.5.0-1 + rtnl_link_set_link_netnsid@libnl_3_2_27 3.5.0-1 + rtnl_link_set_linkmode@Base 3.5.0-1 + rtnl_link_set_linkmode@libnl_3 3.5.0-1 + rtnl_link_set_master@Base 3.5.0-1 + rtnl_link_set_master@libnl_3 3.5.0-1 + rtnl_link_set_mtu@Base 3.5.0-1 + rtnl_link_set_mtu@libnl_3 3.5.0-1 + rtnl_link_set_name@Base 3.5.0-1 + rtnl_link_set_name@libnl_3 3.5.0-1 + rtnl_link_set_ns_fd@Base 3.5.0-1 + rtnl_link_set_ns_fd@libnl_3 3.5.0-1 + rtnl_link_set_ns_pid@Base 3.5.0-1 + rtnl_link_set_ns_pid@libnl_3 3.5.0-1 + rtnl_link_set_num_rx_queues@Base 3.5.0-1 + rtnl_link_set_num_rx_queues@libnl_3 3.5.0-1 + rtnl_link_set_num_tx_queues@Base 3.5.0-1 + rtnl_link_set_num_tx_queues@libnl_3 3.5.0-1 + rtnl_link_set_operstate@Base 3.5.0-1 + rtnl_link_set_operstate@libnl_3 3.5.0-1 + rtnl_link_set_promiscuity@Base 3.5.0-1 + rtnl_link_set_promiscuity@libnl_3 3.5.0-1 + rtnl_link_set_qdisc@Base 3.5.0-1 + rtnl_link_set_qdisc@libnl_3 3.5.0-1 + rtnl_link_set_slave_type@libnl_3_5 3.5.0-1 + rtnl_link_set_stat@Base 3.5.0-1 + rtnl_link_set_stat@libnl_3 3.5.0-1 + rtnl_link_set_txqlen@Base 3.5.0-1 + rtnl_link_set_txqlen@libnl_3 3.5.0-1 + rtnl_link_set_type@Base 3.5.0-1 + rtnl_link_set_type@libnl_3 3.5.0-1 + rtnl_link_set_vf_list@libnl_3_2_29 3.5.0-1 + rtnl_link_set_weight@Base 3.5.0-1 + rtnl_link_set_weight@libnl_3 3.5.0-1 + rtnl_link_sit_add@Base 3.5.0-1 + rtnl_link_sit_add@libnl_3 3.5.0-1 + rtnl_link_sit_alloc@Base 3.5.0-1 + rtnl_link_sit_alloc@libnl_3 3.5.0-1 + rtnl_link_sit_get_flags@Base 3.5.0-1 + rtnl_link_sit_get_flags@libnl_3 3.5.0-1 + rtnl_link_sit_get_ip6rd_prefix@libnl_3_2_28 3.5.0-1 + rtnl_link_sit_get_ip6rd_prefixlen@libnl_3_2_28 3.5.0-1 + rtnl_link_sit_get_ip6rd_relay_prefix@libnl_3_2_28 3.5.0-1 + rtnl_link_sit_get_ip6rd_relay_prefixlen@libnl_3_2_28 3.5.0-1 + rtnl_link_sit_get_link@Base 3.5.0-1 + rtnl_link_sit_get_link@libnl_3 3.5.0-1 + rtnl_link_sit_get_local@Base 3.5.0-1 + rtnl_link_sit_get_local@libnl_3 3.5.0-1 + rtnl_link_sit_get_pmtudisc@Base 3.5.0-1 + rtnl_link_sit_get_pmtudisc@libnl_3 3.5.0-1 + rtnl_link_sit_get_proto@Base 3.5.0-1 + rtnl_link_sit_get_proto@libnl_3 3.5.0-1 + rtnl_link_sit_get_remote@Base 3.5.0-1 + rtnl_link_sit_get_remote@libnl_3 3.5.0-1 + rtnl_link_sit_get_tos@Base 3.5.0-1 + rtnl_link_sit_get_tos@libnl_3 3.5.0-1 + rtnl_link_sit_get_ttl@Base 3.5.0-1 + rtnl_link_sit_get_ttl@libnl_3 3.5.0-1 + rtnl_link_sit_set_flags@Base 3.5.0-1 + rtnl_link_sit_set_flags@libnl_3 3.5.0-1 + rtnl_link_sit_set_ip6rd_prefix@libnl_3_2_28 3.5.0-1 + rtnl_link_sit_set_ip6rd_prefixlen@libnl_3_2_28 3.5.0-1 + rtnl_link_sit_set_ip6rd_relay_prefix@libnl_3_2_28 3.5.0-1 + rtnl_link_sit_set_ip6rd_relay_prefixlen@libnl_3_2_28 3.5.0-1 + rtnl_link_sit_set_link@Base 3.5.0-1 + rtnl_link_sit_set_link@libnl_3 3.5.0-1 + rtnl_link_sit_set_local@Base 3.5.0-1 + rtnl_link_sit_set_local@libnl_3 3.5.0-1 + rtnl_link_sit_set_pmtudisc@Base 3.5.0-1 + rtnl_link_sit_set_pmtudisc@libnl_3 3.5.0-1 + rtnl_link_sit_set_proto@Base 3.5.0-1 + rtnl_link_sit_set_proto@libnl_3 3.5.0-1 + rtnl_link_sit_set_remote@Base 3.5.0-1 + rtnl_link_sit_set_remote@libnl_3 3.5.0-1 + rtnl_link_sit_set_tos@Base 3.5.0-1 + rtnl_link_sit_set_tos@libnl_3 3.5.0-1 + rtnl_link_sit_set_ttl@Base 3.5.0-1 + rtnl_link_sit_set_ttl@libnl_3 3.5.0-1 + rtnl_link_stat2str@Base 3.5.0-1 + rtnl_link_stat2str@libnl_3 3.5.0-1 + rtnl_link_str2carrier@Base 3.5.0-1 + rtnl_link_str2carrier@libnl_3 3.5.0-1 + rtnl_link_str2flags@Base 3.5.0-1 + rtnl_link_str2flags@libnl_3 3.5.0-1 + rtnl_link_str2mode@Base 3.5.0-1 + rtnl_link_str2mode@libnl_3 3.5.0-1 + rtnl_link_str2operstate@Base 3.5.0-1 + rtnl_link_str2operstate@libnl_3 3.5.0-1 + rtnl_link_str2stat@Base 3.5.0-1 + rtnl_link_str2stat@libnl_3 3.5.0-1 + rtnl_link_unregister_info@Base 3.5.0-1 + rtnl_link_unregister_info@libnl_3 3.5.0-1 + rtnl_link_unset_flags@Base 3.5.0-1 + rtnl_link_unset_flags@libnl_3 3.5.0-1 + rtnl_link_unset_vf_list@libnl_3_2_29 3.5.0-1 + rtnl_link_veth_add@Base 3.5.0-1 + rtnl_link_veth_add@libnl_3 3.5.0-1 + rtnl_link_veth_alloc@Base 3.5.0-1 + rtnl_link_veth_alloc@libnl_3 3.5.0-1 + rtnl_link_veth_get_peer@Base 3.5.0-1 + rtnl_link_veth_get_peer@libnl_3 3.5.0-1 + rtnl_link_veth_release@Base 3.5.0-1 + rtnl_link_veth_release@libnl_3 3.5.0-1 + rtnl_link_vf_add@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_alloc@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_free@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_get@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_get_addr@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_get_index@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_get_linkstate@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_get_rate@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_get_rss_query_en@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_get_spoofchk@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_get_stat@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_get_trust@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_get_vlans@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_linkstate2str@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_put@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_set_addr@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_set_ib_node_guid@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_set_ib_port_guid@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_set_index@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_set_linkstate@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_set_rate@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_set_rss_query_en@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_set_spoofchk@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_set_trust@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_set_vlans@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_str2guid@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_str2linkstate@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_str2vlanproto@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_vlan_alloc@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_vlan_free@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_vlan_put@libnl_3_2_29 3.5.0-1 + rtnl_link_vf_vlanproto2str@libnl_3_2_29 3.5.0-1 + rtnl_link_vlan_alloc@Base 3.5.0-1 + rtnl_link_vlan_alloc@libnl_3 3.5.0-1 + rtnl_link_vlan_flags2str@Base 3.5.0-1 + rtnl_link_vlan_flags2str@libnl_3 3.5.0-1 + rtnl_link_vlan_get_egress_map@Base 3.5.0-1 + rtnl_link_vlan_get_egress_map@libnl_3 3.5.0-1 + rtnl_link_vlan_get_flags@Base 3.5.0-1 + rtnl_link_vlan_get_flags@libnl_3 3.5.0-1 + rtnl_link_vlan_get_id@Base 3.5.0-1 + rtnl_link_vlan_get_id@libnl_3 3.5.0-1 + rtnl_link_vlan_get_ingress_map@Base 3.5.0-1 + rtnl_link_vlan_get_ingress_map@libnl_3 3.5.0-1 + rtnl_link_vlan_get_protocol@Base 3.5.0-1 + rtnl_link_vlan_get_protocol@libnl_3 3.5.0-1 + rtnl_link_vlan_set_egress_map@Base 3.5.0-1 + rtnl_link_vlan_set_egress_map@libnl_3 3.5.0-1 + rtnl_link_vlan_set_flags@Base 3.5.0-1 + rtnl_link_vlan_set_flags@libnl_3 3.5.0-1 + rtnl_link_vlan_set_id@Base 3.5.0-1 + rtnl_link_vlan_set_id@libnl_3 3.5.0-1 + rtnl_link_vlan_set_ingress_map@Base 3.5.0-1 + rtnl_link_vlan_set_ingress_map@libnl_3 3.5.0-1 + rtnl_link_vlan_set_protocol@Base 3.5.0-1 + rtnl_link_vlan_set_protocol@libnl_3 3.5.0-1 + rtnl_link_vlan_str2flags@Base 3.5.0-1 + rtnl_link_vlan_str2flags@libnl_3 3.5.0-1 + rtnl_link_vlan_unset_flags@Base 3.5.0-1 + rtnl_link_vlan_unset_flags@libnl_3 3.5.0-1 + rtnl_link_vrf_alloc@libnl_3_2_28 3.5.0-1 + rtnl_link_vrf_get_tableid@libnl_3_2_28 3.5.0-1 + rtnl_link_vrf_set_tableid@libnl_3_2_28 3.5.0-1 + rtnl_link_vxlan_alloc@Base 3.5.0-1 + rtnl_link_vxlan_alloc@libnl_3 3.5.0-1 + rtnl_link_vxlan_disable_l2miss@Base 3.5.0-1 + rtnl_link_vxlan_disable_l2miss@libnl_3 3.5.0-1 + rtnl_link_vxlan_disable_l3miss@Base 3.5.0-1 + rtnl_link_vxlan_disable_l3miss@libnl_3 3.5.0-1 + rtnl_link_vxlan_disable_learning@Base 3.5.0-1 + rtnl_link_vxlan_disable_learning@libnl_3 3.5.0-1 + rtnl_link_vxlan_disable_proxy@Base 3.5.0-1 + rtnl_link_vxlan_disable_proxy@libnl_3 3.5.0-1 + rtnl_link_vxlan_disable_rsc@Base 3.5.0-1 + rtnl_link_vxlan_disable_rsc@libnl_3 3.5.0-1 + rtnl_link_vxlan_enable_l2miss@Base 3.5.0-1 + rtnl_link_vxlan_enable_l2miss@libnl_3 3.5.0-1 + rtnl_link_vxlan_enable_l3miss@Base 3.5.0-1 + rtnl_link_vxlan_enable_l3miss@libnl_3 3.5.0-1 + rtnl_link_vxlan_enable_learning@Base 3.5.0-1 + rtnl_link_vxlan_enable_learning@libnl_3 3.5.0-1 + rtnl_link_vxlan_enable_proxy@Base 3.5.0-1 + rtnl_link_vxlan_enable_proxy@libnl_3 3.5.0-1 + rtnl_link_vxlan_enable_rsc@Base 3.5.0-1 + rtnl_link_vxlan_enable_rsc@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_ageing@Base 3.5.0-1 + rtnl_link_vxlan_get_ageing@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_collect_metadata@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_get_flags@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_get_group@Base 3.5.0-1 + rtnl_link_vxlan_get_group@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_id@Base 3.5.0-1 + rtnl_link_vxlan_get_id@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_l2miss@Base 3.5.0-1 + rtnl_link_vxlan_get_l2miss@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_l3miss@Base 3.5.0-1 + rtnl_link_vxlan_get_l3miss@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_label@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_get_learning@Base 3.5.0-1 + rtnl_link_vxlan_get_learning@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_limit@Base 3.5.0-1 + rtnl_link_vxlan_get_limit@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_link@Base 3.5.0-1 + rtnl_link_vxlan_get_link@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_local@Base 3.5.0-1 + rtnl_link_vxlan_get_local@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_port@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_get_port_range@Base 3.5.0-1 + rtnl_link_vxlan_get_port_range@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_proxy@Base 3.5.0-1 + rtnl_link_vxlan_get_proxy@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_remcsum_rx@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_get_remcsum_tx@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_get_rsc@Base 3.5.0-1 + rtnl_link_vxlan_get_rsc@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_tos@Base 3.5.0-1 + rtnl_link_vxlan_get_tos@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_ttl@Base 3.5.0-1 + rtnl_link_vxlan_get_ttl@libnl_3 3.5.0-1 + rtnl_link_vxlan_get_udp_csum@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_get_udp_zero_csum6_rx@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_get_udp_zero_csum6_tx@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_set_ageing@Base 3.5.0-1 + rtnl_link_vxlan_set_ageing@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_collect_metadata@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_set_flags@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_set_group@Base 3.5.0-1 + rtnl_link_vxlan_set_group@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_id@Base 3.5.0-1 + rtnl_link_vxlan_set_id@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_l2miss@Base 3.5.0-1 + rtnl_link_vxlan_set_l2miss@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_l3miss@Base 3.5.0-1 + rtnl_link_vxlan_set_l3miss@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_label@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_set_learning@Base 3.5.0-1 + rtnl_link_vxlan_set_learning@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_limit@Base 3.5.0-1 + rtnl_link_vxlan_set_limit@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_link@Base 3.5.0-1 + rtnl_link_vxlan_set_link@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_local@Base 3.5.0-1 + rtnl_link_vxlan_set_local@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_port@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_set_port_range@Base 3.5.0-1 + rtnl_link_vxlan_set_port_range@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_proxy@Base 3.5.0-1 + rtnl_link_vxlan_set_proxy@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_remcsum_rx@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_set_remcsum_tx@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_set_rsc@Base 3.5.0-1 + rtnl_link_vxlan_set_rsc@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_tos@Base 3.5.0-1 + rtnl_link_vxlan_set_tos@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_ttl@Base 3.5.0-1 + rtnl_link_vxlan_set_ttl@libnl_3 3.5.0-1 + rtnl_link_vxlan_set_udp_csum@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_set_udp_zero_csum6_rx@libnl_3_2_29 3.5.0-1 + rtnl_link_vxlan_set_udp_zero_csum6_tx@libnl_3_2_29 3.5.0-1 + rtnl_link_xfrmi_alloc@libnl_3_5 3.5.0-1 + rtnl_link_xfrmi_get_if_id@libnl_3_5 3.5.0-1 + rtnl_link_xfrmi_get_link@libnl_3_5 3.5.0-1 + rtnl_link_xfrmi_set_if_id@libnl_3_5 3.5.0-1 + rtnl_link_xfrmi_set_link@libnl_3_5 3.5.0-1 + rtnl_mall_append_action@libnl_3_5 3.5.0-1 + rtnl_mall_del_action@libnl_3_5 3.5.0-1 + rtnl_mall_get_classid@libnl_3_5 3.5.0-1 + rtnl_mall_get_first_action@libnl_3_5 3.5.0-1 + rtnl_mall_get_flags@libnl_3_5 3.5.0-1 + rtnl_mall_set_classid@libnl_3_5 3.5.0-1 + rtnl_mall_set_flags@libnl_3_5 3.5.0-1 + rtnl_meta_value_alloc_id@Base 3.5.0-1 + rtnl_meta_value_alloc_id@libnl_3 3.5.0-1 + rtnl_meta_value_alloc_int@Base 3.5.0-1 + rtnl_meta_value_alloc_int@libnl_3 3.5.0-1 + rtnl_meta_value_alloc_var@Base 3.5.0-1 + rtnl_meta_value_alloc_var@libnl_3 3.5.0-1 + rtnl_meta_value_put@Base 3.5.0-1 + rtnl_meta_value_put@libnl_3 3.5.0-1 + rtnl_mirred_get_action@Base 3.5.0-1 + rtnl_mirred_get_action@libnl_3 3.5.0-1 + rtnl_mirred_get_ifindex@Base 3.5.0-1 + rtnl_mirred_get_ifindex@libnl_3 3.5.0-1 + rtnl_mirred_get_policy@Base 3.5.0-1 + rtnl_mirred_get_policy@libnl_3 3.5.0-1 + rtnl_mirred_set_action@Base 3.5.0-1 + rtnl_mirred_set_action@libnl_3 3.5.0-1 + rtnl_mirred_set_ifindex@Base 3.5.0-1 + rtnl_mirred_set_ifindex@libnl_3 3.5.0-1 + rtnl_mirred_set_policy@Base 3.5.0-1 + rtnl_mirred_set_policy@libnl_3 3.5.0-1 + rtnl_neigh_add@Base 3.5.0-1 + rtnl_neigh_add@libnl_3 3.5.0-1 + rtnl_neigh_alloc@Base 3.5.0-1 + rtnl_neigh_alloc@libnl_3 3.5.0-1 + rtnl_neigh_alloc_cache@Base 3.5.0-1 + rtnl_neigh_alloc_cache@libnl_3 3.5.0-1 + rtnl_neigh_alloc_cache_flags@libnl_3_2_28 3.5.0-1 + rtnl_neigh_build_add_request@Base 3.5.0-1 + rtnl_neigh_build_add_request@libnl_3 3.5.0-1 + rtnl_neigh_build_delete_request@Base 3.5.0-1 + rtnl_neigh_build_delete_request@libnl_3 3.5.0-1 + rtnl_neigh_delete@Base 3.5.0-1 + rtnl_neigh_delete@libnl_3 3.5.0-1 + rtnl_neigh_flags2str@Base 3.5.0-1 + rtnl_neigh_flags2str@libnl_3 3.5.0-1 + rtnl_neigh_get@Base 3.5.0-1 + rtnl_neigh_get@libnl_3 3.5.0-1 + rtnl_neigh_get_by_vlan@libnl_3_5 3.5.0-1 + rtnl_neigh_get_dst@Base 3.5.0-1 + rtnl_neigh_get_dst@libnl_3 3.5.0-1 + rtnl_neigh_get_family@Base 3.5.0-1 + rtnl_neigh_get_family@libnl_3 3.5.0-1 + rtnl_neigh_get_flags@Base 3.5.0-1 + rtnl_neigh_get_flags@libnl_3 3.5.0-1 + rtnl_neigh_get_ifindex@Base 3.5.0-1 + rtnl_neigh_get_ifindex@libnl_3 3.5.0-1 + rtnl_neigh_get_lladdr@Base 3.5.0-1 + rtnl_neigh_get_lladdr@libnl_3 3.5.0-1 + rtnl_neigh_get_master@libnl_3_5 3.5.0-1 + rtnl_neigh_get_state@Base 3.5.0-1 + rtnl_neigh_get_state@libnl_3 3.5.0-1 + rtnl_neigh_get_type@Base 3.5.0-1 + rtnl_neigh_get_type@libnl_3 3.5.0-1 + rtnl_neigh_get_vlan@Base 3.5.0-1 + rtnl_neigh_get_vlan@libnl_3_2_26 3.5.0-1 + rtnl_neigh_parse@Base 3.5.0-1 + rtnl_neigh_parse@libnl_3 3.5.0-1 + rtnl_neigh_put@Base 3.5.0-1 + rtnl_neigh_put@libnl_3 3.5.0-1 + rtnl_neigh_set_dst@Base 3.5.0-1 + rtnl_neigh_set_dst@libnl_3 3.5.0-1 + rtnl_neigh_set_family@Base 3.5.0-1 + rtnl_neigh_set_family@libnl_3 3.5.0-1 + rtnl_neigh_set_flags@Base 3.5.0-1 + rtnl_neigh_set_flags@libnl_3 3.5.0-1 + rtnl_neigh_set_ifindex@Base 3.5.0-1 + rtnl_neigh_set_ifindex@libnl_3 3.5.0-1 + rtnl_neigh_set_lladdr@Base 3.5.0-1 + rtnl_neigh_set_lladdr@libnl_3 3.5.0-1 + rtnl_neigh_set_master@libnl_3_5 3.5.0-1 + rtnl_neigh_set_state@Base 3.5.0-1 + rtnl_neigh_set_state@libnl_3 3.5.0-1 + rtnl_neigh_set_type@Base 3.5.0-1 + rtnl_neigh_set_type@libnl_3 3.5.0-1 + rtnl_neigh_set_vlan@Base 3.5.0-1 + rtnl_neigh_set_vlan@libnl_3_2_26 3.5.0-1 + rtnl_neigh_state2str@Base 3.5.0-1 + rtnl_neigh_state2str@libnl_3 3.5.0-1 + rtnl_neigh_str2flag@Base 3.5.0-1 + rtnl_neigh_str2flag@libnl_3 3.5.0-1 + rtnl_neigh_str2state@Base 3.5.0-1 + rtnl_neigh_str2state@libnl_3 3.5.0-1 + rtnl_neigh_unset_flags@Base 3.5.0-1 + rtnl_neigh_unset_flags@libnl_3 3.5.0-1 + rtnl_neigh_unset_state@Base 3.5.0-1 + rtnl_neigh_unset_state@libnl_3 3.5.0-1 + rtnl_neightbl_alloc@Base 3.5.0-1 + rtnl_neightbl_alloc@libnl_3 3.5.0-1 + rtnl_neightbl_alloc_cache@Base 3.5.0-1 + rtnl_neightbl_alloc_cache@libnl_3 3.5.0-1 + rtnl_neightbl_build_change_request@Base 3.5.0-1 + rtnl_neightbl_build_change_request@libnl_3 3.5.0-1 + rtnl_neightbl_change@Base 3.5.0-1 + rtnl_neightbl_change@libnl_3 3.5.0-1 + rtnl_neightbl_get@Base 3.5.0-1 + rtnl_neightbl_get@libnl_3 3.5.0-1 + rtnl_neightbl_put@Base 3.5.0-1 + rtnl_neightbl_put@libnl_3 3.5.0-1 + rtnl_neightbl_set_anycast_delay@Base 3.5.0-1 + rtnl_neightbl_set_anycast_delay@libnl_3 3.5.0-1 + rtnl_neightbl_set_app_probes@Base 3.5.0-1 + rtnl_neightbl_set_app_probes@libnl_3 3.5.0-1 + rtnl_neightbl_set_base_reachable_time@Base 3.5.0-1 + rtnl_neightbl_set_base_reachable_time@libnl_3 3.5.0-1 + rtnl_neightbl_set_delay_probe_time@Base 3.5.0-1 + rtnl_neightbl_set_delay_probe_time@libnl_3 3.5.0-1 + rtnl_neightbl_set_dev@Base 3.5.0-1 + rtnl_neightbl_set_dev@libnl_3 3.5.0-1 + rtnl_neightbl_set_family@Base 3.5.0-1 + rtnl_neightbl_set_family@libnl_3 3.5.0-1 + rtnl_neightbl_set_gc_interval@Base 3.5.0-1 + rtnl_neightbl_set_gc_interval@libnl_3 3.5.0-1 + rtnl_neightbl_set_gc_stale_time@Base 3.5.0-1 + rtnl_neightbl_set_gc_stale_time@libnl_3 3.5.0-1 + rtnl_neightbl_set_gc_tresh1@Base 3.5.0-1 + rtnl_neightbl_set_gc_tresh1@libnl_3 3.5.0-1 + rtnl_neightbl_set_gc_tresh2@Base 3.5.0-1 + rtnl_neightbl_set_gc_tresh2@libnl_3 3.5.0-1 + rtnl_neightbl_set_gc_tresh3@Base 3.5.0-1 + rtnl_neightbl_set_gc_tresh3@libnl_3 3.5.0-1 + rtnl_neightbl_set_locktime@Base 3.5.0-1 + rtnl_neightbl_set_locktime@libnl_3 3.5.0-1 + rtnl_neightbl_set_mcast_probes@Base 3.5.0-1 + rtnl_neightbl_set_mcast_probes@libnl_3 3.5.0-1 + rtnl_neightbl_set_name@Base 3.5.0-1 + rtnl_neightbl_set_name@libnl_3 3.5.0-1 + rtnl_neightbl_set_proxy_delay@Base 3.5.0-1 + rtnl_neightbl_set_proxy_delay@libnl_3 3.5.0-1 + rtnl_neightbl_set_proxy_queue_len@Base 3.5.0-1 + rtnl_neightbl_set_proxy_queue_len@libnl_3 3.5.0-1 + rtnl_neightbl_set_queue_len@Base 3.5.0-1 + rtnl_neightbl_set_queue_len@libnl_3 3.5.0-1 + rtnl_neightbl_set_retrans_time@Base 3.5.0-1 + rtnl_neightbl_set_retrans_time@libnl_3 3.5.0-1 + rtnl_neightbl_set_ucast_probes@Base 3.5.0-1 + rtnl_neightbl_set_ucast_probes@libnl_3 3.5.0-1 + rtnl_netconf_get_all@libnl_3_4 3.5.0-1 + rtnl_netconf_get_by_idx@libnl_3_4 3.5.0-1 + rtnl_netconf_get_default@libnl_3_4 3.5.0-1 + rtnl_netconf_get_family@libnl_3_4 3.5.0-1 + rtnl_netconf_get_forwarding@libnl_3_4 3.5.0-1 + rtnl_netconf_get_ifindex@libnl_3_4 3.5.0-1 + rtnl_netconf_get_input@libnl_3_4 3.5.0-1 + rtnl_netconf_get_mc_forwarding@libnl_3_4 3.5.0-1 + rtnl_netconf_get_rp_filter@libnl_3_4 3.5.0-1 + rtnl_netconf_put@libnl_3_4 3.5.0-1 + rtnl_netem_get_corruption_correlation@Base 3.5.0-1 + rtnl_netem_get_corruption_correlation@libnl_3 3.5.0-1 + rtnl_netem_get_corruption_probability@Base 3.5.0-1 + rtnl_netem_get_corruption_probability@libnl_3 3.5.0-1 + rtnl_netem_get_delay@Base 3.5.0-1 + rtnl_netem_get_delay@libnl_3 3.5.0-1 + rtnl_netem_get_delay_correlation@Base 3.5.0-1 + rtnl_netem_get_delay_correlation@libnl_3 3.5.0-1 + rtnl_netem_get_delay_distribution@Base 3.5.0-1 + rtnl_netem_get_delay_distribution@libnl_3 3.5.0-1 + rtnl_netem_get_delay_distribution_size@Base 3.5.0-1 + rtnl_netem_get_delay_distribution_size@libnl_3 3.5.0-1 + rtnl_netem_get_duplicate@Base 3.5.0-1 + rtnl_netem_get_duplicate@libnl_3 3.5.0-1 + rtnl_netem_get_duplicate_correlation@Base 3.5.0-1 + rtnl_netem_get_duplicate_correlation@libnl_3 3.5.0-1 + rtnl_netem_get_gap@Base 3.5.0-1 + rtnl_netem_get_gap@libnl_3 3.5.0-1 + rtnl_netem_get_jitter@Base 3.5.0-1 + rtnl_netem_get_jitter@libnl_3 3.5.0-1 + rtnl_netem_get_limit@Base 3.5.0-1 + rtnl_netem_get_limit@libnl_3 3.5.0-1 + rtnl_netem_get_loss@Base 3.5.0-1 + rtnl_netem_get_loss@libnl_3 3.5.0-1 + rtnl_netem_get_loss_correlation@Base 3.5.0-1 + rtnl_netem_get_loss_correlation@libnl_3 3.5.0-1 + rtnl_netem_get_reorder_correlation@Base 3.5.0-1 + rtnl_netem_get_reorder_correlation@libnl_3 3.5.0-1 + rtnl_netem_get_reorder_probability@Base 3.5.0-1 + rtnl_netem_get_reorder_probability@libnl_3 3.5.0-1 + rtnl_netem_set_corruption_correlation@Base 3.5.0-1 + rtnl_netem_set_corruption_correlation@libnl_3 3.5.0-1 + rtnl_netem_set_corruption_probability@Base 3.5.0-1 + rtnl_netem_set_corruption_probability@libnl_3 3.5.0-1 + rtnl_netem_set_delay@Base 3.5.0-1 + rtnl_netem_set_delay@libnl_3 3.5.0-1 + rtnl_netem_set_delay_correlation@Base 3.5.0-1 + rtnl_netem_set_delay_correlation@libnl_3 3.5.0-1 + rtnl_netem_set_delay_distribution@Base 3.5.0-1 + rtnl_netem_set_delay_distribution@libnl_3 3.5.0-1 + rtnl_netem_set_delay_distribution_data@libnl_3_5 3.5.0-1 + rtnl_netem_set_duplicate@Base 3.5.0-1 + rtnl_netem_set_duplicate@libnl_3 3.5.0-1 + rtnl_netem_set_duplicate_correlation@Base 3.5.0-1 + rtnl_netem_set_duplicate_correlation@libnl_3 3.5.0-1 + rtnl_netem_set_gap@Base 3.5.0-1 + rtnl_netem_set_gap@libnl_3 3.5.0-1 + rtnl_netem_set_jitter@Base 3.5.0-1 + rtnl_netem_set_jitter@libnl_3 3.5.0-1 + rtnl_netem_set_limit@Base 3.5.0-1 + rtnl_netem_set_limit@libnl_3 3.5.0-1 + rtnl_netem_set_loss@Base 3.5.0-1 + rtnl_netem_set_loss@libnl_3 3.5.0-1 + rtnl_netem_set_loss_correlation@Base 3.5.0-1 + rtnl_netem_set_loss_correlation@libnl_3 3.5.0-1 + rtnl_netem_set_reorder_correlation@Base 3.5.0-1 + rtnl_netem_set_reorder_correlation@libnl_3 3.5.0-1 + rtnl_netem_set_reorder_probability@Base 3.5.0-1 + rtnl_netem_set_reorder_probability@libnl_3 3.5.0-1 + rtnl_pktloc_add@Base 3.5.0-1 + rtnl_pktloc_add@libnl_3 3.5.0-1 + rtnl_pktloc_alloc@Base 3.5.0-1 + rtnl_pktloc_alloc@libnl_3 3.5.0-1 + rtnl_pktloc_foreach@Base 3.5.0-1 + rtnl_pktloc_foreach@libnl_3 3.5.0-1 + rtnl_pktloc_lookup@Base 3.5.0-1 + rtnl_pktloc_lookup@libnl_3 3.5.0-1 + rtnl_pktloc_put@Base 3.5.0-1 + rtnl_pktloc_put@libnl_3 3.5.0-1 + rtnl_prio2str@Base 3.5.0-1 + rtnl_prio2str@libnl_3 3.5.0-1 + rtnl_qdisc_add@Base 3.5.0-1 + rtnl_qdisc_add@libnl_3 3.5.0-1 + rtnl_qdisc_alloc@Base 3.5.0-1 + rtnl_qdisc_alloc@libnl_3 3.5.0-1 + rtnl_qdisc_alloc_cache@Base 3.5.0-1 + rtnl_qdisc_alloc_cache@libnl_3 3.5.0-1 + rtnl_qdisc_build_add_request@Base 3.5.0-1 + rtnl_qdisc_build_add_request@libnl_3 3.5.0-1 + rtnl_qdisc_build_change_request@Base 3.5.0-1 + rtnl_qdisc_build_change_request@libnl_3 3.5.0-1 + rtnl_qdisc_build_delete_request@Base 3.5.0-1 + rtnl_qdisc_build_delete_request@libnl_3 3.5.0-1 + rtnl_qdisc_build_update_request@Base 3.5.0-1 + rtnl_qdisc_build_update_request@libnl_3 3.5.0-1 + rtnl_qdisc_change@Base 3.5.0-1 + rtnl_qdisc_change@libnl_3 3.5.0-1 + rtnl_qdisc_delete@Base 3.5.0-1 + rtnl_qdisc_delete@libnl_3 3.5.0-1 + rtnl_qdisc_dsmark_get_default_index@Base 3.5.0-1 + rtnl_qdisc_dsmark_get_default_index@libnl_3 3.5.0-1 + rtnl_qdisc_dsmark_get_indices@Base 3.5.0-1 + rtnl_qdisc_dsmark_get_indices@libnl_3 3.5.0-1 + rtnl_qdisc_dsmark_get_set_tc_index@Base 3.5.0-1 + rtnl_qdisc_dsmark_get_set_tc_index@libnl_3 3.5.0-1 + rtnl_qdisc_dsmark_set_default_index@Base 3.5.0-1 + rtnl_qdisc_dsmark_set_default_index@libnl_3 3.5.0-1 + rtnl_qdisc_dsmark_set_indices@Base 3.5.0-1 + rtnl_qdisc_dsmark_set_indices@libnl_3 3.5.0-1 + rtnl_qdisc_dsmark_set_set_tc_index@Base 3.5.0-1 + rtnl_qdisc_dsmark_set_set_tc_index@libnl_3 3.5.0-1 + rtnl_qdisc_fifo_get_limit@Base 3.5.0-1 + rtnl_qdisc_fifo_get_limit@libnl_3 3.5.0-1 + rtnl_qdisc_fifo_set_limit@Base 3.5.0-1 + rtnl_qdisc_fifo_set_limit@libnl_3 3.5.0-1 + rtnl_qdisc_foreach_child@Base 3.5.0-1 + rtnl_qdisc_foreach_child@libnl_3 3.5.0-1 + rtnl_qdisc_foreach_cls@Base 3.5.0-1 + rtnl_qdisc_foreach_cls@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_get_ecn@Base 3.5.0-1 + rtnl_qdisc_fq_codel_get_ecn@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_get_flows@Base 3.5.0-1 + rtnl_qdisc_fq_codel_get_flows@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_get_interval@Base 3.5.0-1 + rtnl_qdisc_fq_codel_get_interval@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_get_limit@Base 3.5.0-1 + rtnl_qdisc_fq_codel_get_limit@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_get_quantum@Base 3.5.0-1 + rtnl_qdisc_fq_codel_get_quantum@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_get_target@Base 3.5.0-1 + rtnl_qdisc_fq_codel_get_target@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_set_ecn@Base 3.5.0-1 + rtnl_qdisc_fq_codel_set_ecn@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_set_flows@Base 3.5.0-1 + rtnl_qdisc_fq_codel_set_flows@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_set_interval@Base 3.5.0-1 + rtnl_qdisc_fq_codel_set_interval@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_set_limit@Base 3.5.0-1 + rtnl_qdisc_fq_codel_set_limit@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_set_quantum@Base 3.5.0-1 + rtnl_qdisc_fq_codel_set_quantum@libnl_3 3.5.0-1 + rtnl_qdisc_fq_codel_set_target@Base 3.5.0-1 + rtnl_qdisc_fq_codel_set_target@libnl_3 3.5.0-1 + rtnl_qdisc_get@Base 3.5.0-1 + rtnl_qdisc_get@libnl_3 3.5.0-1 + rtnl_qdisc_get_by_parent@Base 3.5.0-1 + rtnl_qdisc_get_by_parent@libnl_3 3.5.0-1 + rtnl_qdisc_hfsc_get_defcls@Base 3.5.0-1 + rtnl_qdisc_hfsc_get_defcls@libnl_3 3.5.0-1 + rtnl_qdisc_hfsc_set_defcls@Base 3.5.0-1 + rtnl_qdisc_hfsc_set_defcls@libnl_3 3.5.0-1 + rtnl_qdisc_mqprio_get_hw_offload@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_get_max_rate@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_get_min_rate@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_get_mode@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_get_num_tc@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_get_priomap@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_get_queue@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_get_shaper@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_hw_offload@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_set_max_rate@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_set_min_rate@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_set_mode@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_set_num_tc@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_set_priomap@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_set_queue@libnl_3_5 3.5.0-1 + rtnl_qdisc_mqprio_set_shaper@libnl_3_5 3.5.0-1 + rtnl_qdisc_plug_buffer@Base 3.5.0-1 + rtnl_qdisc_plug_buffer@libnl_3 3.5.0-1 + rtnl_qdisc_plug_release_indefinite@Base 3.5.0-1 + rtnl_qdisc_plug_release_indefinite@libnl_3 3.5.0-1 + rtnl_qdisc_plug_release_one@Base 3.5.0-1 + rtnl_qdisc_plug_release_one@libnl_3 3.5.0-1 + rtnl_qdisc_plug_set_limit@Base 3.5.0-1 + rtnl_qdisc_plug_set_limit@libnl_3 3.5.0-1 + rtnl_qdisc_prio_get_bands@Base 3.5.0-1 + rtnl_qdisc_prio_get_bands@libnl_3 3.5.0-1 + rtnl_qdisc_prio_get_priomap@Base 3.5.0-1 + rtnl_qdisc_prio_get_priomap@libnl_3 3.5.0-1 + rtnl_qdisc_prio_set_bands@Base 3.5.0-1 + rtnl_qdisc_prio_set_bands@libnl_3 3.5.0-1 + rtnl_qdisc_prio_set_priomap@Base 3.5.0-1 + rtnl_qdisc_prio_set_priomap@libnl_3 3.5.0-1 + rtnl_qdisc_put@Base 3.5.0-1 + rtnl_qdisc_put@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_get_limit@Base 3.5.0-1 + rtnl_qdisc_tbf_get_limit@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_get_peakrate@Base 3.5.0-1 + rtnl_qdisc_tbf_get_peakrate@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_get_peakrate_bucket@Base 3.5.0-1 + rtnl_qdisc_tbf_get_peakrate_bucket@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_get_peakrate_cell@Base 3.5.0-1 + rtnl_qdisc_tbf_get_peakrate_cell@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_get_rate@Base 3.5.0-1 + rtnl_qdisc_tbf_get_rate@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_get_rate_bucket@Base 3.5.0-1 + rtnl_qdisc_tbf_get_rate_bucket@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_get_rate_cell@Base 3.5.0-1 + rtnl_qdisc_tbf_get_rate_cell@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_set_limit@Base 3.5.0-1 + rtnl_qdisc_tbf_set_limit@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_set_limit_by_latency@Base 3.5.0-1 + rtnl_qdisc_tbf_set_limit_by_latency@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_set_peakrate@Base 3.5.0-1 + rtnl_qdisc_tbf_set_peakrate@libnl_3 3.5.0-1 + rtnl_qdisc_tbf_set_rate@Base 3.5.0-1 + rtnl_qdisc_tbf_set_rate@libnl_3 3.5.0-1 + rtnl_qdisc_update@Base 3.5.0-1 + rtnl_qdisc_update@libnl_3 3.5.0-1 + rtnl_realms2str@Base 3.5.0-1 + rtnl_realms2str@libnl_3 3.5.0-1 + rtnl_red_get_limit@Base 3.5.0-1 + rtnl_red_get_limit@libnl_3 3.5.0-1 + rtnl_red_set_limit@Base 3.5.0-1 + rtnl_red_set_limit@libnl_3 3.5.0-1 + rtnl_route_add@Base 3.5.0-1 + rtnl_route_add@libnl_3 3.5.0-1 + rtnl_route_add_nexthop@Base 3.5.0-1 + rtnl_route_add_nexthop@libnl_3 3.5.0-1 + rtnl_route_alloc@Base 3.5.0-1 + rtnl_route_alloc@libnl_3 3.5.0-1 + rtnl_route_alloc_cache@Base 3.5.0-1 + rtnl_route_alloc_cache@libnl_3 3.5.0-1 + rtnl_route_build_add_request@Base 3.5.0-1 + rtnl_route_build_add_request@libnl_3 3.5.0-1 + rtnl_route_build_del_request@Base 3.5.0-1 + rtnl_route_build_del_request@libnl_3 3.5.0-1 + rtnl_route_build_msg@Base 3.5.0-1 + rtnl_route_build_msg@libnl_3 3.5.0-1 + rtnl_route_delete@Base 3.5.0-1 + rtnl_route_delete@libnl_3 3.5.0-1 + rtnl_route_foreach_nexthop@Base 3.5.0-1 + rtnl_route_foreach_nexthop@libnl_3 3.5.0-1 + rtnl_route_get@Base 3.5.0-1 + rtnl_route_get@libnl_3 3.5.0-1 + rtnl_route_get_dst@Base 3.5.0-1 + rtnl_route_get_dst@libnl_3 3.5.0-1 + rtnl_route_get_family@Base 3.5.0-1 + rtnl_route_get_family@libnl_3 3.5.0-1 + rtnl_route_get_flags@Base 3.5.0-1 + rtnl_route_get_flags@libnl_3 3.5.0-1 + rtnl_route_get_iif@Base 3.5.0-1 + rtnl_route_get_iif@libnl_3 3.5.0-1 + rtnl_route_get_metric@Base 3.5.0-1 + rtnl_route_get_metric@libnl_3 3.5.0-1 + rtnl_route_get_nexthops@Base 3.5.0-1 + rtnl_route_get_nexthops@libnl_3 3.5.0-1 + rtnl_route_get_nnexthops@Base 3.5.0-1 + rtnl_route_get_nnexthops@libnl_3 3.5.0-1 + rtnl_route_get_pref_src@Base 3.5.0-1 + rtnl_route_get_pref_src@libnl_3 3.5.0-1 + rtnl_route_get_priority@Base 3.5.0-1 + rtnl_route_get_priority@libnl_3 3.5.0-1 + rtnl_route_get_protocol@Base 3.5.0-1 + rtnl_route_get_protocol@libnl_3 3.5.0-1 + rtnl_route_get_scope@Base 3.5.0-1 + rtnl_route_get_scope@libnl_3 3.5.0-1 + rtnl_route_get_src@Base 3.5.0-1 + rtnl_route_get_src@libnl_3 3.5.0-1 + rtnl_route_get_table@Base 3.5.0-1 + rtnl_route_get_table@libnl_3 3.5.0-1 + rtnl_route_get_tos@Base 3.5.0-1 + rtnl_route_get_tos@libnl_3 3.5.0-1 + rtnl_route_get_ttl_propagate@libnl_3_4 3.5.0-1 + rtnl_route_get_type@Base 3.5.0-1 + rtnl_route_get_type@libnl_3 3.5.0-1 + rtnl_route_guess_scope@Base 3.5.0-1 + rtnl_route_guess_scope@libnl_3 3.5.0-1 + rtnl_route_metric2str@Base 3.5.0-1 + rtnl_route_metric2str@libnl_3 3.5.0-1 + rtnl_route_nexthop_n@Base 3.5.0-1 + rtnl_route_nexthop_n@libnl_3 3.5.0-1 + rtnl_route_nh_alloc@Base 3.5.0-1 + rtnl_route_nh_alloc@libnl_3 3.5.0-1 + rtnl_route_nh_clone@Base 3.5.0-1 + rtnl_route_nh_clone@libnl_3 3.5.0-1 + rtnl_route_nh_compare@Base 3.5.0-1 + rtnl_route_nh_compare@libnl_3 3.5.0-1 + rtnl_route_nh_dump@Base 3.5.0-1 + rtnl_route_nh_dump@libnl_3 3.5.0-1 + rtnl_route_nh_encap_mpls@libnl_3_4 3.5.0-1 + rtnl_route_nh_flags2str@Base 3.5.0-1 + rtnl_route_nh_flags2str@libnl_3 3.5.0-1 + rtnl_route_nh_free@Base 3.5.0-1 + rtnl_route_nh_free@libnl_3 3.5.0-1 + rtnl_route_nh_get_flags@Base 3.5.0-1 + rtnl_route_nh_get_flags@libnl_3 3.5.0-1 + rtnl_route_nh_get_gateway@Base 3.5.0-1 + rtnl_route_nh_get_gateway@libnl_3 3.5.0-1 + rtnl_route_nh_get_ifindex@Base 3.5.0-1 + rtnl_route_nh_get_ifindex@libnl_3 3.5.0-1 + rtnl_route_nh_get_newdst@libnl_3_4 3.5.0-1 + rtnl_route_nh_get_realms@Base 3.5.0-1 + rtnl_route_nh_get_realms@libnl_3 3.5.0-1 + rtnl_route_nh_get_via@libnl_3_4 3.5.0-1 + rtnl_route_nh_get_weight@Base 3.5.0-1 + rtnl_route_nh_get_weight@libnl_3 3.5.0-1 + rtnl_route_nh_set_flags@Base 3.5.0-1 + rtnl_route_nh_set_flags@libnl_3 3.5.0-1 + rtnl_route_nh_set_gateway@Base 3.5.0-1 + rtnl_route_nh_set_gateway@libnl_3 3.5.0-1 + rtnl_route_nh_set_ifindex@Base 3.5.0-1 + rtnl_route_nh_set_ifindex@libnl_3 3.5.0-1 + rtnl_route_nh_set_newdst@libnl_3_4 3.5.0-1 + rtnl_route_nh_set_realms@Base 3.5.0-1 + rtnl_route_nh_set_realms@libnl_3 3.5.0-1 + rtnl_route_nh_set_via@libnl_3_4 3.5.0-1 + rtnl_route_nh_set_weight@Base 3.5.0-1 + rtnl_route_nh_set_weight@libnl_3 3.5.0-1 + rtnl_route_nh_str2flags@Base 3.5.0-1 + rtnl_route_nh_str2flags@libnl_3 3.5.0-1 + rtnl_route_nh_unset_flags@Base 3.5.0-1 + rtnl_route_nh_unset_flags@libnl_3 3.5.0-1 + rtnl_route_parse@Base 3.5.0-1 + rtnl_route_parse@libnl_3 3.5.0-1 + rtnl_route_proto2str@Base 3.5.0-1 + rtnl_route_proto2str@libnl_3 3.5.0-1 + rtnl_route_put@Base 3.5.0-1 + rtnl_route_put@libnl_3 3.5.0-1 + rtnl_route_read_protocol_names@Base 3.5.0-1 + rtnl_route_read_protocol_names@libnl_3 3.5.0-1 + rtnl_route_read_table_names@Base 3.5.0-1 + rtnl_route_read_table_names@libnl_3 3.5.0-1 + rtnl_route_remove_nexthop@Base 3.5.0-1 + rtnl_route_remove_nexthop@libnl_3 3.5.0-1 + rtnl_route_set_dst@Base 3.5.0-1 + rtnl_route_set_dst@libnl_3 3.5.0-1 + rtnl_route_set_family@Base 3.5.0-1 + rtnl_route_set_family@libnl_3 3.5.0-1 + rtnl_route_set_flags@Base 3.5.0-1 + rtnl_route_set_flags@libnl_3 3.5.0-1 + rtnl_route_set_iif@Base 3.5.0-1 + rtnl_route_set_iif@libnl_3 3.5.0-1 + rtnl_route_set_metric@Base 3.5.0-1 + rtnl_route_set_metric@libnl_3 3.5.0-1 + rtnl_route_set_pref_src@Base 3.5.0-1 + rtnl_route_set_pref_src@libnl_3 3.5.0-1 + rtnl_route_set_priority@Base 3.5.0-1 + rtnl_route_set_priority@libnl_3 3.5.0-1 + rtnl_route_set_protocol@Base 3.5.0-1 + rtnl_route_set_protocol@libnl_3 3.5.0-1 + rtnl_route_set_scope@Base 3.5.0-1 + rtnl_route_set_scope@libnl_3 3.5.0-1 + rtnl_route_set_src@Base 3.5.0-1 + rtnl_route_set_src@libnl_3 3.5.0-1 + rtnl_route_set_table@Base 3.5.0-1 + rtnl_route_set_table@libnl_3 3.5.0-1 + rtnl_route_set_tos@Base 3.5.0-1 + rtnl_route_set_tos@libnl_3 3.5.0-1 + rtnl_route_set_ttl_propagate@libnl_3_4 3.5.0-1 + rtnl_route_set_type@Base 3.5.0-1 + rtnl_route_set_type@libnl_3 3.5.0-1 + rtnl_route_str2metric@Base 3.5.0-1 + rtnl_route_str2metric@libnl_3 3.5.0-1 + rtnl_route_str2proto@Base 3.5.0-1 + rtnl_route_str2proto@libnl_3 3.5.0-1 + rtnl_route_str2table@Base 3.5.0-1 + rtnl_route_str2table@libnl_3 3.5.0-1 + rtnl_route_table2str@Base 3.5.0-1 + rtnl_route_table2str@libnl_3 3.5.0-1 + rtnl_route_unset_flags@Base 3.5.0-1 + rtnl_route_unset_flags@libnl_3 3.5.0-1 + rtnl_route_unset_metric@Base 3.5.0-1 + rtnl_route_unset_metric@libnl_3 3.5.0-1 + rtnl_rule_add@Base 3.5.0-1 + rtnl_rule_add@libnl_3 3.5.0-1 + rtnl_rule_alloc@Base 3.5.0-1 + rtnl_rule_alloc@libnl_3 3.5.0-1 + rtnl_rule_alloc_cache@Base 3.5.0-1 + rtnl_rule_alloc_cache@libnl_3 3.5.0-1 + rtnl_rule_build_add_request@Base 3.5.0-1 + rtnl_rule_build_add_request@libnl_3 3.5.0-1 + rtnl_rule_build_delete_request@Base 3.5.0-1 + rtnl_rule_build_delete_request@libnl_3 3.5.0-1 + rtnl_rule_delete@Base 3.5.0-1 + rtnl_rule_delete@libnl_3 3.5.0-1 + rtnl_rule_get_action@Base 3.5.0-1 + rtnl_rule_get_action@libnl_3 3.5.0-1 + rtnl_rule_get_dport@libnl_3_5 3.5.0-1 + rtnl_rule_get_dsfield@Base 3.5.0-1 + rtnl_rule_get_dsfield@libnl_3 3.5.0-1 + rtnl_rule_get_dst@Base 3.5.0-1 + rtnl_rule_get_dst@libnl_3 3.5.0-1 + rtnl_rule_get_family@Base 3.5.0-1 + rtnl_rule_get_family@libnl_3 3.5.0-1 + rtnl_rule_get_goto@Base 3.5.0-1 + rtnl_rule_get_goto@libnl_3 3.5.0-1 + rtnl_rule_get_iif@Base 3.5.0-1 + rtnl_rule_get_iif@libnl_3 3.5.0-1 + rtnl_rule_get_ipproto@libnl_3_5 3.5.0-1 + rtnl_rule_get_l3mdev@libnl_3_4 3.5.0-1 + rtnl_rule_get_mark@Base 3.5.0-1 + rtnl_rule_get_mark@libnl_3 3.5.0-1 + rtnl_rule_get_mask@Base 3.5.0-1 + rtnl_rule_get_mask@libnl_3 3.5.0-1 + rtnl_rule_get_oif@Base 3.5.0-1 + rtnl_rule_get_oif@libnl_3 3.5.0-1 + rtnl_rule_get_prio@Base 3.5.0-1 + rtnl_rule_get_prio@libnl_3 3.5.0-1 + rtnl_rule_get_protocol@libnl_3_5 3.5.0-1 + rtnl_rule_get_realms@Base 3.5.0-1 + rtnl_rule_get_realms@libnl_3 3.5.0-1 + rtnl_rule_get_sport@libnl_3_5 3.5.0-1 + rtnl_rule_get_src@Base 3.5.0-1 + rtnl_rule_get_src@libnl_3 3.5.0-1 + rtnl_rule_get_table@Base 3.5.0-1 + rtnl_rule_get_table@libnl_3 3.5.0-1 + rtnl_rule_put@Base 3.5.0-1 + rtnl_rule_put@libnl_3 3.5.0-1 + rtnl_rule_set_action@Base 3.5.0-1 + rtnl_rule_set_action@libnl_3 3.5.0-1 + rtnl_rule_set_dport@libnl_3_5 3.5.0-1 + rtnl_rule_set_dport_range@libnl_3_5 3.5.0-1 + rtnl_rule_set_dsfield@Base 3.5.0-1 + rtnl_rule_set_dsfield@libnl_3 3.5.0-1 + rtnl_rule_set_dst@Base 3.5.0-1 + rtnl_rule_set_dst@libnl_3 3.5.0-1 + rtnl_rule_set_family@Base 3.5.0-1 + rtnl_rule_set_family@libnl_3 3.5.0-1 + rtnl_rule_set_goto@Base 3.5.0-1 + rtnl_rule_set_goto@libnl_3 3.5.0-1 + rtnl_rule_set_iif@Base 3.5.0-1 + rtnl_rule_set_iif@libnl_3 3.5.0-1 + rtnl_rule_set_ipproto@libnl_3_5 3.5.0-1 + rtnl_rule_set_l3mdev@libnl_3_4 3.5.0-1 + rtnl_rule_set_mark@Base 3.5.0-1 + rtnl_rule_set_mark@libnl_3 3.5.0-1 + rtnl_rule_set_mask@Base 3.5.0-1 + rtnl_rule_set_mask@libnl_3 3.5.0-1 + rtnl_rule_set_oif@Base 3.5.0-1 + rtnl_rule_set_oif@libnl_3 3.5.0-1 + rtnl_rule_set_prio@Base 3.5.0-1 + rtnl_rule_set_prio@libnl_3 3.5.0-1 + rtnl_rule_set_protocol@libnl_3_5 3.5.0-1 + rtnl_rule_set_realms@Base 3.5.0-1 + rtnl_rule_set_realms@libnl_3 3.5.0-1 + rtnl_rule_set_sport@libnl_3_5 3.5.0-1 + rtnl_rule_set_sport_range@libnl_3_5 3.5.0-1 + rtnl_rule_set_src@Base 3.5.0-1 + rtnl_rule_set_src@libnl_3 3.5.0-1 + rtnl_rule_set_table@Base 3.5.0-1 + rtnl_rule_set_table@libnl_3 3.5.0-1 + rtnl_scope2str@Base 3.5.0-1 + rtnl_scope2str@libnl_3 3.5.0-1 + rtnl_sfq_get_divisor@Base 3.5.0-1 + rtnl_sfq_get_divisor@libnl_3 3.5.0-1 + rtnl_sfq_get_limit@Base 3.5.0-1 + rtnl_sfq_get_limit@libnl_3 3.5.0-1 + rtnl_sfq_get_perturb@Base 3.5.0-1 + rtnl_sfq_get_perturb@libnl_3 3.5.0-1 + rtnl_sfq_get_quantum@Base 3.5.0-1 + rtnl_sfq_get_quantum@libnl_3 3.5.0-1 + rtnl_sfq_set_limit@Base 3.5.0-1 + rtnl_sfq_set_limit@libnl_3 3.5.0-1 + rtnl_sfq_set_perturb@Base 3.5.0-1 + rtnl_sfq_set_perturb@libnl_3 3.5.0-1 + rtnl_sfq_set_quantum@Base 3.5.0-1 + rtnl_sfq_set_quantum@libnl_3 3.5.0-1 + rtnl_skbedit_get_action@Base 3.5.0-1 + rtnl_skbedit_get_action@libnl_3_2_26 3.5.0-1 + rtnl_skbedit_get_mark@Base 3.5.0-1 + rtnl_skbedit_get_mark@libnl_3_2_26 3.5.0-1 + rtnl_skbedit_get_priority@Base 3.5.0-1 + rtnl_skbedit_get_priority@libnl_3_2_26 3.5.0-1 + rtnl_skbedit_get_queue_mapping@Base 3.5.0-1 + rtnl_skbedit_get_queue_mapping@libnl_3_2_26 3.5.0-1 + rtnl_skbedit_set_action@Base 3.5.0-1 + rtnl_skbedit_set_action@libnl_3_2_26 3.5.0-1 + rtnl_skbedit_set_mark@Base 3.5.0-1 + rtnl_skbedit_set_mark@libnl_3_2_26 3.5.0-1 + rtnl_skbedit_set_priority@Base 3.5.0-1 + rtnl_skbedit_set_priority@libnl_3_2_26 3.5.0-1 + rtnl_skbedit_set_queue_mapping@Base 3.5.0-1 + rtnl_skbedit_set_queue_mapping@libnl_3_2_26 3.5.0-1 + rtnl_str2prio@Base 3.5.0-1 + rtnl_str2prio@libnl_3 3.5.0-1 + rtnl_str2scope@Base 3.5.0-1 + rtnl_str2scope@libnl_3 3.5.0-1 + rtnl_tc_build_rate_table@Base 3.5.0-1 + rtnl_tc_build_rate_table@libnl_3 3.5.0-1 + rtnl_tc_calc_bufsize@Base 3.5.0-1 + rtnl_tc_calc_bufsize@libnl_3 3.5.0-1 + rtnl_tc_calc_cell_log@Base 3.5.0-1 + rtnl_tc_calc_cell_log@libnl_3 3.5.0-1 + rtnl_tc_calc_txtime@Base 3.5.0-1 + rtnl_tc_calc_txtime@libnl_3 3.5.0-1 + rtnl_tc_clone@Base 3.5.0-1 + rtnl_tc_clone@libnl_3 3.5.0-1 + rtnl_tc_compare@Base 3.5.0-1 + rtnl_tc_compare@libnl_3 3.5.0-1 + rtnl_tc_data@Base 3.5.0-1 + rtnl_tc_data@libnl_3 3.5.0-1 + rtnl_tc_data_check@Base 3.5.0-1 + rtnl_tc_data_check@libnl_3 3.5.0-1 + rtnl_tc_data_peek@Base 3.5.0-1 + rtnl_tc_dump_details@Base 3.5.0-1 + rtnl_tc_dump_details@libnl_3 3.5.0-1 + rtnl_tc_dump_line@Base 3.5.0-1 + rtnl_tc_dump_line@libnl_3 3.5.0-1 + rtnl_tc_dump_stats@Base 3.5.0-1 + rtnl_tc_dump_stats@libnl_3 3.5.0-1 + rtnl_tc_free_data@Base 3.5.0-1 + rtnl_tc_free_data@libnl_3 3.5.0-1 + rtnl_tc_get_chain@libnl_3_5 3.5.0-1 + rtnl_tc_get_handle@Base 3.5.0-1 + rtnl_tc_get_handle@libnl_3 3.5.0-1 + rtnl_tc_get_ifindex@Base 3.5.0-1 + rtnl_tc_get_ifindex@libnl_3 3.5.0-1 + rtnl_tc_get_kind@Base 3.5.0-1 + rtnl_tc_get_kind@libnl_3 3.5.0-1 + rtnl_tc_get_link@Base 3.5.0-1 + rtnl_tc_get_link@libnl_3 3.5.0-1 + rtnl_tc_get_linktype@Base 3.5.0-1 + rtnl_tc_get_linktype@libnl_3 3.5.0-1 + rtnl_tc_get_mpu@Base 3.5.0-1 + rtnl_tc_get_mpu@libnl_3 3.5.0-1 + rtnl_tc_get_mtu@Base 3.5.0-1 + rtnl_tc_get_mtu@libnl_3 3.5.0-1 + rtnl_tc_get_ops@Base 3.5.0-1 + rtnl_tc_get_ops@libnl_3 3.5.0-1 + rtnl_tc_get_overhead@Base 3.5.0-1 + rtnl_tc_get_overhead@libnl_3 3.5.0-1 + rtnl_tc_get_parent@Base 3.5.0-1 + rtnl_tc_get_parent@libnl_3 3.5.0-1 + rtnl_tc_get_stat@Base 3.5.0-1 + rtnl_tc_get_stat@libnl_3 3.5.0-1 + rtnl_tc_handle2str@Base 3.5.0-1 + rtnl_tc_handle2str@libnl_3 3.5.0-1 + rtnl_tc_lookup_ops@Base 3.5.0-1 + rtnl_tc_lookup_ops@libnl_3 3.5.0-1 + rtnl_tc_msg_build@Base 3.5.0-1 + rtnl_tc_msg_build@libnl_3 3.5.0-1 + rtnl_tc_msg_parse@Base 3.5.0-1 + rtnl_tc_msg_parse@libnl_3 3.5.0-1 + rtnl_tc_read_classid_file@Base 3.5.0-1 + rtnl_tc_read_classid_file@libnl_3 3.5.0-1 + rtnl_tc_register@Base 3.5.0-1 + rtnl_tc_register@libnl_3 3.5.0-1 + rtnl_tc_set_chain@libnl_3_5 3.5.0-1 + rtnl_tc_set_handle@Base 3.5.0-1 + rtnl_tc_set_handle@libnl_3 3.5.0-1 + rtnl_tc_set_ifindex@Base 3.5.0-1 + rtnl_tc_set_ifindex@libnl_3 3.5.0-1 + rtnl_tc_set_kind@Base 3.5.0-1 + rtnl_tc_set_kind@libnl_3 3.5.0-1 + rtnl_tc_set_link@Base 3.5.0-1 + rtnl_tc_set_link@libnl_3 3.5.0-1 + rtnl_tc_set_linktype@Base 3.5.0-1 + rtnl_tc_set_linktype@libnl_3 3.5.0-1 + rtnl_tc_set_mpu@Base 3.5.0-1 + rtnl_tc_set_mpu@libnl_3 3.5.0-1 + rtnl_tc_set_mtu@Base 3.5.0-1 + rtnl_tc_set_mtu@libnl_3 3.5.0-1 + rtnl_tc_set_overhead@Base 3.5.0-1 + rtnl_tc_set_overhead@libnl_3 3.5.0-1 + rtnl_tc_set_parent@Base 3.5.0-1 + rtnl_tc_set_parent@libnl_3 3.5.0-1 + rtnl_tc_stat2str@Base 3.5.0-1 + rtnl_tc_stat2str@libnl_3_2_26 3.5.0-1 + rtnl_tc_str2handle@Base 3.5.0-1 + rtnl_tc_str2handle@libnl_3 3.5.0-1 + rtnl_tc_str2stat@Base 3.5.0-1 + rtnl_tc_str2stat@libnl_3_2_26 3.5.0-1 + rtnl_tc_type_register@Base 3.5.0-1 + rtnl_tc_type_register@libnl_3 3.5.0-1 + rtnl_tc_type_unregister@Base 3.5.0-1 + rtnl_tc_type_unregister@libnl_3 3.5.0-1 + rtnl_tc_unregister@Base 3.5.0-1 + rtnl_tc_unregister@libnl_3 3.5.0-1 + rtnl_u32_add_action@Base 3.5.0-1 + rtnl_u32_add_action@libnl_3 3.5.0-1 + rtnl_u32_add_key@Base 3.5.0-1 + rtnl_u32_add_key@libnl_3 3.5.0-1 + rtnl_u32_add_key_in6_addr@Base 3.5.0-1 + rtnl_u32_add_key_in6_addr@libnl_3 3.5.0-1 + rtnl_u32_add_key_in_addr@Base 3.5.0-1 + rtnl_u32_add_key_in_addr@libnl_3 3.5.0-1 + rtnl_u32_add_key_uint16@Base 3.5.0-1 + rtnl_u32_add_key_uint16@libnl_3 3.5.0-1 + rtnl_u32_add_key_uint32@Base 3.5.0-1 + rtnl_u32_add_key_uint32@libnl_3 3.5.0-1 + rtnl_u32_add_key_uint8@Base 3.5.0-1 + rtnl_u32_add_key_uint8@libnl_3 3.5.0-1 + rtnl_u32_add_mark@Base 3.5.0-1 + rtnl_u32_add_mark@libnl_3 3.5.0-1 + rtnl_u32_del_action@Base 3.5.0-1 + rtnl_u32_del_action@libnl_3 3.5.0-1 + rtnl_u32_del_mark@Base 3.5.0-1 + rtnl_u32_del_mark@libnl_3 3.5.0-1 + rtnl_u32_get_action@libnl_3_4 3.5.0-1 + rtnl_u32_get_classid@Base 3.5.0-1 + rtnl_u32_get_classid@libnl_3_2_26 3.5.0-1 + rtnl_u32_get_key@Base 3.5.0-1 + rtnl_u32_get_key@libnl_3 3.5.0-1 + rtnl_u32_set_classid@Base 3.5.0-1 + rtnl_u32_set_classid@libnl_3 3.5.0-1 + rtnl_u32_set_cls_terminal@Base 3.5.0-1 + rtnl_u32_set_cls_terminal@libnl_3 3.5.0-1 + rtnl_u32_set_divisor@Base 3.5.0-1 + rtnl_u32_set_divisor@libnl_3 3.5.0-1 + rtnl_u32_set_flags@Base 3.5.0-1 + rtnl_u32_set_flags@libnl_3 3.5.0-1 + rtnl_u32_set_handle@Base 3.5.0-1 + rtnl_u32_set_handle@libnl_3 3.5.0-1 + rtnl_u32_set_hashmask@Base 3.5.0-1 + rtnl_u32_set_hashmask@libnl_3 3.5.0-1 + rtnl_u32_set_hashtable@Base 3.5.0-1 + rtnl_u32_set_hashtable@libnl_3 3.5.0-1 + rtnl_u32_set_link@Base 3.5.0-1 + rtnl_u32_set_link@libnl_3 3.5.0-1 + rtnl_u32_set_selector@libnl_3_2_29 3.5.0-1 + rtnl_vlan_get_action@libnl_3_5 3.5.0-1 + rtnl_vlan_get_mode@libnl_3_5 3.5.0-1 + rtnl_vlan_get_protocol@libnl_3_5 3.5.0-1 + rtnl_vlan_get_vlan_id@libnl_3_5 3.5.0-1 + rtnl_vlan_get_vlan_prio@libnl_3_5 3.5.0-1 + rtnl_vlan_set_action@libnl_3_5 3.5.0-1 + rtnl_vlan_set_mode@libnl_3_5 3.5.0-1 + rtnl_vlan_set_protocol@libnl_3_5 3.5.0-1 + rtnl_vlan_set_vlan_id@libnl_3_5 3.5.0-1 + rtnl_vlan_set_vlan_prio@libnl_3_5 3.5.0-1 + tc_groups@Base 3.5.0-1 + tca_parse@Base 3.5.0-1 + tca_set_kind@Base 3.5.0-1 diff --git a/src/libnl3/debian/libnl-route-3-dev.install b/src/libnl3/debian/libnl-route-3-dev.install new file mode 100644 index 000000000000..37e248c3ed5b --- /dev/null +++ b/src/libnl3/debian/libnl-route-3-dev.install @@ -0,0 +1,3 @@ +debian/tmp/usr/lib/*/pkgconfig/libnl-route-3* +debian/tmp/usr/lib/*/libnl-route-3*.so +debian/tmp/usr/lib/*/libnl-route-3*.a diff --git a/src/libnl3/debian/libnl-utils.install b/src/libnl3/debian/libnl-utils.install new file mode 100644 index 000000000000..8ffdce84e93a --- /dev/null +++ b/src/libnl3/debian/libnl-utils.install @@ -0,0 +1 @@ +debian/tmp/usr/bin/* diff --git a/src/libnl3/debian/libnl-utils.manpages b/src/libnl3/debian/libnl-utils.manpages new file mode 100644 index 000000000000..0b2dcacf5b84 --- /dev/null +++ b/src/libnl3/debian/libnl-utils.manpages @@ -0,0 +1 @@ +debian/tmp/usr/share/man/man8/* diff --git a/src/libnl3/debian/libnl-xfrm-3-200.install b/src/libnl3/debian/libnl-xfrm-3-200.install new file mode 100644 index 000000000000..89b2d4e0c9e0 --- /dev/null +++ b/src/libnl3/debian/libnl-xfrm-3-200.install @@ -0,0 +1 @@ +debian/tmp/usr/lib/*/libnl-xfrm-3*.so.* diff --git a/src/libnl3/debian/libnl-xfrm-3-200.symbols b/src/libnl3/debian/libnl-xfrm-3-200.symbols new file mode 100644 index 000000000000..3704a7aa4384 --- /dev/null +++ b/src/libnl3/debian/libnl-xfrm-3-200.symbols @@ -0,0 +1,484 @@ +libnl-xfrm-3.so.200 libnl-xfrm-3-200 #MINVER# + libnl_3@libnl_3 3.5.0-1 + xfrmnl_ae_alloc@Base 3.5.0-1 + xfrmnl_ae_alloc@libnl_3 3.5.0-1 + xfrmnl_ae_build_get_request@Base 3.5.0-1 + xfrmnl_ae_build_get_request@libnl_3 3.5.0-1 + xfrmnl_ae_flags2str@Base 3.5.0-1 + xfrmnl_ae_flags2str@libnl_3 3.5.0-1 + xfrmnl_ae_get_curlifetime@Base 3.5.0-1 + xfrmnl_ae_get_curlifetime@libnl_3 3.5.0-1 + xfrmnl_ae_get_daddr@Base 3.5.0-1 + xfrmnl_ae_get_daddr@libnl_3 3.5.0-1 + xfrmnl_ae_get_family@Base 3.5.0-1 + xfrmnl_ae_get_family@libnl_3 3.5.0-1 + xfrmnl_ae_get_flags@Base 3.5.0-1 + xfrmnl_ae_get_flags@libnl_3 3.5.0-1 + xfrmnl_ae_get_kernel@Base 3.5.0-1 + xfrmnl_ae_get_kernel@libnl_3 3.5.0-1 + xfrmnl_ae_get_mark@Base 3.5.0-1 + xfrmnl_ae_get_mark@libnl_3 3.5.0-1 + xfrmnl_ae_get_proto@Base 3.5.0-1 + xfrmnl_ae_get_proto@libnl_3 3.5.0-1 + xfrmnl_ae_get_replay_maxage@Base 3.5.0-1 + xfrmnl_ae_get_replay_maxage@libnl_3 3.5.0-1 + xfrmnl_ae_get_replay_maxdiff@Base 3.5.0-1 + xfrmnl_ae_get_replay_maxdiff@libnl_3 3.5.0-1 + xfrmnl_ae_get_replay_state@Base 3.5.0-1 + xfrmnl_ae_get_replay_state@libnl_3 3.5.0-1 + xfrmnl_ae_get_replay_state_esn@Base 3.5.0-1 + xfrmnl_ae_get_replay_state_esn@libnl_3 3.5.0-1 + xfrmnl_ae_get_reqid@Base 3.5.0-1 + xfrmnl_ae_get_reqid@libnl_3 3.5.0-1 + xfrmnl_ae_get_saddr@Base 3.5.0-1 + xfrmnl_ae_get_saddr@libnl_3 3.5.0-1 + xfrmnl_ae_get_spi@Base 3.5.0-1 + xfrmnl_ae_get_spi@libnl_3 3.5.0-1 + xfrmnl_ae_parse@Base 3.5.0-1 + xfrmnl_ae_parse@libnl_3 3.5.0-1 + xfrmnl_ae_put@Base 3.5.0-1 + xfrmnl_ae_put@libnl_3 3.5.0-1 + xfrmnl_ae_set@Base 3.5.0-1 + xfrmnl_ae_set@libnl_3 3.5.0-1 + xfrmnl_ae_set_curlifetime@Base 3.5.0-1 + xfrmnl_ae_set_curlifetime@libnl_3 3.5.0-1 + xfrmnl_ae_set_daddr@Base 3.5.0-1 + xfrmnl_ae_set_daddr@libnl_3 3.5.0-1 + xfrmnl_ae_set_family@Base 3.5.0-1 + xfrmnl_ae_set_family@libnl_3 3.5.0-1 + xfrmnl_ae_set_flags@Base 3.5.0-1 + xfrmnl_ae_set_flags@libnl_3 3.5.0-1 + xfrmnl_ae_set_mark@Base 3.5.0-1 + xfrmnl_ae_set_mark@libnl_3 3.5.0-1 + xfrmnl_ae_set_proto@Base 3.5.0-1 + xfrmnl_ae_set_proto@libnl_3 3.5.0-1 + xfrmnl_ae_set_replay_maxage@Base 3.5.0-1 + xfrmnl_ae_set_replay_maxage@libnl_3 3.5.0-1 + xfrmnl_ae_set_replay_maxdiff@Base 3.5.0-1 + xfrmnl_ae_set_replay_maxdiff@libnl_3 3.5.0-1 + xfrmnl_ae_set_replay_state@Base 3.5.0-1 + xfrmnl_ae_set_replay_state@libnl_3 3.5.0-1 + xfrmnl_ae_set_replay_state_esn@Base 3.5.0-1 + xfrmnl_ae_set_replay_state_esn@libnl_3 3.5.0-1 + xfrmnl_ae_set_reqid@Base 3.5.0-1 + xfrmnl_ae_set_reqid@libnl_3 3.5.0-1 + xfrmnl_ae_set_saddr@Base 3.5.0-1 + xfrmnl_ae_set_saddr@libnl_3 3.5.0-1 + xfrmnl_ae_set_spi@Base 3.5.0-1 + xfrmnl_ae_set_spi@libnl_3 3.5.0-1 + xfrmnl_ae_str2flag@Base 3.5.0-1 + xfrmnl_ae_str2flag@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_alloc@Base 3.5.0-1 + xfrmnl_ltime_cfg_alloc@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_clone@Base 3.5.0-1 + xfrmnl_ltime_cfg_clone@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_cmp@Base 3.5.0-1 + xfrmnl_ltime_cfg_cmp@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_get@Base 3.5.0-1 + xfrmnl_ltime_cfg_get@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_get_hard_addexpires@Base 3.5.0-1 + xfrmnl_ltime_cfg_get_hard_addexpires@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_get_hard_bytelimit@Base 3.5.0-1 + xfrmnl_ltime_cfg_get_hard_bytelimit@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_get_hard_packetlimit@Base 3.5.0-1 + xfrmnl_ltime_cfg_get_hard_packetlimit@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_get_hard_useexpires@Base 3.5.0-1 + xfrmnl_ltime_cfg_get_hard_useexpires@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_get_soft_addexpires@Base 3.5.0-1 + xfrmnl_ltime_cfg_get_soft_addexpires@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_get_soft_bytelimit@Base 3.5.0-1 + xfrmnl_ltime_cfg_get_soft_bytelimit@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_get_soft_packetlimit@Base 3.5.0-1 + xfrmnl_ltime_cfg_get_soft_packetlimit@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_get_soft_useexpires@Base 3.5.0-1 + xfrmnl_ltime_cfg_get_soft_useexpires@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_put@Base 3.5.0-1 + xfrmnl_ltime_cfg_put@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_set_hard_addexpires@Base 3.5.0-1 + xfrmnl_ltime_cfg_set_hard_addexpires@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_set_hard_bytelimit@Base 3.5.0-1 + xfrmnl_ltime_cfg_set_hard_bytelimit@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_set_hard_packetlimit@Base 3.5.0-1 + xfrmnl_ltime_cfg_set_hard_packetlimit@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_set_hard_useexpires@Base 3.5.0-1 + xfrmnl_ltime_cfg_set_hard_useexpires@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_set_soft_addexpires@Base 3.5.0-1 + xfrmnl_ltime_cfg_set_soft_addexpires@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_set_soft_bytelimit@Base 3.5.0-1 + xfrmnl_ltime_cfg_set_soft_bytelimit@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_set_soft_packetlimit@Base 3.5.0-1 + xfrmnl_ltime_cfg_set_soft_packetlimit@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_set_soft_useexpires@Base 3.5.0-1 + xfrmnl_ltime_cfg_set_soft_useexpires@libnl_3 3.5.0-1 + xfrmnl_ltime_cfg_shared@Base 3.5.0-1 + xfrmnl_ltime_cfg_shared@libnl_3 3.5.0-1 + xfrmnl_sa_add@Base 3.5.0-1 + xfrmnl_sa_add@libnl_3 3.5.0-1 + xfrmnl_sa_alloc@Base 3.5.0-1 + xfrmnl_sa_alloc@libnl_3 3.5.0-1 + xfrmnl_sa_alloc_cache@Base 3.5.0-1 + xfrmnl_sa_alloc_cache@libnl_3 3.5.0-1 + xfrmnl_sa_build_add_request@Base 3.5.0-1 + xfrmnl_sa_build_add_request@libnl_3 3.5.0-1 + xfrmnl_sa_build_delete_request@Base 3.5.0-1 + xfrmnl_sa_build_delete_request@libnl_3 3.5.0-1 + xfrmnl_sa_build_get_request@Base 3.5.0-1 + xfrmnl_sa_build_get_request@libnl_3 3.5.0-1 + xfrmnl_sa_build_update_request@Base 3.5.0-1 + xfrmnl_sa_build_update_request@libnl_3 3.5.0-1 + xfrmnl_sa_delete@Base 3.5.0-1 + xfrmnl_sa_delete@libnl_3 3.5.0-1 + xfrmnl_sa_flags2str@Base 3.5.0-1 + xfrmnl_sa_flags2str@libnl_3 3.5.0-1 + xfrmnl_sa_get@Base 3.5.0-1 + xfrmnl_sa_get@libnl_3 3.5.0-1 + xfrmnl_sa_get_aead_params@Base 3.5.0-1 + xfrmnl_sa_get_aead_params@libnl_3 3.5.0-1 + xfrmnl_sa_get_auth_params@Base 3.5.0-1 + xfrmnl_sa_get_auth_params@libnl_3 3.5.0-1 + xfrmnl_sa_get_coaddr@Base 3.5.0-1 + xfrmnl_sa_get_coaddr@libnl_3 3.5.0-1 + xfrmnl_sa_get_comp_params@Base 3.5.0-1 + xfrmnl_sa_get_comp_params@libnl_3 3.5.0-1 + xfrmnl_sa_get_crypto_params@Base 3.5.0-1 + xfrmnl_sa_get_crypto_params@libnl_3 3.5.0-1 + xfrmnl_sa_get_curlifetime@Base 3.5.0-1 + xfrmnl_sa_get_curlifetime@libnl_3 3.5.0-1 + xfrmnl_sa_get_daddr@Base 3.5.0-1 + xfrmnl_sa_get_daddr@libnl_3 3.5.0-1 + xfrmnl_sa_get_encap_tmpl@Base 3.5.0-1 + xfrmnl_sa_get_encap_tmpl@libnl_3 3.5.0-1 + xfrmnl_sa_get_family@Base 3.5.0-1 + xfrmnl_sa_get_family@libnl_3 3.5.0-1 + xfrmnl_sa_get_flags@Base 3.5.0-1 + xfrmnl_sa_get_flags@libnl_3 3.5.0-1 + xfrmnl_sa_get_kernel@Base 3.5.0-1 + xfrmnl_sa_get_kernel@libnl_3 3.5.0-1 + xfrmnl_sa_get_lifetime_cfg@Base 3.5.0-1 + xfrmnl_sa_get_lifetime_cfg@libnl_3 3.5.0-1 + xfrmnl_sa_get_mark@Base 3.5.0-1 + xfrmnl_sa_get_mark@libnl_3 3.5.0-1 + xfrmnl_sa_get_mode@Base 3.5.0-1 + xfrmnl_sa_get_mode@libnl_3 3.5.0-1 + xfrmnl_sa_get_proto@Base 3.5.0-1 + xfrmnl_sa_get_proto@libnl_3 3.5.0-1 + xfrmnl_sa_get_replay_maxage@Base 3.5.0-1 + xfrmnl_sa_get_replay_maxage@libnl_3 3.5.0-1 + xfrmnl_sa_get_replay_maxdiff@Base 3.5.0-1 + xfrmnl_sa_get_replay_maxdiff@libnl_3 3.5.0-1 + xfrmnl_sa_get_replay_state@Base 3.5.0-1 + xfrmnl_sa_get_replay_state@libnl_3 3.5.0-1 + xfrmnl_sa_get_replay_state_esn@Base 3.5.0-1 + xfrmnl_sa_get_replay_state_esn@libnl_3 3.5.0-1 + xfrmnl_sa_get_replay_window@Base 3.5.0-1 + xfrmnl_sa_get_replay_window@libnl_3 3.5.0-1 + xfrmnl_sa_get_reqid@Base 3.5.0-1 + xfrmnl_sa_get_reqid@libnl_3 3.5.0-1 + xfrmnl_sa_get_saddr@Base 3.5.0-1 + xfrmnl_sa_get_saddr@libnl_3 3.5.0-1 + xfrmnl_sa_get_sec_ctx@Base 3.5.0-1 + xfrmnl_sa_get_sec_ctx@libnl_3 3.5.0-1 + xfrmnl_sa_get_sel@Base 3.5.0-1 + xfrmnl_sa_get_sel@libnl_3 3.5.0-1 + xfrmnl_sa_get_seq@Base 3.5.0-1 + xfrmnl_sa_get_seq@libnl_3 3.5.0-1 + xfrmnl_sa_get_spi@Base 3.5.0-1 + xfrmnl_sa_get_spi@libnl_3 3.5.0-1 + xfrmnl_sa_get_stats@Base 3.5.0-1 + xfrmnl_sa_get_stats@libnl_3 3.5.0-1 + xfrmnl_sa_get_tfcpad@Base 3.5.0-1 + xfrmnl_sa_get_tfcpad@libnl_3 3.5.0-1 + xfrmnl_sa_is_expiry_reached@Base 3.5.0-1 + xfrmnl_sa_is_expiry_reached@libnl_3 3.5.0-1 + xfrmnl_sa_is_hardexpiry_reached@Base 3.5.0-1 + xfrmnl_sa_is_hardexpiry_reached@libnl_3 3.5.0-1 + xfrmnl_sa_mode2str@Base 3.5.0-1 + xfrmnl_sa_mode2str@libnl_3 3.5.0-1 + xfrmnl_sa_parse@Base 3.5.0-1 + xfrmnl_sa_parse@libnl_3 3.5.0-1 + xfrmnl_sa_put@Base 3.5.0-1 + xfrmnl_sa_put@libnl_3 3.5.0-1 + xfrmnl_sa_set_aead_params@Base 3.5.0-1 + xfrmnl_sa_set_aead_params@libnl_3 3.5.0-1 + xfrmnl_sa_set_auth_params@Base 3.5.0-1 + xfrmnl_sa_set_auth_params@libnl_3 3.5.0-1 + xfrmnl_sa_set_coaddr@Base 3.5.0-1 + xfrmnl_sa_set_coaddr@libnl_3 3.5.0-1 + xfrmnl_sa_set_comp_params@Base 3.5.0-1 + xfrmnl_sa_set_comp_params@libnl_3 3.5.0-1 + xfrmnl_sa_set_crypto_params@Base 3.5.0-1 + xfrmnl_sa_set_crypto_params@libnl_3 3.5.0-1 + xfrmnl_sa_set_daddr@Base 3.5.0-1 + xfrmnl_sa_set_daddr@libnl_3 3.5.0-1 + xfrmnl_sa_set_encap_tmpl@Base 3.5.0-1 + xfrmnl_sa_set_encap_tmpl@libnl_3 3.5.0-1 + xfrmnl_sa_set_family@Base 3.5.0-1 + xfrmnl_sa_set_family@libnl_3 3.5.0-1 + xfrmnl_sa_set_flags@Base 3.5.0-1 + xfrmnl_sa_set_flags@libnl_3 3.5.0-1 + xfrmnl_sa_set_lifetime_cfg@Base 3.5.0-1 + xfrmnl_sa_set_lifetime_cfg@libnl_3 3.5.0-1 + xfrmnl_sa_set_mark@Base 3.5.0-1 + xfrmnl_sa_set_mark@libnl_3 3.5.0-1 + xfrmnl_sa_set_mode@Base 3.5.0-1 + xfrmnl_sa_set_mode@libnl_3 3.5.0-1 + xfrmnl_sa_set_proto@Base 3.5.0-1 + xfrmnl_sa_set_proto@libnl_3 3.5.0-1 + xfrmnl_sa_set_replay_maxage@Base 3.5.0-1 + xfrmnl_sa_set_replay_maxage@libnl_3 3.5.0-1 + xfrmnl_sa_set_replay_maxdiff@Base 3.5.0-1 + xfrmnl_sa_set_replay_maxdiff@libnl_3 3.5.0-1 + xfrmnl_sa_set_replay_state@Base 3.5.0-1 + xfrmnl_sa_set_replay_state@libnl_3 3.5.0-1 + xfrmnl_sa_set_replay_state_esn@Base 3.5.0-1 + xfrmnl_sa_set_replay_state_esn@libnl_3 3.5.0-1 + xfrmnl_sa_set_replay_window@Base 3.5.0-1 + xfrmnl_sa_set_replay_window@libnl_3 3.5.0-1 + xfrmnl_sa_set_reqid@Base 3.5.0-1 + xfrmnl_sa_set_reqid@libnl_3 3.5.0-1 + xfrmnl_sa_set_saddr@Base 3.5.0-1 + xfrmnl_sa_set_saddr@libnl_3 3.5.0-1 + xfrmnl_sa_set_sec_ctx@Base 3.5.0-1 + xfrmnl_sa_set_sec_ctx@libnl_3 3.5.0-1 + xfrmnl_sa_set_sel@Base 3.5.0-1 + xfrmnl_sa_set_sel@libnl_3 3.5.0-1 + xfrmnl_sa_set_spi@Base 3.5.0-1 + xfrmnl_sa_set_spi@libnl_3 3.5.0-1 + xfrmnl_sa_set_tfcpad@Base 3.5.0-1 + xfrmnl_sa_set_tfcpad@libnl_3 3.5.0-1 + xfrmnl_sa_str2flag@Base 3.5.0-1 + xfrmnl_sa_str2flag@libnl_3 3.5.0-1 + xfrmnl_sa_str2mode@Base 3.5.0-1 + xfrmnl_sa_str2mode@libnl_3 3.5.0-1 + xfrmnl_sa_update@Base 3.5.0-1 + xfrmnl_sa_update@libnl_3 3.5.0-1 + xfrmnl_sel_alloc@Base 3.5.0-1 + xfrmnl_sel_alloc@libnl_3 3.5.0-1 + xfrmnl_sel_clone@Base 3.5.0-1 + xfrmnl_sel_clone@libnl_3 3.5.0-1 + xfrmnl_sel_cmp@Base 3.5.0-1 + xfrmnl_sel_cmp@libnl_3 3.5.0-1 + xfrmnl_sel_dump@Base 3.5.0-1 + xfrmnl_sel_dump@libnl_3 3.5.0-1 + xfrmnl_sel_get@Base 3.5.0-1 + xfrmnl_sel_get@libnl_3 3.5.0-1 + xfrmnl_sel_get_daddr@Base 3.5.0-1 + xfrmnl_sel_get_daddr@libnl_3 3.5.0-1 + xfrmnl_sel_get_dport@Base 3.5.0-1 + xfrmnl_sel_get_dport@libnl_3 3.5.0-1 + xfrmnl_sel_get_dportmask@Base 3.5.0-1 + xfrmnl_sel_get_dportmask@libnl_3 3.5.0-1 + xfrmnl_sel_get_family@Base 3.5.0-1 + xfrmnl_sel_get_family@libnl_3 3.5.0-1 + xfrmnl_sel_get_ifindex@Base 3.5.0-1 + xfrmnl_sel_get_ifindex@libnl_3 3.5.0-1 + xfrmnl_sel_get_prefixlen_d@Base 3.5.0-1 + xfrmnl_sel_get_prefixlen_d@libnl_3 3.5.0-1 + xfrmnl_sel_get_prefixlen_s@Base 3.5.0-1 + xfrmnl_sel_get_prefixlen_s@libnl_3 3.5.0-1 + xfrmnl_sel_get_proto@Base 3.5.0-1 + xfrmnl_sel_get_proto@libnl_3 3.5.0-1 + xfrmnl_sel_get_saddr@Base 3.5.0-1 + xfrmnl_sel_get_saddr@libnl_3 3.5.0-1 + xfrmnl_sel_get_sport@Base 3.5.0-1 + xfrmnl_sel_get_sport@libnl_3 3.5.0-1 + xfrmnl_sel_get_sportmask@Base 3.5.0-1 + xfrmnl_sel_get_sportmask@libnl_3 3.5.0-1 + xfrmnl_sel_get_userid@Base 3.5.0-1 + xfrmnl_sel_get_userid@libnl_3 3.5.0-1 + xfrmnl_sel_put@Base 3.5.0-1 + xfrmnl_sel_put@libnl_3 3.5.0-1 + xfrmnl_sel_set_daddr@Base 3.5.0-1 + xfrmnl_sel_set_daddr@libnl_3 3.5.0-1 + xfrmnl_sel_set_dport@Base 3.5.0-1 + xfrmnl_sel_set_dport@libnl_3 3.5.0-1 + xfrmnl_sel_set_dportmask@Base 3.5.0-1 + xfrmnl_sel_set_dportmask@libnl_3 3.5.0-1 + xfrmnl_sel_set_family@Base 3.5.0-1 + xfrmnl_sel_set_family@libnl_3 3.5.0-1 + xfrmnl_sel_set_ifindex@Base 3.5.0-1 + xfrmnl_sel_set_ifindex@libnl_3 3.5.0-1 + xfrmnl_sel_set_prefixlen_d@Base 3.5.0-1 + xfrmnl_sel_set_prefixlen_d@libnl_3 3.5.0-1 + xfrmnl_sel_set_prefixlen_s@Base 3.5.0-1 + xfrmnl_sel_set_prefixlen_s@libnl_3 3.5.0-1 + xfrmnl_sel_set_proto@Base 3.5.0-1 + xfrmnl_sel_set_proto@libnl_3 3.5.0-1 + xfrmnl_sel_set_saddr@Base 3.5.0-1 + xfrmnl_sel_set_saddr@libnl_3 3.5.0-1 + xfrmnl_sel_set_sport@Base 3.5.0-1 + xfrmnl_sel_set_sport@libnl_3 3.5.0-1 + xfrmnl_sel_set_sportmask@Base 3.5.0-1 + xfrmnl_sel_set_sportmask@libnl_3 3.5.0-1 + xfrmnl_sel_set_userid@Base 3.5.0-1 + xfrmnl_sel_set_userid@libnl_3 3.5.0-1 + xfrmnl_sel_shared@Base 3.5.0-1 + xfrmnl_sel_shared@libnl_3 3.5.0-1 + xfrmnl_sp_action2str@Base 3.5.0-1 + xfrmnl_sp_action2str@libnl_3 3.5.0-1 + xfrmnl_sp_add@Base 3.5.0-1 + xfrmnl_sp_add@libnl_3 3.5.0-1 + xfrmnl_sp_add_usertemplate@Base 3.5.0-1 + xfrmnl_sp_add_usertemplate@libnl_3 3.5.0-1 + xfrmnl_sp_alloc@Base 3.5.0-1 + xfrmnl_sp_alloc@libnl_3 3.5.0-1 + xfrmnl_sp_alloc_cache@Base 3.5.0-1 + xfrmnl_sp_alloc_cache@libnl_3 3.5.0-1 + xfrmnl_sp_build_add_request@Base 3.5.0-1 + xfrmnl_sp_build_add_request@libnl_3 3.5.0-1 + xfrmnl_sp_build_delete_request@Base 3.5.0-1 + xfrmnl_sp_build_delete_request@libnl_3 3.5.0-1 + xfrmnl_sp_build_get_request@Base 3.5.0-1 + xfrmnl_sp_build_get_request@libnl_3 3.5.0-1 + xfrmnl_sp_build_update_request@Base 3.5.0-1 + xfrmnl_sp_build_update_request@libnl_3 3.5.0-1 + xfrmnl_sp_delete@Base 3.5.0-1 + xfrmnl_sp_delete@libnl_3 3.5.0-1 + xfrmnl_sp_dir2str@Base 3.5.0-1 + xfrmnl_sp_dir2str@libnl_3 3.5.0-1 + xfrmnl_sp_flags2str@Base 3.5.0-1 + xfrmnl_sp_flags2str@libnl_3 3.5.0-1 + xfrmnl_sp_foreach_usertemplate@Base 3.5.0-1 + xfrmnl_sp_foreach_usertemplate@libnl_3 3.5.0-1 + xfrmnl_sp_get@Base 3.5.0-1 + xfrmnl_sp_get@libnl_3 3.5.0-1 + xfrmnl_sp_get_action@Base 3.5.0-1 + xfrmnl_sp_get_action@libnl_3 3.5.0-1 + xfrmnl_sp_get_curlifetime@Base 3.5.0-1 + xfrmnl_sp_get_curlifetime@libnl_3 3.5.0-1 + xfrmnl_sp_get_dir@Base 3.5.0-1 + xfrmnl_sp_get_dir@libnl_3 3.5.0-1 + xfrmnl_sp_get_flags@Base 3.5.0-1 + xfrmnl_sp_get_flags@libnl_3 3.5.0-1 + xfrmnl_sp_get_index@Base 3.5.0-1 + xfrmnl_sp_get_index@libnl_3 3.5.0-1 + xfrmnl_sp_get_kernel@Base 3.5.0-1 + xfrmnl_sp_get_kernel@libnl_3 3.5.0-1 + xfrmnl_sp_get_lifetime_cfg@Base 3.5.0-1 + xfrmnl_sp_get_lifetime_cfg@libnl_3 3.5.0-1 + xfrmnl_sp_get_mark@Base 3.5.0-1 + xfrmnl_sp_get_mark@libnl_3 3.5.0-1 + xfrmnl_sp_get_nusertemplates@Base 3.5.0-1 + xfrmnl_sp_get_nusertemplates@libnl_3 3.5.0-1 + xfrmnl_sp_get_priority@Base 3.5.0-1 + xfrmnl_sp_get_priority@libnl_3 3.5.0-1 + xfrmnl_sp_get_sec_ctx@Base 3.5.0-1 + xfrmnl_sp_get_sec_ctx@libnl_3 3.5.0-1 + xfrmnl_sp_get_sel@Base 3.5.0-1 + xfrmnl_sp_get_sel@libnl_3 3.5.0-1 + xfrmnl_sp_get_share@Base 3.5.0-1 + xfrmnl_sp_get_share@libnl_3 3.5.0-1 + xfrmnl_sp_get_userpolicy_type@Base 3.5.0-1 + xfrmnl_sp_get_userpolicy_type@libnl_3 3.5.0-1 + xfrmnl_sp_get_usertemplates@Base 3.5.0-1 + xfrmnl_sp_get_usertemplates@libnl_3 3.5.0-1 + xfrmnl_sp_index2dir@Base 3.5.0-1 + xfrmnl_sp_index2dir@libnl_3 3.5.0-1 + xfrmnl_sp_parse@Base 3.5.0-1 + xfrmnl_sp_parse@libnl_3 3.5.0-1 + xfrmnl_sp_put@Base 3.5.0-1 + xfrmnl_sp_put@libnl_3 3.5.0-1 + xfrmnl_sp_remove_usertemplate@Base 3.5.0-1 + xfrmnl_sp_remove_usertemplate@libnl_3 3.5.0-1 + xfrmnl_sp_set_action@Base 3.5.0-1 + xfrmnl_sp_set_action@libnl_3 3.5.0-1 + xfrmnl_sp_set_dir@Base 3.5.0-1 + xfrmnl_sp_set_dir@libnl_3 3.5.0-1 + xfrmnl_sp_set_flags@Base 3.5.0-1 + xfrmnl_sp_set_flags@libnl_3 3.5.0-1 + xfrmnl_sp_set_index@Base 3.5.0-1 + xfrmnl_sp_set_index@libnl_3 3.5.0-1 + xfrmnl_sp_set_lifetime_cfg@Base 3.5.0-1 + xfrmnl_sp_set_lifetime_cfg@libnl_3 3.5.0-1 + xfrmnl_sp_set_mark@Base 3.5.0-1 + xfrmnl_sp_set_mark@libnl_3 3.5.0-1 + xfrmnl_sp_set_priority@Base 3.5.0-1 + xfrmnl_sp_set_priority@libnl_3 3.5.0-1 + xfrmnl_sp_set_sec_ctx@Base 3.5.0-1 + xfrmnl_sp_set_sec_ctx@libnl_3 3.5.0-1 + xfrmnl_sp_set_sel@Base 3.5.0-1 + xfrmnl_sp_set_sel@libnl_3 3.5.0-1 + xfrmnl_sp_set_share@Base 3.5.0-1 + xfrmnl_sp_set_share@libnl_3 3.5.0-1 + xfrmnl_sp_set_userpolicy_type@Base 3.5.0-1 + xfrmnl_sp_set_userpolicy_type@libnl_3 3.5.0-1 + xfrmnl_sp_share2str@Base 3.5.0-1 + xfrmnl_sp_share2str@libnl_3 3.5.0-1 + xfrmnl_sp_str2action@Base 3.5.0-1 + xfrmnl_sp_str2action@libnl_3 3.5.0-1 + xfrmnl_sp_str2dir@Base 3.5.0-1 + xfrmnl_sp_str2dir@libnl_3 3.5.0-1 + xfrmnl_sp_str2flag@Base 3.5.0-1 + xfrmnl_sp_str2flag@libnl_3 3.5.0-1 + xfrmnl_sp_str2share@Base 3.5.0-1 + xfrmnl_sp_str2share@libnl_3 3.5.0-1 + xfrmnl_sp_str2type@Base 3.5.0-1 + xfrmnl_sp_str2type@libnl_3 3.5.0-1 + xfrmnl_sp_type2str@Base 3.5.0-1 + xfrmnl_sp_type2str@libnl_3 3.5.0-1 + xfrmnl_sp_update@Base 3.5.0-1 + xfrmnl_sp_update@libnl_3 3.5.0-1 + xfrmnl_sp_usertemplate_n@Base 3.5.0-1 + xfrmnl_sp_usertemplate_n@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_alloc@Base 3.5.0-1 + xfrmnl_user_tmpl_alloc@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_clone@Base 3.5.0-1 + xfrmnl_user_tmpl_clone@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_cmp@Base 3.5.0-1 + xfrmnl_user_tmpl_cmp@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_dump@Base 3.5.0-1 + xfrmnl_user_tmpl_dump@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_free@Base 3.5.0-1 + xfrmnl_user_tmpl_free@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_aalgos@Base 3.5.0-1 + xfrmnl_user_tmpl_get_aalgos@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_calgos@Base 3.5.0-1 + xfrmnl_user_tmpl_get_calgos@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_daddr@Base 3.5.0-1 + xfrmnl_user_tmpl_get_daddr@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_ealgos@Base 3.5.0-1 + xfrmnl_user_tmpl_get_ealgos@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_family@Base 3.5.0-1 + xfrmnl_user_tmpl_get_family@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_mode@Base 3.5.0-1 + xfrmnl_user_tmpl_get_mode@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_optional@Base 3.5.0-1 + xfrmnl_user_tmpl_get_optional@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_proto@Base 3.5.0-1 + xfrmnl_user_tmpl_get_proto@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_reqid@Base 3.5.0-1 + xfrmnl_user_tmpl_get_reqid@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_saddr@Base 3.5.0-1 + xfrmnl_user_tmpl_get_saddr@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_share@Base 3.5.0-1 + xfrmnl_user_tmpl_get_share@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_get_spi@Base 3.5.0-1 + xfrmnl_user_tmpl_get_spi@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_mode2str@Base 3.5.0-1 + xfrmnl_user_tmpl_mode2str@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_aalgos@Base 3.5.0-1 + xfrmnl_user_tmpl_set_aalgos@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_calgos@Base 3.5.0-1 + xfrmnl_user_tmpl_set_calgos@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_daddr@Base 3.5.0-1 + xfrmnl_user_tmpl_set_daddr@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_ealgos@Base 3.5.0-1 + xfrmnl_user_tmpl_set_ealgos@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_family@Base 3.5.0-1 + xfrmnl_user_tmpl_set_family@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_mode@Base 3.5.0-1 + xfrmnl_user_tmpl_set_mode@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_optional@Base 3.5.0-1 + xfrmnl_user_tmpl_set_optional@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_proto@Base 3.5.0-1 + xfrmnl_user_tmpl_set_proto@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_reqid@Base 3.5.0-1 + xfrmnl_user_tmpl_set_reqid@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_saddr@Base 3.5.0-1 + xfrmnl_user_tmpl_set_saddr@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_share@Base 3.5.0-1 + xfrmnl_user_tmpl_set_share@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_set_spi@Base 3.5.0-1 + xfrmnl_user_tmpl_set_spi@libnl_3 3.5.0-1 + xfrmnl_user_tmpl_str2mode@Base 3.5.0-1 + xfrmnl_user_tmpl_str2mode@libnl_3 3.5.0-1 diff --git a/src/libnl3/debian/libnl-xfrm-3-dev.install b/src/libnl3/debian/libnl-xfrm-3-dev.install new file mode 100644 index 000000000000..f57e152c5aae --- /dev/null +++ b/src/libnl3/debian/libnl-xfrm-3-dev.install @@ -0,0 +1,3 @@ +debian/tmp/usr/lib/*/pkgconfig/libnl-xfrm-3* +debian/tmp/usr/lib/*/libnl-xfrm-3*.so +debian/tmp/usr/lib/*/libnl-xfrm-3*.a diff --git a/src/libnl3/debian/patches/series b/src/libnl3/debian/patches/series new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/src/libnl3/debian/rules b/src/libnl3/debian/rules new file mode 100755 index 000000000000..bb33dda05a64 --- /dev/null +++ b/src/libnl3/debian/rules @@ -0,0 +1,39 @@ +#!/usr/bin/make -f + +DEB_BUILDDIR = debian/build +DEB_MAKE_FLAVORS = main udeb + +udeb_libnl=libnl-3-200-udeb +udeb_libnl_genl=libnl-genl-3-200-udeb + +TG_BRANCHES := debian/etc-libnl-3,debian/out-of-tree,debian/no-symvers + +-include /usr/share/topgit/tg2quilt.mk + +# to export the patch series use +# debian/rules tg-clean +# debian/rules tg-export + + +include /usr/share/cdbs/1/rules/debhelper.mk +include /usr/share/cdbs/1/rules/autoreconf.mk +include /usr/share/cdbs/1/class/autotools.mk + +# FIXME: not honoured +#CFLAGS_udeb += $(CFLAGS) -Os +CFLAGS += $(if $(findstring udeb,$(cdbs_make_curflavor)),-Os) + +DEB_DH_STRIP_ARGS := --dbg-package=libnl-3-200-dbg +DEB_DH_MAKESHLIBS_ARGS_libnl-3-200 := --add-udeb=$(udeb_libnl) +DEB_DH_MAKESHLIBS_ARGS_libnl-genl-3-200 := --add-udeb=$(udeb_libnl_genl) + +DEB_MAKE_DESTDIRSKEL = $(CURDIR)/debian/tmp +DEB_MAKE_DESTDIRSKEL_udeb = $(CURDIR)/debian/tmp/udeb + +DEB_DH_INSTALL_ARGS_$(udeb) += --sourcedir=debian/tmp/udeb + +DEB_CONFIGURE_EXTRA_FLAGS += --libdir=\$${prefix}/lib/$(DEB_HOST_MULTIARCH) + +clean:: + # from some unknown reason CDBS does not remove the builddir + rm -rf $(DEB_BUILDDIR) diff --git a/src/libnl3/debian/source/format b/src/libnl3/debian/source/format new file mode 100644 index 000000000000..163aaf8d82b6 --- /dev/null +++ b/src/libnl3/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/src/libnl3/debian/watch b/src/libnl3/debian/watch new file mode 100644 index 000000000000..9939913ca0e0 --- /dev/null +++ b/src/libnl3/debian/watch @@ -0,0 +1,2 @@ +version=3 +https://github.com/thom311/libnl/releases/libnl-(.*)\.tar\.gz From cdf469c8dbe21b0695ea8c2b1f2c43c9748ba61b Mon Sep 17 00:00:00 2001 From: Qi Luo Date: Thu, 12 Dec 2019 18:46:35 -0800 Subject: [PATCH 037/178] Change the dpkg default behavior in slave, and docker-base, in order to prevent prompt (#3879) * Change the dpkg default behavior in slave, and docker-base, in order to prevent prompt * Move to right place --- dockers/docker-base-stretch/dpkg_01_drop | 8 ++++++++ dockers/docker-base/dpkg_01_drop | 8 ++++++++ sonic-slave-stretch/Dockerfile.j2 | 8 ++++++++ 3 files changed, 24 insertions(+) diff --git a/dockers/docker-base-stretch/dpkg_01_drop b/dockers/docker-base-stretch/dpkg_01_drop index e75ef3147158..d749943797d9 100644 --- a/dockers/docker-base-stretch/dpkg_01_drop +++ b/dockers/docker-base-stretch/dpkg_01_drop @@ -20,3 +20,11 @@ path-exclude /usr/share/pyshared/twisted/test* path-exclude /usr/lib/python*/dist-packages/twisted/test* path-exclude /usr/share/pyshared/twisted/*/test* path-exclude /usr/lib/python*/dist-packages/twisted/*/test* + +## install the configuration file if it’s currently missing +force-confmiss +## combined with confold: overwrite configuration files that you have not modified +force-confdef +## do not modify the current configuration file, the new version is installed with a .dpkg-dist suffix +force-confold + diff --git a/dockers/docker-base/dpkg_01_drop b/dockers/docker-base/dpkg_01_drop index e75ef3147158..d749943797d9 100644 --- a/dockers/docker-base/dpkg_01_drop +++ b/dockers/docker-base/dpkg_01_drop @@ -20,3 +20,11 @@ path-exclude /usr/share/pyshared/twisted/test* path-exclude /usr/lib/python*/dist-packages/twisted/test* path-exclude /usr/share/pyshared/twisted/*/test* path-exclude /usr/lib/python*/dist-packages/twisted/*/test* + +## install the configuration file if it’s currently missing +force-confmiss +## combined with confold: overwrite configuration files that you have not modified +force-confdef +## do not modify the current configuration file, the new version is installed with a .dpkg-dist suffix +force-confold + diff --git a/sonic-slave-stretch/Dockerfile.j2 b/sonic-slave-stretch/Dockerfile.j2 index d76cccbdc2c8..4d34e8e81a75 100644 --- a/sonic-slave-stretch/Dockerfile.j2 +++ b/sonic-slave-stretch/Dockerfile.j2 @@ -303,6 +303,14 @@ RUN apt-get update && apt-get install -y \ libexplain-dev \ libevent-dev +## Config dpkg +## install the configuration file if it’s currently missing +RUN sudo augtool --autosave "set /files/etc/dpkg/dpkg.cfg/force-confmiss" +## combined with confold: overwrite configuration files that you have not modified +RUN sudo augtool --autosave "set /files/etc/dpkg/dpkg.cfg/force-confdef" +## do not modify the current configuration file, the new version is installed with a .dpkg-dist suffix +RUN sudo augtool --autosave "set /files/etc/dpkg/dpkg.cfg/force-confold" + # For smartmontools 6.6-1 RUN apt-get -t stretch-backports install -y debhelper From 896b53ea5d588812a26cacf1684e6e2d6a3a5daa Mon Sep 17 00:00:00 2001 From: Abhishek Date: Mon, 3 Feb 2020 16:24:45 -0800 Subject: [PATCH 038/178] [Soubmodule Update] for sonic-swss. Following changes are here: * 1158 [restore_neighbors.py] build arp packet with correct hwsrc andpsrc] * 1153 Move away sairedis logrotate from signal handler * 1126 Natsyncd changes in sonic-swss submodule to support NAT feature * 1125 Orchagent changes in sonic-swss submodule to support NAT feature * 1084 [qosorch]: Remove Init Color ACLs * 1059 Natmgrd changes in sonic-swss sub module to support NAT feature --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index 15441fe0fe80..53bd488c960e 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 15441fe0fe80cba16d05c1759de0a392fdc27231 +Subproject commit 53bd488c960ed4a6f1ec68e94373003fd2e7b43a From 3ebcf132e72cc62828c881d21a6f59307f3b169a Mon Sep 17 00:00:00 2001 From: Abhishek Date: Mon, 3 Feb 2020 16:33:16 -0800 Subject: [PATCH 039/178] [Submodule update] sonic-swss-common * 323 [Enhancement] debian/conffiles will give prompt when file existing, need a way to supress prompt --- src/sonic-swss-common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss-common b/src/sonic-swss-common index 8d6844984b6f..49245bb8568b 160000 --- a/src/sonic-swss-common +++ b/src/sonic-swss-common @@ -1 +1 @@ -Subproject commit 8d6844984b6f02d389eb5f8d92e14f3e12e3f19c +Subproject commit 49245bb8568b70c98e3efb0dcbb823efe43fc2f6 From becf49414fbcba05c4c58c460ec392671f553e89 Mon Sep 17 00:00:00 2001 From: Abhishek Date: Mon, 3 Feb 2020 16:45:45 -0800 Subject: [PATCH 040/178] [SubModule Update] sonic-linux-kernel * 100 Added support in the kernel for fullcone 3-tuple unique nat. --- 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 d5bc436a6179..6650d4eb8d8c 160000 --- a/src/sonic-linux-kernel +++ b/src/sonic-linux-kernel @@ -1 +1 @@ -Subproject commit d5bc436a6179ec5ba985f66e96d2fb7864f0002d +Subproject commit 6650d4eb8d8c1ea4007145e5ffe17c3821298da2 From 9f132d9a979105ff16c1d1883fb5b698f9700744 Mon Sep 17 00:00:00 2001 From: Abhishek Date: Mon, 3 Feb 2020 16:50:55 -0800 Subject: [PATCH 041/178] [Submodule Commit] sonic-platofrm-daemons * 50 : Fix missing DOM threshold info from DB --- 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 e97f2ab26c6c..2e8bd64535f3 160000 --- a/src/sonic-platform-daemons +++ b/src/sonic-platform-daemons @@ -1 +1 @@ -Subproject commit e97f2ab26c6cfc8e620cceddf94fe47646afe64c +Subproject commit 2e8bd64535f3991d67ad225701cb5ad92b6d6133 From 96d05a0cb51b03315725aef1c383dd449fa8930b Mon Sep 17 00:00:00 2001 From: Abhishek Date: Mon, 3 Feb 2020 16:55:14 -0800 Subject: [PATCH 042/178] [Submodule update] sonic-swss-common * 323 [Enhancement] debian/conffiles will give prompt when file existing, need a way to supress prompt --- src/sonic-swss-common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss-common b/src/sonic-swss-common index 49245bb8568b..7e4e2161d41a 160000 --- a/src/sonic-swss-common +++ b/src/sonic-swss-common @@ -1 +1 @@ -Subproject commit 49245bb8568b70c98e3efb0dcbb823efe43fc2f6 +Subproject commit 7e4e2161d41a845a8a57cd3c187acf497d3ce329 From 7843d94a2ef84b7b795acbf19785638bcc27dde3 Mon Sep 17 00:00:00 2001 From: Abhishek Date: Mon, 3 Feb 2020 17:13:45 -0800 Subject: [PATCH 043/178] [Submodule update] sonic-swss Revert the PR#1166 portsorch fix wrong orchagent behaviour when LAG member gets disabled. --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index 53bd488c960e..9cc4810d9bf6 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 53bd488c960ed4a6f1ec68e94373003fd2e7b43a +Subproject commit 9cc4810d9bf69deb1e2704fe06cc700f5b350f92 From 48ca0a1a471e20ecba686bd5b0482fe6140ef672 Mon Sep 17 00:00:00 2001 From: Prince Sunny Date: Tue, 4 Feb 2020 01:03:16 -0800 Subject: [PATCH 044/178] [kernel]: Increasing gc threshold values for kernel neighbors (#4100) Increase gc threashold values as below: Previous: net.ipv6.neigh.default.gc_thresh1=128 net.ipv6.neigh.default.gc_thresh2=512 net.ipv6.neigh.default.gc_thresh3=1024 net.ipv4.neigh.default.gc_thresh1=128 net.ipv4.neigh.default.gc_thresh2=512 net.ipv4.neigh.default.gc_thresh3=1024 New net.ipv6.neigh.default.gc_thresh1=1024 net.ipv6.neigh.default.gc_thresh2=2048 net.ipv6.neigh.default.gc_thresh3=4096 net.ipv4.neigh.default.gc_thresh1=1024 net.ipv4.neigh.default.gc_thresh2=2048 net.ipv4.neigh.default.gc_thresh3=4096 --- build_debian.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/build_debian.sh b/build_debian.sh index d5820ef5edd5..d21456b2be45 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -375,6 +375,12 @@ set /files/etc/sysctl.conf/net.ipv4.conf.all.arp_ignore 2 set /files/etc/sysctl.conf/net.ipv4.neigh.default.base_reachable_time_ms 1800000 set /files/etc/sysctl.conf/net.ipv6.neigh.default.base_reachable_time_ms 1800000 +set /files/etc/sysctl.conf/net.ipv4.neigh.default.gc_thresh1 1024 +set /files/etc/sysctl.conf/net.ipv6.neigh.default.gc_thresh1 1024 +set /files/etc/sysctl.conf/net.ipv4.neigh.default.gc_thresh2 2048 +set /files/etc/sysctl.conf/net.ipv6.neigh.default.gc_thresh2 2048 +set /files/etc/sysctl.conf/net.ipv4.neigh.default.gc_thresh3 4096 +set /files/etc/sysctl.conf/net.ipv6.neigh.default.gc_thresh3 4096 set /files/etc/sysctl.conf/net.ipv6.conf.default.forwarding 1 set /files/etc/sysctl.conf/net.ipv6.conf.all.forwarding 1 From d09b1ab78a50a8c1705efd2cecc2b81e4b8fabd2 Mon Sep 17 00:00:00 2001 From: Abhishek Date: Tue, 4 Feb 2020 11:48:37 -0800 Subject: [PATCH 045/178] [Submodule Update] sonic-utilities *792: [neighbor advertiser] remove http endpoint access *789: [fdbshow][nbrshow] Print interface OID in lieu of name if there is no OID->interface name mapping *788 [acl-loader] Use V6 EtherType for IPv6 ACL rule *786 ipaddr module to ipaddress *785 [dropconfig] Move prefix-handling from CLI to orchagent *645 Changes in swss-utilities submodule to support NAT feature --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 4d82ff82e880..2f1b64489ee9 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 4d82ff82e8800f9b3b6213f2d79b7e6752eae069 +Subproject commit 2f1b64489ee9bc8276bc0537c6099cf8e4597e04 From d192e0c9653bb2c15e9297b8cbfcd2c2c0f08d56 Mon Sep 17 00:00:00 2001 From: Abhishek Date: Tue, 4 Feb 2020 12:10:06 -0800 Subject: [PATCH 046/178] [SubModule Update] sonic-swss [aclorch] Enable IN_PORTS ACL qualifier on MIRROR tables (#1176) --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index 9cc4810d9bf6..beff2f0a0b47 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 9cc4810d9bf69deb1e2704fe06cc700f5b350f92 +Subproject commit beff2f0a0b47ea94057ed8436ae6de385af85e11 From c71deb09b26f3e1fbc10e94671b0440fb5f61119 Mon Sep 17 00:00:00 2001 From: Mykola F <37578614+mykolaf@users.noreply.github.com> Date: Fri, 7 Feb 2020 02:27:20 +0200 Subject: [PATCH 047/178] [docker] remove leftover --net=host docker run options (#4119) Fixes #4118 Signed-off-by: Mykola Faryma --- rules/docker-nat.mk | 2 +- rules/docker-sonic-mgmt-framework.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rules/docker-nat.mk b/rules/docker-nat.mk index 765b6f7d3b0f..f41c8f06647c 100644 --- a/rules/docker-nat.mk +++ b/rules/docker-nat.mk @@ -22,7 +22,7 @@ SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_NAT_DBG) SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_NAT_DBG) $(DOCKER_NAT)_CONTAINER_NAME = nat -$(DOCKER_NAT)_RUN_OPT += --net=host --privileged -t +$(DOCKER_NAT)_RUN_OPT += --privileged -t $(DOCKER_NAT)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_NAT)_RUN_OPT += -v /host/warmboot:/var/warmboot diff --git a/rules/docker-sonic-mgmt-framework.mk b/rules/docker-sonic-mgmt-framework.mk index eb99f37875fc..f07b8d023d2d 100644 --- a/rules/docker-sonic-mgmt-framework.mk +++ b/rules/docker-sonic-mgmt-framework.mk @@ -26,7 +26,7 @@ SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_MGMT_FRAMEWORK_DBG) endif $(DOCKER_MGMT_FRAMEWORK)_CONTAINER_NAME = mgmt-framework -$(DOCKER_MGMT_FRAMEWORK)_RUN_OPT += --net=host --privileged -t +$(DOCKER_MGMT_FRAMEWORK)_RUN_OPT += --privileged -t $(DOCKER_MGMT_FRAMEWORK)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_MGMT_FRAMEWORK)_RUN_OPT += -v /etc:/host_etc:ro $(DOCKER_MGMT_FRAMEWORK)_RUN_OPT += --mount type=bind,source="/var/platform/",target="/mnt/platform/" From 8305e8414046a65bb0ba09d8b23d8487d0fc39be Mon Sep 17 00:00:00 2001 From: Tony Titus <49417625+tonytitus@users.noreply.github.com> Date: Tue, 11 Feb 2020 06:09:57 -0800 Subject: [PATCH 048/178] Add Innvoium build support for 201911 (#4112) --- platform/innovium/invm-sai.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/innovium/invm-sai.mk b/platform/innovium/invm-sai.mk index 8c236a8b68d2..2d89ef71e3b4 100755 --- a/platform/innovium/invm-sai.mk +++ b/platform/innovium/invm-sai.mk @@ -1,6 +1,6 @@ # INVM SAI -INVM_SAI_ONLINE = https://github.com/Innovium/SONiC/raw/master/debian/master +INVM_SAI_ONLINE = https://github.com/Innovium/SONiC/raw/master/debian/201911 INVM_LIBSAI = isai.deb INVM_HSAI = saihdr.deb From 74ac9b02dcff46f0bb89f0e7a548bfe42e108faa Mon Sep 17 00:00:00 2001 From: kannankvs Date: Fri, 17 Jan 2020 09:06:49 +0530 Subject: [PATCH 049/178] =?UTF-8?q?modified=20down=20rules=20to=20pre-down?= =?UTF-8?q?=20rules=20to=20ensure=20that=20default=20route=20is=E2=80=A6?= =?UTF-8?q?=20(#3853)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * modified down rules to pre-down rules to ensure that default route is deleted just before interface is made down --- files/image_config/interfaces/interfaces.j2 | 24 +++++++++---------- .../tests/sample_output/interfaces | 12 +++++----- .../tests/sample_output/mvrf_interfaces | 22 ++++++++--------- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/files/image_config/interfaces/interfaces.j2 b/files/image_config/interfaces/interfaces.j2 index 91be4437fc06..0b64fdfbbdb2 100644 --- a/files/image_config/interfaces/interfaces.j2 +++ b/files/image_config/interfaces/interfaces.j2 @@ -5,23 +5,23 @@ # file: /etc/network/interfaces # {% endblock banner %} +{% block mgmt_vrf %} {% if (MGMT_VRF_CONFIG) and (MGMT_VRF_CONFIG['vrf_global']['mgmtVrfEnabled'] == "true") %} auto mgmt iface mgmt vrf-table 5000 -{% endif %} -{% block loopback %} -# The loopback network interface -auto lo -iface lo inet loopback -{% if (MGMT_VRF_CONFIG) and (MGMT_VRF_CONFIG['vrf_global']['mgmtVrfEnabled'] == "true") %} # The loopback network interface for mgmt VRF that is required for applications like NTP up ip link add lo-m type dummy + up ip link set dev lo-m master mgmt up ip addr add 127.0.0.1/8 dev lo-m up ip link set lo-m up - up ip link set dev lo-m master mgmt - down ip link delete dev lo-m + down ip link delete dev lo-m {% endif %} +{% endblock mgmt_vrf %} +{% block loopback %} +# The loopback network interface +auto lo +iface lo inet loopback {% endblock loopback %} {% block mgmt_interface %} @@ -50,14 +50,14 @@ iface eth0 {{ 'inet' if prefix | ipv4 else 'inet6' }} static up ip rule add to {{ route }} table {{ vrf_table }} {% endfor %} # management port down rules - down ip {{ '-4' if prefix | ipv4 else '-6' }} route delete default via {{ MGMT_INTERFACE[(name, prefix)]['gwaddr'] }} dev eth0 table {{ vrf_table }} - down ip {{ '-4' if prefix | ipv4 else '-6' }} route delete {{ prefix | network }}/{{ prefix | prefixlen }} dev eth0 table {{ vrf_table }} - down ip {{ '-4' if prefix | ipv4 else '-6' }} rule delete from {{ prefix | ip }}/{{ '32' if prefix | ipv4 else '128' }} table {{ vrf_table }} + pre-down ip {{ '-4' if prefix | ipv4 else '-6' }} route delete default via {{ MGMT_INTERFACE[(name, prefix)]['gwaddr'] }} dev eth0 table {{ vrf_table }} + pre-down ip {{ '-4' if prefix | ipv4 else '-6' }} route delete {{ prefix | network }}/{{ prefix | prefixlen }} dev eth0 table {{ vrf_table }} + pre-down ip {{ '-4' if prefix | ipv4 else '-6' }} rule delete from {{ prefix | ip }}/{{ '32' if prefix | ipv4 else '128' }} table {{ vrf_table }} {% if (MGMT_VRF_CONFIG) and (MGMT_VRF_CONFIG['vrf_global']['mgmtVrfEnabled'] == "true") %} down cgdelete -g l3mdev:mgmt {% endif %} {% for route in MGMT_INTERFACE[(name, prefix)]['forced_mgmt_routes'] %} - down ip rule delete to {{ route }} table {{ vrf_table }} + pre-down ip rule delete to {{ route }} table {{ vrf_table }} {% endfor %} {# TODO: COPP policy type rules #} {% endfor %} diff --git a/src/sonic-config-engine/tests/sample_output/interfaces b/src/sonic-config-engine/tests/sample_output/interfaces index d3921bcbab4d..913fc8531443 100644 --- a/src/sonic-config-engine/tests/sample_output/interfaces +++ b/src/sonic-config-engine/tests/sample_output/interfaces @@ -18,9 +18,9 @@ iface eth0 inet static up ip -4 route add 10.0.0.0/24 dev eth0 table default up ip -4 rule add from 10.0.0.100/32 table default # management port down rules - down ip -4 route delete default via 10.0.0.1 dev eth0 table default - down ip -4 route delete 10.0.0.0/24 dev eth0 table default - down ip -4 rule delete from 10.0.0.100/32 table default + 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 from 10.0.0.100/32 table default iface eth0 inet6 static address 2603:10e2:0:2902::8 netmask 64 @@ -30,9 +30,9 @@ iface eth0 inet6 static up ip -6 route add 2603:10e2:0:2902::/64 dev eth0 table default up ip -6 rule add from 2603:10e2:0:2902::8/128 table default # management port down rules - down ip -6 route delete default via 2603:10e2:0:2902::1 dev eth0 table default - down ip -6 route delete 2603:10e2:0:2902::/64 dev eth0 table default - down ip -6 rule delete from 2603:10e2:0:2902::8/128 table default + 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 from 2603:10e2:0:2902::8/128 table default # source /etc/network/interfaces.d/* # diff --git a/src/sonic-config-engine/tests/sample_output/mvrf_interfaces b/src/sonic-config-engine/tests/sample_output/mvrf_interfaces index afd0615b81e9..7bd664d4a9db 100644 --- a/src/sonic-config-engine/tests/sample_output/mvrf_interfaces +++ b/src/sonic-config-engine/tests/sample_output/mvrf_interfaces @@ -6,15 +6,15 @@ auto mgmt iface mgmt vrf-table 5000 -# The loopback network interface -auto lo -iface lo inet loopback # The loopback network interface for mgmt VRF that is required for applications like NTP up ip link add lo-m type dummy + up ip link set dev lo-m master mgmt up ip addr add 127.0.0.1/8 dev lo-m up ip link set lo-m up - up ip link set dev lo-m master mgmt - down ip link delete dev lo-m + down ip link delete dev lo-m +# The loopback network interface +auto lo +iface lo inet loopback # The management network interface auto eth0 @@ -30,9 +30,9 @@ iface eth0 inet static up cgcreate -g l3mdev:mgmt up cgset -r l3mdev.master-device=mgmt mgmt # management port down rules - down ip -4 route delete default via 10.0.0.1 dev eth0 table 5000 - down ip -4 route delete 10.0.0.0/24 dev eth0 table 5000 - down ip -4 rule delete from 10.0.0.100/32 table 5000 + 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 from 10.0.0.100/32 table 5000 down cgdelete -g l3mdev:mgmt iface eth0 inet6 static address 2603:10e2:0:2902::8 @@ -46,9 +46,9 @@ iface eth0 inet6 static up cgcreate -g l3mdev:mgmt up cgset -r l3mdev.master-device=mgmt mgmt # management port down rules - down ip -6 route delete default via 2603:10e2:0:2902::1 dev eth0 table 5000 - down ip -6 route delete 2603:10e2:0:2902::/64 dev eth0 table 5000 - down ip -6 rule delete from 2603:10e2:0:2902::8/128 table 5000 + pre-down ip -6 route delete default via 2603:10e2:0:2902::1 dev eth0 table 5000 + pre-down ip -6 route delete 2603:10e2:0:2902::/64 dev eth0 table 5000 + pre-down ip -6 rule delete from 2603:10e2:0:2902::8/128 table 5000 down cgdelete -g l3mdev:mgmt # source /etc/network/interfaces.d/* From 68f664beb6e5861b136e5f19048c382b396b4f90 Mon Sep 17 00:00:00 2001 From: Wirut Getbamrung Date: Mon, 16 Dec 2019 22:30:35 +0700 Subject: [PATCH 050/178] [platform/cel]: Remove afulnx_64 (#3900) remove afulnx_64 install script --- .../sonic_platform/component.py | 4 ++-- .../sonic_platform/component.py | 4 ++-- .../debian/platform-modules-dx010.install | 1 - .../debian/platform-modules-haliburton.install | 1 - .../sonic-platform-modules-cel/tools/afulnx_64 | Bin 828912 -> 0 bytes 5 files changed, 4 insertions(+), 6 deletions(-) delete mode 100755 platform/broadcom/sonic-platform-modules-cel/tools/afulnx_64 diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/component.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/component.py index ad6810b14c38..fe34bc45c670 100644 --- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/component.py +++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/component.py @@ -140,7 +140,7 @@ def install_firmware(self, image_path): new_image_path = os.path.join("/tmp", (root.lower() + ext)) shutil.copy(image_path, new_image_path) install_command = "ispvm %s" % new_image_path - elif self.name == "BIOS": - install_command = "afulnx_64 %s /p /b /n /x /r" % image_path + # elif self.name == "BIOS": + # install_command = "afulnx_64 %s /p /b /n /x /r" % image_path return self.__run_command(install_command) diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/component.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/component.py index 67c7a9c46341..d94a93474452 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/component.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/component.py @@ -141,7 +141,7 @@ def install_firmware(self, image_path): new_image_path = os.path.join("/tmp", (root.lower() + ext)) shutil.copy(image_path, new_image_path) install_command = "ispvm %s" % new_image_path - elif self.name == "BIOS": - install_command = "afulnx_64 %s /p /b /n /x /r" % image_path + # elif self.name == "BIOS": + # install_command = "afulnx_64 %s /p /b /n /x /r" % image_path return self.__run_command(install_command) diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install index 2ab53302a9bf..8570fa1eae84 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.install @@ -3,4 +3,3 @@ dx010/cfg/dx010-modules.conf etc/modules-load.d dx010/systemd/platform-modules-dx010.service lib/systemd/system dx010/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-cel_seastone-r0 services/platform_api/platform_api_mgnt.sh usr/local/bin -tools/afulnx_64 usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install index d50306304cd5..df78b7a34ea4 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.install @@ -5,4 +5,3 @@ services/fancontrol/fancontrol.service lib/systemd/system services/fancontrol/fancontrol usr/local/bin haliburton/modules/sonic_platform-1.0-py2-none-any.whl usr/share/sonic/device/x86_64-cel_e1031-r0 services/platform_api/platform_api_mgnt.sh usr/local/bin -tools/afulnx_64 usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-cel/tools/afulnx_64 b/platform/broadcom/sonic-platform-modules-cel/tools/afulnx_64 deleted file mode 100755 index c32823393c0805484f1a5ef37375c0ca3384a72b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 828912 zcmdSC3w%`7^*?$785uD+BZ5W@8Zl}RgrKNFQ3nWmP}HbcQ$ecaG5f6S0b|ApVZF@~quJ z2ZTq2SS0Pc!%^*i2L-jP!T8Q*dXU2y6j2H1J5Nz4L48~c`OWhDPsB;8?^Vl{o$j|~ zQP@Ke9QUX<`h)iuh?!rn#X+2PQGSG-u-s#<$k;MW8L^KPDpa>|^ z5q?=E^4I?sUw~Koesn(5;puybM0omXY2Odd5YlqL-F#;upVUvm|M9PD=fs+Y7aucu zV$J*`Y8Ec8TXDpS;$x0DX7Yq(OC}sC_J^T~zB}cNb491?kKv$L_6YoATM~c0ux$0? z4{Q(bad6Xq*G0eTJ$lqpO~h8=pXdLBEGs`NJea&2@b5^K!P|S99g8 z%N_wMGam9y=Yu{l1HS_Nf&6o02K&#?AphG8@;}R9|HB#h&t~AS z$iQ#T;DudshZ~4$Gjw zC|YmW@|8l6G@&J6O0 zWhnQm4E!rI@ONh5S7j(Sm_h!l4D#I>_^)K(f0n@yWf{u-O$Pqw8QSZ~4DxSgu;=v* z@=G$r+l3kQ{3L^(>I`~vGw{b}@J~&Ka_44{|007u8#2gWlEI%X8T1^R!JfA==t*TL zcY6l?zt6xwB!iy%4CUShem?%0pPyy0e{2T+sTu6~E`vR1pumCV&37~C&&{C!v<&*+ z%)nomLC?M!;%!z2{)rjvoSLEBy)*EW8SGhA zM(|hrV8692I=^zyOBPpFc|>Ies2U5FE>cD!Rq2|$ zqV|$`7gsE+LMc_&@gt-hWecoj(WRBOS6b9Kf8kPVS?$t=i=)+6bjk9X zCCjUpTGdNxs}@_!E0-;%7^D|hE~>Svqf6@+(@b)fRxVgd3DDO3nt2Q12UehV!ThCG zWzCXhRa9IZt*WU}`JrbK9J&Nq;0?I3^0IlA3oe^iU9qr6=~-6ALTc-xl?y7CdUae> z7p+<`5AM0lT2@t4RT;GwE?X}4(tP^OsrI60kD{^x@2iZEdy&l zs$wl%QW-_NUy0ta$XZmlm@Z|kI5CG43~@Ju$t}0Ws$K{OF0tyC)l^l%oaIV$_41{N zEvuTb3fYQi^)h;(s&3(Yt0KB&A{U}g+xv=Y$6cVMlPp{8 zFi`u-C2-9pi|gjiuexI1qKeC^@XeYq9#^m~_^x&nD;8b0c*%Tr=1VG3B)jn>>y+8E zrq3uVn|IWN$riq+O`kPy(uAWFd)|=~$QBVv`+SY-;YUt5nxosG|L`AWvLVBN-~Zo0 zx&r?p&-ZKGO>z%5bYNokIO*6Bk3W!Jvj)LkqzB_fEDKyrVHVFzitsNw_7+Sf+13px zmb@1qx(vsdgRNU=20mFh)%+{IiSZNNZ{hA1PFa8H$S)Imi1mAi9GN`I7uq zE)(A?9Q{L(ra#wQ*hd`!9Cr&;4WRT6BC#%I~?XRXH9&qdd1eA?uG)@yus z&L`HQ@!?SK)1mQ)dR)ues`1qct^&I?evT%;P2;0My-$zE-_zq-Rzl;4G=8tfcVmcf zpT^%?leZdFJkSR`!*xGFjX%<5;ybMI_tE&d8h>AnpRe(AHGZMS-%sNgX?(1*yic*l z-{0d}Rz%}FNB4r-8h^AVU#jsB(D-E)%do?KSAS{YWx#5ewoHU zN#mDm{D{V1pz)_^{927aUE{CN_%k$qy~Z!m_^UPkOpV{H@lV$HYc&2T8h@?Ew>ADc zjXz7{uh;meYWx@z2uu zy&C^)jo+v7&(ZkSDnI_`X#AkYKUd?2HU1AYey+wpPvhrn{4$MSsPTWO@ryJ*uK~HA zVvRr7W#T)c@h{Z)w#L6mVLmjbE?v zt2F*GF=8h?$(U!d{VYW#&7f1Sp^RO7GL_?Kz?7LBhWMu8m~e~~7?RpT$# z_}vfDD>Z(R#=lDA7i;_`Jd!g4$Dx7&l3-LN^hssHHKdE>4A zLmtQ9(18)8NK3>gd;0M?1@(#g}#L}w-Cu@ zp>HD1twXY2=<7*yxty#O`YO^e)Jm2My_7U;wvwenUrL%=gJeYLi%D}!kSr4Ve9}3j z^MyW}G`9fBu+XQH=F&fD2|b-Om;A}z@4z_ZIMQ6|CwqiGk~Ft=$!?(!C(R?sWQWjW zNOKF2Trcz}(p>r{*9twHG?)CzW}%0Y=2AadFZ3YNT;eBdh5q^?&|KOl%Z2`oG?(oCJ&H7!zR9&h4=2qf zZ?akFp`^LgP1XxNh%}eD$y%Ymz7RB*w#jm#KO@a0ZL(D8k4SSVn~Vs(oivxQ$s(a& zC(Wg6GGFKyNS{DDEc8>Pxl~PBLT@C^C2F$w8)<*i5z;+EKTLWW>29I#Cq12XhtT(u zohm+=#FWD^gP|{rLCF_MAM4C&yWUbI& z&jrn;U9w#0&q#Agmn;?fBhp;TB_l#_Cw&3wBB5U=%_UtjU+5P|Ur0JE^i!m{giBgN zZzRp7Te9~nX@An?q*(~%; zq`3r3)(d?-X)e8zwL)J-niEj6TPxl~D7LT@C^B}%gQOKE@7^`v`*ewg%1 z(%qo(EuTpr&x$>NksaG^H@w$dI%if_M}3QJ*d=80W$cEIEIStX1BCiVJRw5yz^|BP%C@E3w*=xyX0f;np4?PjT|FUmV58V? zH=NKj2j#Hb=6gjz72xf$))E3vM` z`afG%Ebt2$8xP!uzc9s-y&1A9R{*J4V7bU#o+iWTvAv$f9{`hLfpbLW^fZ|gDKk%u zeU!4TwAYTkjnZo|eK&T5ZtcLIMp$AcKER)NU=O7s)W(Xp^H1U(to)QYAF-wleOZz% zs>?hE8M+HTvQnqQJ9(Zno?xap{1FK{1x9I+FYp^B02wLNhIPEfrh)3>a|`lR*^4PP zWmD)DSX_5^;wY4)fQztjhzHK8Mf*2w&c9$2BT6BEMi%9xFOW(M#|liMkc}LMwK=Sw z`<;9g1e=wHi(~V46T|IzBnNR4x=md5V^iwiuJvU(X}RBa_)bjpzZeTVw1jQ_d;DG1 zQFmFI^m-)?Cmk_0tM1@5>{bsO4{S(__&6Z(3s)QpKjqL*Im+rEP}=cRXw^7$?^Jek zDhoYwbNGTy16Tbqvr-2+#>XQg*hSLq$^JfjqKBl}zAfAJ;RrFWzdIIKx0r6Y7k{Dp z#58eUl0h86QdAH^ai^Ks8Wog{sK{AnZ5X8A9 zl5TIK-v`<6F#;9CI@WxQ9UncO>39ytxT8esWZ)9jQo!4T z-KykyRXH$C;&ESsx0qP{-G0c6iZ}(_kiXZCkGy5kc&okpQQMNn?|&gf(Urd93`I}# zC8UqX~9UOf9gYqag8d4JEP*WB||wM90vsz;7VH z`l?R)s{&~Q)p3j22D!0l!3aAx2aSOW=0lP`#=woCWp+EaWr-^>joC4PaOik@josNZ z*dC15vEyMHmv6_^_m&9uyzx0;fSZePmxIgOYH%5!#mvW-6pRSn#WCeRL_#q~k6acT zl;RHdsv6-?`!$#hPbm5DQ&@oZ3TCNlJVyx1f}x*NS(oDSR!ykQ6}6mJP_-bOnUhsF zdnNqA$+d2}lI41_<*WJ3)GeyJOPFX1x|o~TSl;r8YP+% zF+{%vw^T`D8x=-?cO~wmu{4YGG~B|tcd@5@4E#Rw@h4IQSY5#GddoN~L+ezZr7Xe!NB2{!H= zS0q*{joW8;MRI-Ft_Zht*8fww{&)T1woz&r>n|;saJ(YK6CfITvk-Rgc&%EfS{0*N zJKd5v?`ItrR!xe<&~Cl=xnICc(ujVmIAD~Cl8WL*eN+*B&<4U0;P zU`C><<-~Hg8cuwm zQmQ^dyJ4eSCwzA$M*kC@5zQ>Ksnj97TKvCZQ|#mKx5)428kL|XbZY}r(bbn81 z>{XwJ#xDIwXzZoWhsIvq85(>3pF(5Lz9%&H)SrgNPG6}PTT)QWHF3BLH(sDTNk+2S zDJ4y%oCGA?2-;0^3L;)Wg&wh{meuXXQKUGFki=QBGk|}C7K6o;F;B0l!eoO+Ec{o0 zKiY7zy>c__r`9>}f~?7aj|c`WWXZvFetI>QA4r1xM@%MmY@<+H+E4Q)s~5?E%bW#M zzN(m-1kb~WC%b~w5s=Em3(%-*&FlvF7EQKq#c`ddN zo7kP)|EiWLm;|+z$p4_cid4q(e!FA9@>sP*tQVosv$~|dfQC1{+`UZoC_QR;4m~1G*ej~ubW~AcFBQJ& zD17O^Q8hztcS?=`?AXZ`+R0T!0xGdn z;d;OB12Q?1g;fm5>X2)juEe7lgkl@Lg`rv#CQ_;+y0aKO)0;~7fEZkNpff{?2OLj( zr9Q`SK*_9JsIA+nuf){zV>@G8X^;$w=;_gdaI70mm(vJ?sc2ypoeXR zT|vzTDe)!@M;cGcyn;hinq4u+Qs1uS;J~h6R-I#4g=g1!NFjGlY@=q~!_YaETUBKp z<6Ht2yZLXppj1si68XGVw*dK}z;%k+Zoa|I{5M~2qu+}d2>uckgJ!m4c}YQGY9eM# z(6iNo3jW|mA#oT?aUv=@gwlnnacuuW##}aIu8?_hk$D7$-@WW9-KyX}wJ<(Wfg+hr zIiR7zxq{?!9GQcduke*4Ckn5jJwgwGN(Cg!kuP`Cxg1fXVS@UZMv5_?r)F$7-f2>h z%Lohu*#%uJnj>W%&Rb#~_Ltl2Ea0h&Spg1lQzu?~rk9>_-3(@mt0`FGwxc0Y6njDx zB(e})L!mBlwAlDW(}=+okA<-UWufS@d08o^1Mh|UHLDuO!ImC<}}Dlhh==E;x%u{Y6UV=r>N?m?9XvxOhAVq4(+9j$+V=9y<= zTff}i`O)B5cW2L_tnRFi*i&OS#=4ubcUwIexp!b-d`aX$y!7REh$RMtw?iAkZWDuX z3;|pFXlw5#yDRY0yz$m=uykj-8|j-dx8k^o>u;xRpb-t!m3a0&ncS2gTd{xePem%< zSG`2!eyim27&p=it!yqQ;HE$l3iDLxH|!|(f)>Lxx)kCQ`9?5buAVQ8`DC_rwYG7m zM!QZqp)n8H$@M@pQS?@`UXWOr%sav zL@PF^R@)p**)(q9huG=Q(tz_Epp*bsbr|4UvE#Se&Ub)g3GA!oa8(@uz*}*^)3RlZ zp#q%Eis`XpRNwZ7V6|FqyU5Wy&ykci$#wmY@m61voey6E%9YtZB5flBx!Ux?Q@J!O z-zoehR28v473N#1C=8g&vATn!_pjAa4DEHL3&Cpah@O%r_ah}2SL^jKR`hBJ*+U`+ z1x}5H(=wbY8FEuRU7E_%rKzgGG30xvOT2o^vm;s4!2m=FoNULop>mN6Hcgu&gO3_9 zrGkjQoc0mOkk~*MVC59shCsx!OoA@TiK#1b87iFGKlbvh*k(KSPU7nA{r$6JJ$B{G z1V1`VdsZcT%18Xt1 z4@ioN(azj0%2DW{D70k~w56svWqSJHAej%}b+QPcwwI#n1=P}=@ocq*_s?RAs0|&` z3H^0ETETSVw$wASn|LR2Mi2WI=M)vOwUmR&&cRHp;(o_=l?6UVV4O1r-Z+1}RXQVL zDR?i2aRUwpf#zznF3xSndFM6@7iHXuqzTq z3$c!}PcJscAa_+0W=*5H z1gDE0mX~0daA21CIDreCxvBXIK=uFAAuDEtUMu>2hpSI=*66i#^#Q8K($ufh|K5q) z1FvUl9CtiYE#ox>?}Ac23+C?d*8Rug0O-b!p%#K-r`@?d+s^8aTZpC|bqI*SqI878 zl-ghI4gx;}HU%36wLfTSS-ZMMofRiMId1&Rl%r}88VBYiwjDM<(;{qu9k zhCD>oB@nsh0mI_io7q)(!ZluzausJh&r`+^R))L;uN7k=UAcn~hftleX>Ng9X0-AS z6fAD+*z^CgA3#~>oamH=^o^&gG(Gu%lg>x_BuAzY=|7*PWH2)ae(uN=BYlpOjv&47 zX-dXM`uN!@U5a$b;g=yj&XF%i`Y37U`25{tBdLNV>70p7zHB;~jFfB5yl^ zr8E{aEAo+9id>_}4W}z|ts>VryXWg+|99hjUrWCH5RN@WTB&Zog&Y2gx4$b zCP!6^B7f$P9g4imA-5{>K8Ng97|vQLpuJHq&l zA)WJ#Lk1Q3mP3XW>9wyS-*M1X zrHVY+DX2`5s=qfDlq+(rgDz0y}al6Jt*D{}f7ifjSd)mX3VE-)3RN^bt~99=;{6(wf-JD9^#^L?U59lB^iUqxB)ai+fjWxgAdI^Nyp3WE z`%#ST`814)LP^8}KbBq&06ewzp9MpvDm(LO=VX_z*_^MowY+4G?JKwPC<3?n^uO#K zJ2J-AR5g_|1Wra}s(OH98<(v%&)2ZsDYs+q3a^#tb^7#>_c^^OGt}jhR5R3lj-hZ= z;K|1+f=LbOCW$T{W5fdoovHYoHNJRErHhch(vjh;ai25VM^NFpG%CfJZmycz+?mcH zWu}|Udd%J3pXtiw<{#P1$gKlmYN1ba-9)}5;(@b{RW{J(qn&iF>wJ8xnU?pa$kgft z##oo0y*VtK7|=mk*7iT|`kBY7g<1Hc=HWrgxP>E9d7W!1%@uWZ+%Q5jVtXB%;pgEf7LU5zIbwvl`_MrcH7_Hhhs65vK zqZc^$DY)w>XmSoMx3r%;t7J~%pEbAz4(Hxb%*%Q=lv^rL<(`!N(Ns8K;vU)&Z-+P; zI3|~PXi(d^LT7yhm#EW40ikaj&-8F07j9edxH@l4c_*<=c8Pz8=p1hp6KzmC>q1;^ z2w91#-1WmmId}_Ob)#{k%x262?X}P-R`kEXiwvRUF!WP+F^`3#K6!|LEJ5SV9e35h zXlRH>CQsQ|cZH9IHZ*T`!O(_CaW&xc(%>x`d>mo)H`>x7bN zz)pOEL#uSDDM|{r*$s6&tbb3%NNUb0!=Lvq<}HO5=Ow2Z)rKS<*nx^-=*0or$YFrv zfj7XAxj}r8xEqu0%ih z0ShsJ{B5{}n?aMCm|DdYE;e##RU7GQXj3#zZt5f6vPIqf}UJ^go_jqjz5o`sVz%zMm;365X=IDFg_-^mZq6iU&^ zzaiHlN)a!cMu)a=>`iWlL@Vy1wAus$Ar&WWDROQF+-c~a@R!&~bK zN&g-+yhhKrms7_I=tv!6$8Rm57G|xNZyZyJ_U*jn$D48M*3l*<)RmY7OSBej!!knE zNrsHXMwlE6G-3@D4_u4Corwbx){QpAH2a@H_31gy{!rsH(3Bdh*I^YMj5^@fJE_C_ zpq)AlZ25bl*SGv(-SXvrGec*E(c+J?!O~j1f1b2BT@XFWtmo@+Lo9IDOxE*u{QVNw z-B4468ERoAFGP1~ucw>$qDf6obb%|4bJtnkts3ynpxu66?QV+zP z@ma-mFSHu9NwM|QYBNdIM*6~OcKnFfW{k&u;&5o3{dx~+@=b}Ogki^C$HZi{x#hg9 zg79Q0Z9f9s#8en7Wv7;#j_HISV_0&~G1uU)atlkmgeAU!f~3Sdq^UL~I)$N1jF=_9 z1anl0Pd(|D=**BSH?Kpru|ni&c|0&2MWI#4#REa4P@{!g-M;e^Dv|Mk@ubxK2eMW(`Jrp2OuZmanA?opgIOy>cj&YNOBZP?|f8Ibrd; zlTZ|bfg1^bNMQFozsv35S5nn!(tfHic2O4UX7u{$zfnbW4>cx@bz!woxE@-lcRFNv zis#fv0uZqx`T$q5-CYLY>TJ6~*`Wr9k#JCI%q}v&)MY-UZdmKO*44yvR}sSiK#YT{$b?qCu9*;OTm#C@ zl%q^_P1bM;zqP+`$tS& z!?uNw-C%F~3f%UcgpMQx7t7t&aIuJl8oz_l?We-Ci3&Oq0!3^CRFB`SIqkSTI3Isd zG1b(E(=@=MC)U}DrIRHqqxN!$B_88whqxBl(c&1~;p7y>Pf&5UuK0NxIB?DzzQ4>< zSSG4O#TKrmdc}4ncCu|XYxno89o_+Jhl#a*WsdUTBEtXVV4~&b&ni`27Z85VfG2zK zTEgoM*w4L<@J|ic&mHarywrgC6HQgNP52xG<}XkcyqfT213uh?TL`ni>J^*n!3n}L z{%G|+&Vvg#0)EwS>VY1-fN)Djcs1cWGQ#T!UzHKwO85c;&iBer5T2S5#$9q&Vssje z``H;-yY!by6dkk)(60SuWv<&_CT&y##ZG_Wx9Tr8@_YT|YwFQ_Y4n%4gtp&bM4MW5 zH*Z!sMe(lv*<~s zrMLP$$M0CbB>Wcx_H#c<__mBN?#i?hR~RsS?gaNIgwHcz{MO2WgPQ>t8?ayYfrR%n z;QhSZ#}WRT!=P4gU-=xuZy2y&@5=~3Zot0fHxmA3MtCjZYYmvUlBiDoDB*bq?3ev4 z;fMiG^m6wSKFEOm-1$!c9%R6>hvBNCeJbI1jga!)QbKsM0UzX*T~7Eu1J3v0)r4;_ zVBc%MCwxgpcq3suBm4&8u^Hjd2@f@3KOBZ_0h}_ruOCc@5q`#iv8;Dm%qIK?1D@l- zYYG3@fPJs^5nf`zI7)Jq=XU`vHDKBNN{clSo@BuM4X_HPHH3#7u+iTC;^?MzgCBai z!&{O2B?CUpgKG)@)quH{bjl`ty8-*{{R_g&4cL#hzYs1nV86wlCOpM}4X2JWVEk^? zF)hK|-*l$e+i>ce2E4DAd-#*c{Wk+PoO-tb`xQH!xvw)|9EUijO(R@xz(pQx6P{+k z*pWE7>j{rB;29p=L3pqMkMrQ*Q-I&=NO#Mz9$ZZL2?O?51hs^JYrsJ-cQfG|4cMsI z0s|i7zyA1$G$q5LNX zY{Xiv0s8~?Va$D&0sG2l5I)j?{a$hb;k^ym?zVt925dCRaRzKO$^HiHd+j4C-}$%ndK*phmI3=t9rO%x zw;Awg&+4cMqyo&o!1OU1s$ z53Tf7k3ZxdN#$=Fuu-vg1HRC6ODS`&HDJTEl?H5>cCi5;;3;2Ex(wKFk|EDQ`8oqOOp6(Cp;xg&=DyT`4bx6DV8gWW2JCySjLL@@ zuwmLiH>B6wKSf!=+|L=XVcL2FHcb1e0sEuFIx1gkz=mn(7_eWlZswkBz=mlf4cIX4 z-;bo%+i%cMsQgs}HcV?V;3K^T4R<5=9fWz5nPnc8Ph77MURp~(;2jAB$28t)y&PYw zLuom6b=0-lD8M^;sec$}s)u@~rcI?o++x$^${^<j)14 zoH|g?Ki3loJ`aHpP>>EAQ&AUS)MpOt;D^pCchX4K_{my78Fhu5N^lEAJ+ie)UR0~_ zk0?#G@IgG)S1k;&wkjCoHSay}P3mB2I0PVmOpoT>Md)feP}o0Gc@u{}1P)rO32LDEuX5R{4ga8 zxsZuc47lycM7!uY+9e*W!$VGdLw<&ec zVk_8#m2_*Ep1;=d&D+R=;2hkXx&U{YQ7+4oKVBKC?qPl`HPukVUuYg5Jz)Uu__`oe zF*LHiPvt{$tGrWdJp9FVfI7_=pP)(;U>^`_8(en~UE@ad@vH_rQ+qQ5_Gs4i`yzS- z`>dAVSRQ@h_|8?20v+|TfqBJ%jp1{H0rO@LW!y6~ZjAvO!{?O-Ji*JIVD9q`*f8yQ z12#;{GhlylweJg1{w=$U<`%=Ww+&c=N4$PGbGI9?VcJ>)HcVS-zy)5tBUFB|0UM^x zFyJCD_X6fFFkr*9fB_q(eZVn8bITY{`C2OPGGN2Bbq4G==vL;A8L(m6rDo9-tG}l`hVVzu;O2G( z|E#W*@Y4qDub3ASe$asZiD?z#CIdc*6_S8jM|iOT`|Q zSN^ut*MR+a`-<>Y2JHJi_Z7ew7;wJl_Xy#s27H(YFCaYHfc@dGnecZHq}SWuimW62 zjsg2;N6!=PFkru*_Y%IxfQ?b&dIR=@IsaAUt~6lZ=cf`b$q1JdKE#0i)7=$>cQfFF zJ+G}J{2|8`EgbxMKSOw{0sEFG2>;%I{oKR10lvwA{f$f!;mZuzZ|_pVvklnasa#I@ zh>Y-$3GbN^et_^NzfZ5XuY4=vZUf%k^V<7_|75^^5B-GjEe4$9<<5Q$@G=9IyAWk$ z+>7v>jPPi}M`wh`65b~xd^F)NIU;H8&71Sps637EHUl2!!LtcJYQTQ(^9kRX5w0Tq zBLnv9T}ybb0sG3YCVYYc`%Q8q;R6iVpK54e)11El)?iPROX=Lsv4cKq7I|<)! z!2YoJTf%VzKGX}Q^@M8-*w4L&SL;qUV80W+%G?tS*q>_NBOEede-mN70l4?R^m_Ye zW)Z^A8?aIDhYi@bT*MR+5@b85C zev@8r>@}V4-$VE{1J;(4Zvt*L;PGDWV#2>LU_bW)!dDxxZ`$pIFErq&r+hu(6AjoO zau0b6@PP*GPc;$3mI3?Se;(m~{5st&$9iSg6W(aR{#vz#@UJt%PZDl4V1Lc@I^ik< z_OEe%LHJ|?_M=5&?JxuOyTA1|at96A?}CMdllP|A+mE#~2|s1Pe%TVK4;ZjNw$w8B z%?9lI{7%A)4A}4A8wj6az(&~<4cOnhY-aAT0UNnLy(hiielWeo+%FigKNEdM_|FFH zE0-p@)qwqI`Ifos4A{>tPW^!a`==LszJuJy8nEADGCJfMu(rZx?yuIS*V~Vl2;tWa z*mui(!jBoSzaPAk@LdMHm)D7IBYcek`(>{qe31eBGto1IPcmS?VhO_e2JBCgvJlNO zV1Kv|_aOK7U!}XH#IxKcyvcyacyKe}-x#pJANw=mRR-*jOxp-o8}ON)@;<_+7;v2j z+y4MuXuz{QxP$QS27HDGhqnX%=_=)o;lCKL z5sJ4Nu&-Q}R96_VUojb5&NEKR z_ZR7IndQN22yZrE%{0RI8L)pk8Gaw|4F>FYBAf6f8Q~R#Z3FgagWnMzYrsY@4K-lj zEwbWD-I-qRWnR74Q~5In?2j#l9{~P?0sCX>3c^1&;3>Xx!b=R;xBMf*r3UOr>KBA3 z8L(e=_(Q-yJjHw?c{_ZBchXJ4MMQZRPz&mbFueZNGzku-H4R}v4 z_X@&)G+@7CHxmAd0s9+|wS;R8*l)2e!e<%qK3>_c50sFn~Qo;`! zu)nXpj&PF!`v>l82`@Hae>L$W;WG``ziRge;UWVz+_D$oHq_N>|Af*n{LKGR=Ye{K z{YA*&k0JLu1OBl z4*%Ds&5&%%|EG4R$A%wM5_jDI;hhaXZ^G{#r$Hj|x44hA*3%;V6Pb4fac>?`dD~9W zwN@Bfr$MV@aZY+uqTV6Q8|M>kP?;K><*1)= zc0eF`CI$pOyo`}xF5Rm2MnAlosrdv0HbVXY1D-*T!Kru>DRcL8sM3`Coi+Otz&!?h zxR*PhaHj$LXYZ#GzSn^L++~Ct4A?Kbf$)3-_M>kt;h6^P&jp(ZA8NqE)F9I0hAJ6ma^~8{lN>QxlQTzv0X2vuSwW59|@YEP4%fi-$-MfK9w7A`&11D7~zTS$l8JgACa{holKroC{J#~V^M;byKki! zairI{X=;=n!mfIWtd-C`t+wT;9a%fkmGN|fu~M`rc%mtN>)wufO^JB%&Fa9VJqBlj8|w{u8Bsj zpE|j&lU$}xLXG#NS)^*dH*8W)X60z*YqD;kEqI3M5Z+)ZZfk{$R4Sk0gdfp|9;qiX zbzgM>4P@;FO+O-iDFoegMl1m4WJdu)F&EMZDS*(ZGDj#NS zmAz2F!2W$s7CL^b+~N55K={mgPDQBkVo{76Bz?o_#m5>mX}!|Z>fKxE{E+`VRBK>M zX8L)gP4K)Owi}ke>`}a{PkL6}0d^BCVfk^4XzKM!#nL;I=TH#ZB?AOTNtbt|FZ86H z=WZP0xNFy&iMKaoGIFgfbWjK$N`;%HprP#^N|_)}!gM{{H6F5eob_oZ60D_$4#gseKi<$K#fhi)Z!)ru2`q@VbGzquMB~o@Fu% z-u0d?(*8IL`z>;I1%eRfrv-LdsR>$^eY7llwQpmVWyqogy~nC>u)|a9R_-8Qo{QoH zWb+{ks7zW%D3BW^~g%+Z$Td0eO}5;w^h@hmogkO&W+a`*jT01 zsB}^5Q#Gi6NV^e&QWn(j%eiI1k@A|AKxBRkt*U}bS09bKheoMqsW6hb+mnKw+twXv z23PvCRGvgW^(+-V0Nc`@rE(v28!e;4v@0=%7(6DAAw{9mdZAT+(M$+6t^zf1mF}-c zb|d=J4J`bg!XKyW%)-&gbU^awSUJ(JVi`Pil5{jR1JPsGaZk*5%SBID8LEv8dm@AO zl$4WL*g#K7(R%Cy=m%}tXjnC#&jyK!Dk9@gdbIxOI#!&~%K4yehzbTZBpl6>h|$bk zHo6GbqgK)l$-X>2f3BYY3pWb|w~2>$=@ygH^GEdjf7SD^VSY6J8afr90c?5yTGvFW zOQo)Bp{q;o9Hl|~QlU9UhZ^6-D#{Jo(5g~yOm?mHkJ3x3)l2GkE6PH)vwCrNT<>f( zHZ~1t7#%i_IOZF$v9XzHz!h+d+Steu$Dsyn9B~XWVB?4*!Fbm!H;y>iUv=1DMavP# z{RV6tal{SSIO3==VB?76bOScrG6Ar}r#j;J1X1kHEC=c)`^OA&#PKDgU8}Hh#IenQ z{XMA7lYmDJ*jFxR7@11XRzs!atdH>VE_n2N*Kicq1nIb^7VWSJzO?89Uy*+L@M)n-GKewxa{TE8n6+ZD-GDsEqnQk4cISR_VP0f*x0NWq`_T@5)9ii$GXp@UAdVg zSBL8)ys;;iIR*qj14Qb|6^s#iE*WD!=QHiZF2E?}6s2;j?3@Mex(WcN8tUYBfCBuL z)5tOZ8izR=N?OS3e?h)dr$`in!OS5Tt%kERAeYDo=`Q-Hq31JbC^t0(q?*|DvtDWS zi}m6evDwvdH?uy zAoDJRHswmg5zdR+a0WTK0M7uU2NtIBLBX8) ztSy1N(Nw4@U+M-s)%(NRI#%PE!7zU=db>Nx$a_L^)svWqYzb5&AKu1^CsT(W37ijN zQ**4Z8V{Y_5!%2P-fi502I=RciTgLD1Jxf>>^q8mXFwkV*cr#aO|h?Iz14W@*G|gz zQFdo&1K!r)xO>hy2Mnpek}0p>*Mg7?Kg*5e8_P;&<+yX z>xRf9j-$izim6=0>dZexoV{W|A^?S`x4_lH9aHgCc)Ts7q@bMT%S+b|K;tGZy8_n0 z359rYr;Q(vc7A=5{Uu%?hBUY}@xb-H+_%X)-)a!ZQ)BX$&{$`Du zhEDYSTs#1EQ@i-_V6?B&m*z)wH~O&<8VljQ5lz{H_|SRuBD|We(Ejo@JL@U9$&S66 zxEwtf?Zbtzm8w97@m@sUi^1QHyRRU^Gqw*(gBt+HBVjxwdxUwo7Ue5td_^x~l1Yu0 zhqt5E#yjy&?e5!xZ&br)1KxJW_$)(pwKodH1Izv?+jz(AE1(@Ph7*nq`SHLUz-{Hz z_=stV!Nk)`5p8ff1LjzO%#blo7R!JfSpEs*_{wGo^L>KxkyYT3f;+>mfn~Ih%^|NX z#l!X^6hdU3fxKweKoM#6XuXlk#fltQ%6IQT4K&N38xP#`F-)$|OwNVL=u#iUT7KN} z)Jx;a(;dPdRYoZep;&Wm3A~JR4w)8;T4kwAkYmOt*vobWRyayIK};a~V1yfot_jr` zL>uWdMa2T=LKI3%(49K)T|`Cro^0WmAhaQH4B*g)4pyS5?KNOf)_^r8s#gLh9HnPv zkJPe$gBqJz`CMm}weA>vPmTqihZIw7xk~xN->3*LV?&g+lFI-sU5kqE%Zpd!Z(tO zo`>dVlD%=RN{&FXTqVOu&R5B7Bo|1M(=_Iy6I0^<^We#2k*vmRwsPubp{u|AjdcCG z{o;X90Nj@8r$w>A2BPu6dVIx8N5lhrLuATE{?t5h7kMKGfe|YmkvR8D?_J8F#yij& z@jye8MTQ!)(1+-t94;!tT(bmGso`+`TpOHmNR%^iJQ53-;2V@{nAqDHXQn_?TeUXM ztX~A{ATZTN0J*f>>#` zldOq_7N2i=0Qt7F*(tSRCYFL!F`BzSl)f#JRCP*qlRUIT&?oVP_)x9WFau&eSmw zce`^gJ+>MV!A_SZUjlh$%@&pIC@}nNQb0WLQ#27q@hMnb=2+}e^BdpNswJ^Oa@XIgN$k+BN4igOE30+;Sb52xAO+J$U6@D>|z>px_vsU_Vpu9aw~9 zEHDuzie{pRFX70Z2No(lyuAlTBo0OSiD@uaRi=>J$Xw`@^0fNgjiD5q+Z;gH+w#j= zF*_c3?%$$p2F>J!2hYqDcChi0>j4953;s*nL2r^O!+1P@1T{=-f@+q&ax)8-p}4&W z84@?K{tfE&vBCBTS<5{Zo`DY=xVVUTi|;#X=$r3Z_Yy4g++EI8K6x^X6*5&z9v4n4 z@GYCAhMq5w%n`S4RBl1Rc*V&A*nSC01bVe&hmP;KMB@5tUX+LYrgJ8BgzgPZf^;8u zawuXa-gbZ&F6JZIXYbyvc1c|2fx#E>jH08Q04wGUhc=I5nJ6#fVaPz{WQh@OYLKar zoCWYa*2g(=?L6wNULzhn3owe6H94|`ofp(x#RE83#UYfD_qvC-_^U!SNVQsFG;=*B z{q|C}$QLl6g{0e3Fajqm?G#JQkXebPAY$={bE8_O-n|gz!57X8qw6pvi!oh^BanxS zLn{?fyav3O1-t46pJP|ext<<^AA;PGroTv7wz`v%wPkyI#A@C8C?3R49^G;wn#*cy3RJlET`Nqf60S4)(DC%Y22fspG;b?@wAsquDIiI6^d9H1fy1LKRbWwPd0 zC{`+clG#gfeLl;nY-uTKSSatXQdSN0UfliY9N)%s^UE=4UcXTxUit{fmRPJ?LP*Ew}Lh*|+5ust%2}<+@Srv}{*mgjxpW^8HKcXmuAt z5550FoT=fpKKY4kT)J~#IyDCG>%nOdhcontYOLGB@jy))N08743wus?EDW@)fllcz zD9hjWb6my3Xf{CZ2J=oRIj3Y!Xw~mX%8-k#7{~d1XUNRP5xRREcpXe^MZqv}WTFDM zJi|nJ36C@WUL7Cy3=T0Rdn*@+>J9F9LQ=&B&SM?Xvru*c2k_;Gqu7G@u%9s_m|>Nt zdVoBmnJ2ZcXC}>ul?aKoly2B8CkWoi3ArFdWQ&z}VuwF4B8o6}V{pxe2-d^!sv53S zANxWp;G`N3@A#fWXQA$o!A88_%()u=7E#C(qhR!hGH&k5tWe{T&hS^3zE=8i1r`x_H(d|c)^pmfLSFO; znMV>2SE7&gWl4kJ*;R)Dftzuhn8gxALV5UFlmkaD1%y~Q zGd?UEryebIlXy+F{iVFJCZ?_q%z`Agb?@UOBG%bL--#=g;51F}AP7QpuF^aj$vsta zIFi{aX}*|!g$({(eB<(-Y-dE#AbtnY>{RwN4xIeg;p&_VKDzj#D;Hv*GHQ9gB|nddgk*rpbZ^7q5iDjHOFnKub2e;=>Tz2I$d>2ft zUbqzBg^QL~@OymK#EMFM7u7DD7{&MGii>Ni@LjxYV#zr?S)N)l2N#M?WM?mdm-_K- z(+BvLnVIpG>rXBmz^}swQk>!LKGm?F!ju3nmY^$?U<>{iD3J(-f)Y`nX2{JKAa_Gw zfts(cR>Mv-D&@o@*{F8T@@mOLGo%QV`Syj#MN{IX+4!36Tq}}|RhSHWjh)rWY^s!t zPzsD;78_&EY_!2_w}>el)!g$C#i9G+^IhGMY`>q#6mEMHH2e{Ed_2POajxUzJjciR zj*kl*9~Um0c=9y*c>Ih~_;><+I@$4YF)IgpD!=K>aJn<^#>F()KN-%PY^^ARrBhLb zY`xk+GTmxVR@J@)RY5jxq>EAQsT6@nvsHy31vwcNzWj&MU$n~FX?rZJ%(n6JLm!Px z9ZtXX*;%qd?crRG-OOyPV4Ftl6?z1N<_lN}+URzDvUTX=4q%%a)Sr-PO?;?!4i#J>W8=}Q|?G%bi)~*-IR@S65~$?^4zcG!F3;3u%Rb} zzKAv5L%`99f6^8t&<^Wz#kySkc%1dgJEVV(g1&qKSGpb$$ugrBgvz5#+k=e@A?r_S<@CgaO z@IlqVh+B9giUH~r9%QX}Q=4PN$v~0J!^i{2s6!xJ5BpG#q4tOejzKC(=ZOQ_{|r|q zUYP6O9CkUDf2}KAoTJAy+1B>3{Y82*g3%pCXQ1>I@2$M(ZG2yiOz_w2f)!N3Ri87< zHA4YLad}JS@UFmm92GKf@QzxfQWKRS&(e@tnjw(90XWuakmR|e+tZ!nqG{(&n8Bw`_pwYTEn1y)kR>n;ua)ABy`hrOBimeJ zPY~TMF$~03m&gIp;Szg<9!a?Ap`l06-IT7~Lyz>jX`H`0YBxl7D+z6IGHi%sgFr7u zjyQI%Sa@@EDKEiMa&ZYNQ&fV=6qcaH^J6u*-i$>b>KTmX70iq!XX5NIq4k`^jc9(! z-*(LB>W=24e*g|nCRtD3b|du-HFCXZ#~n6W`Pw>IB9-PnubfqKSOi%3^oUdcC6R@vjrz7w>wv$8P3G5lQ34X0~+A ze317(+FdiZ;tOrCip4o2BStNkLM~s{^l0%()yhaUTjt&s>h4VT_zXTo;@f z`)X#aH+|GR>ukoB=y2BsiQjz*=g!>RaLs1CEcf?xgd@=G46JXKGNfj1wHvP4YK0o( z;;Wf0cGKw(%2?;je$(VAlzcloew#E_d=*;`6RI71E^!cW)nay2Ep{*G!cCBlJ#WW8 z^M=22M5L3sVPm#?cVKh~T3ode%)mIc5S=R(h|k=NHK1cH2Qxz3{w>uZwx=C?)2@7h zT8@Z4wcX;y7fMK62865fJ8ok|glZ6RY zp5gBV(l#i84(zA!{C;3qN|aE6tyHb-%mveteUJsB30H8Lh7XeUNV4D8KdxFcI#gT$ zZc1K1OlP#YvEOt0Kvh1KldyOJ<4QR%zDh0K5c~xze*#%*E6Mj)Gluxlo%Cxs89pP# zdw22W%(lFl1Q$fyoivwvK|7YidsxRa5ED7L!jFT@=n(ugHhO64WILXN9VMl32|r9{ zuc3Mm6J z%dEhW8fAO~c&H`2Gb{nKw*+e5!1Z!06|!-Xm6(66vo2p9I2U{zpPYd&ch%gW-v|Wk zNMM-W0*Rkqk5(ZnH%*Ch=e}UsEXghiHOQm);BEOW@DF7Jjz+W8<@N9vYOVPUP86o9 zbL8lCW~Ks_X-g!CE-`Y#6WGY@hkWivEMwp~?-ts&}-8^8V!Dqc<%alhi%pjh_V7qR=# zSn+WxlT-1dX>NMO$B?yJuYptXIh|g`zuUA+#ZzScHx<8=i{}9<-rUTpm%6vr$Xy}` z3{I+fU|ENx`-RzYZOI3QkN4+wo`YkMQU4+wf;x z2mXvF?}!ojGvQzOGw}nCU$}7`J2bm#F7FnFMyFTquL6EHLVC7Um#;c3?+@fCrg|@~ zf4?TCOs*)vB-T-|BSs6dos2)_B!`~$WwwWHrlvU?i?t@z@d&%W#EVh zW^Ci8xNb6TAuB`@H{-Qkhnk`}-^XGi7C0D8+`o;#hgiL23`bJJHFYN3vGY}&j37Vm ze)$SXhP&*WZhHaVjs@N#Z{#}^f*I=G)h8Va{RpE`pp~SYhQmlX#_+B{0liD1(LyzT z1a2m+`rlczQAAhZ3UK&o;RrimN9Qns&VEOybav;=^GEIVf5u7pU*6SzL!nsHu<{do z(Aym0Gt}@h6;2wA;xs39U=0%seD?~S)Q7(~;@Ag9O?q&gb@Uq%tRDjtkbDivcwn30 zI0BH7hJ#F>9MF5ijU89V;O+?XDt?uuWYZ5%yLsmm&z=fdaVB_FgS8o!dQODM2z88X z0~lGbzX;2-{mDQ>&y6I&>_dF~yd;v9p-tQ7Y5zVYC-_CUHb&Cv6YvOW&Vk#CH#Vj!w(;rW_rh4?ug2 z=WD*cPJz()9l5DPy+K@+bsI5nAghCK#fJzK4CC4{Afg_TksCR8+R4zJ-O$quC+4M& zm#J7v!_D_`3y#R;yM!=5yG*ZI_o67}n|<)}j=V6Ondkhx<59Oz>9X**yCA`^Bey2; z${VI>MgjDOJ)LJr)xg2AIre5*#6$pw6siN*XHl18X@dyV;-)J3h0bL9pTS=2CM5j9 zC?EshVb&GH>j+DEYM~Sb@5bp}=;1Y~f5BraoFraw>2M5kCpY2`J5T`!Wic6bk~QZ| z2qRQO9co8+ho;HNTOkdPK{Je2LEeDj678&C&%a!q>PdurLj8!4CL7hABR_yBK=siC z_LNSkc62-@>H;mx<9ZgBgCC@bMR63B7>++IUPAqV7bU7E!*LP+4ly2)p_1nPPYhT( zv*qpW-u+MDv3FcJgIz|glK#v4pRzfMFiW$HXfz3(KT?!-HVh2-Lr+eE>Jd)3L0ml_lcOikxj2xNe zCM2rk{WjVyM;Kl?adA9XwKwjmlCt|mv35_DDDJbnA~YDGLAP~9WFXgO1u-8DgPFkf zvb*}#?)G9XYJdm268zm{rn|jpxg1;nmv^$d6THw=Xx!_3Qud`AKt-|F^<>MF* zdjoF*Qo^3Q)h`!vxKPEWCUsV5!)%%u_$5U78;mufN1ADsUD>%>62Mjh!>L*IA^itd z#{$bh(Z)QnF^@Lp$bc7GwFgE4$j_vFA`7y|i`Kwoe0|wn-I)mCZiyz`Hj{{BD@*Sj zP>tIP4(PX*Pmr2%?RtQ{MwL8ZA<<3A-@}p0Jx6>CC4pD|j^6=J-GfXnJfE)~+Zo%+ z@|C@t0H;oO>-kqund*55Fu$I0Py?D!cR1=;L0PHed7?2;iZ8E@KTVE8Lo~a0_?@G? zz7zS55b5qvJMQU?y%_6!@!i-q)L|d6lTA{wK#n7VmSK*so80-^4xq&JPp zI)wJTBCIdg&y8?%r;uJe6Lnn|HQY}hsv=JlMNPHRSx_{T zl&o{iz*h-=<*`jjRo~~vcE$Q)?;tKdjP+%0v@5r;taZCuDmtFxt%_{7thH=6>bX_U z!JJOO%12yF&JS(Cbu_JLs6d?{ffZ5bi{Ig=8z^s+lqXW5_SpruvQHJqo*VmW>}%et zXT{!*J^$hdvCotfw)sxDRXO2jh?2V7QWKR1W_By~y&CjJ*vuxrm5~W=mC##`nd~kI zB-W}}GFZ{+A}dEPes3x%I4+ed1~^y#SIe!TzOBWy^*D87!K)OMFmZI@_r_N2m9bl5 zy}PKDZT^W^C(;$ncOuufPK3~`sWfYqTM# zrKZMSsb;mM=;T_sffFfk-Vs}O5=YSK6rPU0P~FuyJpZK{%AjtyT1;cgsE#4|CXy=S zoPz0&xzi>7PZnbi>SoxEc9qL$Op5}NlP0D19{^+t1goE)UvOMCb|OyKRa=qJsxzIb z4+bkY(N^X9f)a^p499fciDHX%+7qSIhE^4E8Qrkic22-4o7=>TiBGX!D-!Ph%OVe_P z)J>vPo)u0Fr!VrJmw`5qcI3j2z&*%ReJ}vDhw2RI&&asjwL>YN+mINHg$y>eYO1Dv z2fzUnzQV}MnmM*&wnp`g+GW=r*N)W@UbOJFa#!xa?qEaG7!>Etp3)`7N2A0?p;eqs z2hPu&Y3`(DIgiqJ>V{9+2BY7E(P&|8j(Kq0juU(asR}O29TOex{`x1vel-|QM zp$ZO4JHF?%BbI4sli;^ms!iT@MWqojrq3xDsv0rkxW>uQA95R!?;~|`B@dN>BCr=u zebE~_`%qSBL!$}+*f*5+4IO^%1(e^jp6&es&PmyHd$KFZoQU$6hkb~38mg>zx#&E? zrMvc2aj>V-D)V~XgLE5(@svndj0q1un~CdwA~fi_8u_;BFxfy3Q)!7Xvg$^(<5G&1 zI0_dC8af86k_(j|dC{PuV}xeSENh?HJ=mgr*znOHSq;MNjIW@`2L0X> zTJ;2a?tjxjkFp_Jb6{&*KD4!e2bU+hP(dyqBqre1+i{G{vF=2*yuXO`j|J+%RZr2w z?+L7SK71x=WI5@Ln}Zr_T&Hn!(i&H(Rg01bTxql}Dz94i5?uFDe0qS# z-(lF(3oph0hWw;ApjC_b+kR#%q0Lgk5AcO{7dFQNBdAMb(H`;9UR_Fx z?LjrU=&wCEnt1vHcx2W)3v`1vyBnvnSF>rs($%Hk=ADY)WzPiCBZE=kcKjA>BYP>c zH3sgVAe&_Hn@WgH1&_(0o;O+aOVB!Q;RoK-P*spQnT@_138(H#q$V^~#gZrdUfURs zJ%?K5deNZm#4}^)i6lyq6sJZXYhd#Oq0e+A55k(6a>mn=LX8q%vSI9&KR-atziB~} zOy|rIXY*$?vF)uy9&acKM@!d*;J%{8Qac%=E?r0uNNnb;1{KR+#CP}D2SEi5TAr*FO z?0RS=B@RaS%R3ympO_QX)L5t8t!1ObDPkv;OJ!{rg+6cOx)a+YD731RE0?YAUAVHj zbtsS;ZIKh5ir9#GIuB=%a6qVm0ULi~O*~1wn+gtbEF7wtbtM7lZa~SzX?w-Bua6N! zD+f`($;>MvYU@GY$kO5%WNI_pGyBZghwswICKb(#fbg1I85~Trd<$fB{Do#n7xe$iDlKifK@ApG>nM^t(Pul#6MAU) zoh5Xy2=w@*jXbr(BG_Y-L@g-|2tlby#ipbU3bT+BGt>}#I1u9J>uM;=LciCv9VBTH z5xhvCs#v>5G`kgVF-pmBtdaQ|m}iv+QWiC1Yu<5X;S5mg7GjgMl3k@1*HrS3P(HH$ z`3YGRbZ9RPgilx!C1fXRb?-#sO7U@;jSX?us+4iob0KFvH;urLl-63!VCMV6e1O(< zXapd=b-C%Wq11aq&B`7!vXZY#O);6^i&P_un9rp~D1B%-BSumkr%QT}ureafE+uq9 z*kFb*XYt%IrvLb;kgmDTq_VYi%uq?R7o#}=pIE><1bpJPM=xldmFhcsbM*@9)px)A zN=lA_e+_}zXj{;aUrx=hRh`qS>ncKiWitWzI>9qTsP1*St+0kxU~g%yQAxz*MD)Ga z$h}Dmsug5pd$7f+;FloK5g&5{^li!~70j1o6X7<>hs$~uR{}}}E&M*Ayx9SilfJzi z`oc-UG%;>utS)0L>%A}Hq81(wRxj9x``Bp7tO+yC=7+S0DQ$+#?0CQ251U7jLO9+} zQazMISn{b5SzS0h2DQ|(e4gaN`(qwnA0tG=tdVgKc(%n@EN&@IRoq96f?_DXH z{6)9YIVaJu)VGm~>*grgbYb+?(t#pTp#jy66*!E0GgcSKw8W8xQP zhEh8=rP*!5=J$%CDwcvZQxvI=v+`PWBVu}^3&Nk7D6s2jjLZ?MB7 z)wl0pE%I0c`s!AlV(Z_$ws+$I&XhG(ENURh%%DXHIh!pSCuh^P;Q3POmOAMorjXRF zBqb9XR$Q~}%lh~eQ^8-q#ccO_t}KUU6dAtSvOR!cv$ z1wR*4(62hbK&5zzGQg~ z;{1@HW3_9!zuu-w3D!}gRKce>^fry`@8P8;5QQYiz3RRYl}g%!M@n2zRewkZ5Ar4E zPX_nkOEizJ;aqO2?^8a8kP@k?8W{q>bQ}jkNwrweamf`{Ql<*ce(6e;@OcdDrgx;6 z8^XLBOo%#|EYyofcQ*B7eKDkIxPRmZd8({*Mi1vQhmR0%?p7LaxI$P3WaofAwLG}Df^GDNrUT2 zE!Jcsq9)UQ+Yx~^8AG!**$8X0pP67693MuEnrs^;x*Cni&R`X5t2!jF8n=R56t-u0 zp!h4>a|<$1ds3 z>3vY~!6rSl(&at1(&w&~9t|T#tu%q;X5K6wOZ4x`evapC zIsNlS*H-V{)OA|^?JhPbyg&dW;YY3^GB~MRRFC)kE>ZRLr|fO*r-nTGw^MTPk-&f5brZXeBI8HEW&<{rrlZUYfsOhe$fdI*b*Bu$Gp++YlOisPN*a9}+@A5U;!nvcQUmoLVj!uFun=K*lIP{e#y!1x|y-!Na9 zefK;MFA&=u%pr;N-TZ859v)0RlJZjOT&%~+Dw<9Ypv>5`Ez&3^iGTy#PxHZ&67!_g z7ei1e6L3e_(4d#h}X^!d!hO(W^8PRx%xxkY3ed!OhapuVCn8aCDUI z)~R5e%a%ACCV2>DP1oFOK|l%2z3svHOg#l#R@!>iQf6wYVrr>$Q_F0{kKoCbL_Iqf z^g<4SS>gs7aZm6bovRawdw>sHX7@x~3IuW}rXKKR8eGg>Q^5s_xlB2+HSy31u2?a$ z=8xhDQ^)zH!O4E$5gFcYam2bz2lY;)D#SMR3rh?vl8RN=G4|ztiPbx?k z#;dd&sWBBSQ$sO#!@srS)6Au$Vl#OyVi+q&q&}S=b|6@~iVW(UWc+sqtBJ-nmsm!Z zI-xB1Hebdzb&jWN^9VZx49C=C@O7*sW0<-&PhP4urY@a>VM1MO%gRz>?9vt~X(HN0 zZd;-^_EmB*Uy3k9y;07+O3w3e9q8Zck4p-o>cm>w!+dR+`0s<^n7##HW`ExlBax33 zS6pA`xZVmLa(!KLrQ>?vMxN~(h~s9EaCGS+*~3(SyvEr6Q`Iu^4^FCL5wJMhuM#w3 z`)A#kXZv6C<=FmiUXk;{-917P+usU|WN)%>*#7(W?b!Zm^LNkoCX*G4r5CZWmj0NZ zp7`2OzYi+;>_k3Y`FejEG8yblW~pEVzbGAtfcon9^E#8sV{3*-YXCaH7uZc9*I-I zJ$!Ar1Iz)#b%0Co#XG>a6!#l;fIWzl?Eu}h5sdKCJaCf1C#q%kiE&aDj{}Q$fL8>K zI>0mT%Xfe$`EniLr|U*U@~=?T0d4_CvNzf{9bmqFyAF`VpI+5R<2Kq~uo5CAcYrsZ zd~mzYP9(LRkZyM>2=CSeiw-o-K3pkABlZ}+dSKXLh8SHm&7TBQK`CUyu(i=LZ$Fj} zj5)Qo{K^@$9mo&bwb?=YI^)^LzKn=s+`E@AYxY{lv)a(holU+6hDP0IDH55R;Mj4q z8-imwae*W&R6NCTgl|S$Cx=hIS&ZKr6Q{qRHG?M)Agf5w+N0?gcXU2U{ZFP-yKDk|GE<`7}SRdgB{Szc!DXGCDX6DaE2#y$DDVq?fF zw<|Q#?T(Xf_sotts>Qw);H831l?IG#8jN(33e22~Dx^SxTYdB|p``iMBAEwhn8m6& zZc>5zW}8cl*NYffT7%(gEEg=%ql7oc13)+j+kkvejRbH|FCt$ zv3#(On1rLh_F#hd<=82058j4+n|RuTckt>DRr;HFYbsEsw+E{|v@Phs$5|7F>8#0L zRlH;&Ck?b={Mx&+P*|?4+Jb)0DVAgFLt4O&HszjoN$Y^?++g)uDhWXVB-6%X zHM<`hQfs#@#9E`B1`Ipz_KUY6hEwHF)e(oihAP*;lMioqysYf_3zz=Ic5H)1(`+)p z?xSC8Y`xT?j^L;pDn55Vsx3GH9N7_km_#7N;-buhTLA7$AnI1Ljaj_7H@$m_NL0B$ z-^Q;wvn^Grh1#Y>k=xrv?XzfqB6u9ZN05(Sy{wJ&hNum7-?vKf3EvCv49pne%niOE zp;X1E`ehghPe3o@1oWDXS0;m32~fW%D`>O}joIzDGgMI%A(MCvrR|0o>Mg5PM0+nM z(pwrE!|i2=mF@(CyPf|z?Lp0i3eWtAHUiDn!Z+ymdEC;bv|a={X|@S6yfnMKHwFN* zpLXh^lAJ?fR`q)fqeR$DUe~}O5i2VC#-Z8R%h;DzVvvk*|;0y z#aN8Xt6s8UwmzGY1Ip&nEx~>e7qRy-IEBP|Zac~kR$qrwkGi?_ETh)3x|q6iWn1w0 zr|@XV-A=(V%2?DQ*ijOyxh!?}=aQGY*}vw(jyo&^XN*#RbA2Y=i?PdwOl)FI zVU#gD`+nh7k)K|qPM0xdrt}*=gPR$ab&x8FKUHyj3nRVR7Uw)>@NHn^yri0%q24$B zQC9Ked;R0VIFBPq7o2x*>jr0AkE3A)oaNo&6nY%31i`tZJDk7KGNMOXUT`ky4(ADv zqrEwBj_D5P29Kkz0?w{oaiUiyQ0!0*(;T|pBkdEzwXrtgbYIyUsycL+`v}OFTiGT$ z$|~!iW!hqdV`}KHt$O%FdGvC5=q@UTLLq9&E!Jhq!be>8x{jts{23*l;3xa6P&FYT zyC%dOqdZCZl$`GvA9DkytdsMe{8@=6-xwRwHjjke7YJ#stW}U<_M`o?ataaB#nz|u#Pe-Oq zu8e|Aods|`z1@tQ_qO^BPQu>#(SuERI391C^G?CL<&ZJR1*hOcj!>B7h$C^U4{Hk! z!*x5TOQv$*LL=#d*I=sl;1pOue|R@S$oAeNJ+wVIA{%~K)_X`4J}wJ9C<2c4zP4bD ze5CyshIi`@7IerDPM zAK@%%h4EhOGV|<^-dh>GGo7FF*_2;eP>CQ=O5a|}e?j`Yzv5>`YhiAFxe^+AUL4C) zawd7+f!*}(^X!-2OL+#>w*HAEIzMcYTAfc#Czq;SYDeUyre0zKV|#G(%v^U~7db!mxm!dKF9zX<; zr7PBk=8axTUlc>sQR7`eJZS$h1&h#&g~Gb+BNeCbV}~o-!7O}>biX%a!1R7^N0Hz+ zw}N2)(2i3yJ(+xiRF1`!$_E7F_y4Puy@cJwP^q%4`@~%^^-=@f_%ip;2!U<#DBl{S1Uj7hx>w;yuTiQpC%U<#s~&@e*^v@-k-of z!uw&WU=Qz~g8u;TpNjur@1KtULhnBh|4i?{2>&JKZ>gE(s^C)pIoEw&=06v>&&&Pi z&F=Fa|GCh8KI}j5b)Qf8&xhUT8}F-7Ej6mHww9U~aOA$|-Iu)kNAJGuT}FJvdqr+K zfw)W>YBOxrS<^Mj&ZvAHPt)${Ih<+=`EQ%_SsTK?Uifp*LZoY{S*7Ipi+MXf=bN+@ zBuQcH)3l|IwrRCJM|9@~q8YAKPoq#Gx-c(vkPlVS^Fz1rp{j`d&?+CQ>d6ls>_b&) z`JqF6sH!kObW0zq0u?s9;&#EJPuK`nI_DoO+_14{jn!BkmNb3b7FOvtknHZE1(~|^ ztP8V^5!Fk&E`}XKWx3Cqnmf16}@7(I~It=r1#gYSo91Tf0%uOeS65*M{B{ z+N%CeSFv^Xh~ILE4BiD4Rw=2lF2z;Rkg=Pv!lz{ChqN_rlb*+q;Me%Uw4Rmi9d`p&-z(_24PW}%9}}UXDb38e(xtuy4QI@UYix#V43()#-)7hc zJ8T`nZY(3zSSE~>{!L|;2^5;slOuW#PoH9VO=al|oTuwlwP|{Ov(#Nrl3V&`j2=DK z;Y+=&pvH}6ZrF0#*6XyxyO$nGl0K7FW zRZ(X_Ct1*i3fh?<)QdZ&D*9W{0TwhvL7NlAy~+Wp;4^$|{MfyIyz4t-!${_Q+GQ2V zcO65TCUy<5$)~0(RCoLyB-fiIyY^TY?MMk<)q5{Qi4!tTmNDiNGkx>sQBN&x`2p0% zOK?_KlKd#xB*T}vMJv|)xn(}Mb7hZ|%beL)QGQ9cl&j&x@-&?diy6x`GWAu=yAX>n ze~3hw7gH6Js6ysDwVyNm^pD%4A~zyIRUE4*?`5MbV(X+Ja{(dyDdfX!NSG%#^<0xI9l~ZtPkSQ6hbOYS;~3P1f$-v)2Tqf-U|*T2!u9 z1pV+MoV@mSSK%aF5yaP>zXj_s(nD@*!}}*BX}rtve&D>Vcnj+!Uq6EnM`4n$pTzAw z%Lc_I4PLMw@`5zUZ}S*SOq7%?mDa(X)yQ${$jgP9B0il9vhvtP!EjxC2Du#W=$nT3 zS}1|O)A0V;d8guCUN8F2!pFK;VWRJN+=koQf}?T$x_DM7|F7iGLVJ0(g|qJlzX{tc z5{=qFTX2Sa(D8+6CswnI^)8?KYYRpTp)J_mIrYvN;hbS|$YVB)sXw>C z-x>)%eeC}H+pwsA1{bR7zqgys26uz?ohS`EuF)ljBeH26-g6owHkd}=Y#RM~PUGF8uq@rt z@r(;qS;~4&<0l(TV@@`WUOlIA@&?lwlTD+d=QOt5U>g7KZ6#G%Ht#u&R~(iW)Mx_j zfEdl6mB#K-cw{;8HDvm975$rmrAjQ5*@w2)4Ix&orn`at;be7Vx9~Q-V=R1*3-4S> zZthACxw)wDX=J3a>0SrZ=0Z4Nu&X1LUNkDVXjbu~@%URlaRhxsIZaz{9+V5G>2R%-0Ds$^^AhWJx?G2X z*X?%&FQ+i|HK*${y9v(r8f&l>p>)m#G>W=Owe(B%@}Z1o2Sq+U_1tdr(^J@eXba}Q%6zO5s}{a0p)fXJ zf~V{9_B0|k-X06i1dWTwbAyxc@O=!<=>9V%q#u2jm)V(+3(|L9sZ1+IPDd1;{_jvV z_#y(so@Y9N;h9g?cc%Amk$AYdvUM`R*~Cj<&`#uLPA%9lYV??>q|MZV^i42Ts3Y|< z(HqM0p%`4^*dk>F?PxmNmd?r2V2O4-q$oi|???WGQ8%ClAJ(YbQG?G#8dMeej?7{0t6XRw3vCKi z%0gEgCqPyD^fq;p=+Jv;-NaSK)rdyf%3vv5&@q_Q(|5+;s*L+ZeOMXSXUSY-Q8KEG zwJXBLdwZ5u#>{w}+{$P?!&OGn$5h5;v>C@MR2gH5(nDoTYusK1Jg9M~oHJb29O$a% z6jwE4x>il;oFc_XqF8nQ3?_Dc;l?YhI&0%`a;tOO(_M8w z%8ZuYkw*8``6=-Ki`Dt`IlRNwLj@+D_|MoXQxEF;RQu+-3o+y3P<3AX~|8XvUPR?&K zKdMhQ&Yg}IFPO;FTd7=OMOE&I5@W<)ozDg`~Xy9xuKO5A+2yaMk2;!(yL}KbQ2WvCzqR zp~uBS59<;dAK-pTnDV+WhJX78@UQmxSH|!~XN@dw55`{v?P+;zwy>z2#I(rDeZEBeTpdWB5rtvkqlHC)k8Uwb-dr^|Cj7*?rb zg{qfTx&E1!ViriFk({;guDN}pRPox!?I zJmfyGjfRX40FO57G&*kT*8kof)|a2IXUKHQt#RQ&xzYA01?##7$!HCj7UF!K)|ug9 z)kOTT>Y`W@I$JS1GlGTYXz5Kxrz%c-jvb49V?t*$REL_dDa-8%Tb^JNx7y-!l*^Aw zPZX54ET$qSU<3a+*o0IQ?2qet+7;o4o?vVZKl=JdXoXecAEA|>Q{8Jq98@f(6BK-7 zBCieuiuv#%X6Mak!F!7sqBf)yuj%#p5bf&+nl*=e!$s7X&KI4=Zla!UbBE7WMzIGw z3dSCla+S0lyE%9D`cAA|YE9koU_4+F%PEjT^F?&2(G8dD>|q>o&=uR|LQvk!pZE;0 z%4Ms2g+{W`NR{WJjov9QsXe<*YGpS`(b$!R7;|;{&(BvbOAmpg=Il=kgI&&K<5Zof z7AQG7vm#1gW$RoxuA**=Yt>?kq-G?!;zAb8e+etG^F| z%NiwJk<-oGOQyAY_Ia(UkSr525(0ZosF|W8t5YZ7o37mEmrI3Pu;>a-yd{ROOw7N& z=0mG0!zQ969mk4uM-zqWMv{@It4y*+-% zu)W36)D*h7`_PRod4mdA`Zho5hK*1fLRvpW@)h2!3h|KF-1S6a2y$d}jyWPVnX!e2{~e z3Vu@zUg+ST9|`=P7`y{^h96!N{LvWv1qW{zygdeg!oeRB{FNB|#}0mz;OQ7V>EKrg z{zVLazJs4Bc;A9?Zg;2i#g1bg{BXes$KYced=J6vWANb)K1A?+WAOeC-be65WAJ}z zJc0iw0Y51Qf8D`f5&XOu{22#dDtJo_{tE}cNAO!>@LL@G8o}?2!Dl=8Ou?Us!OwE= zlLdb^20y~V4;K8D7<^9$-%0Q{WALpVe4yZKV(^U}yz>a)pU2?;wDGLsUBNqJ@IO2F z^MY^8C}Oe(?Xt|l9~ZnL2Il~|>hli4cZk8Sb?~bM-zy8xTnh390v;R#o(b?o0gsCT zvDH|S5b)bEAg50&b`|jA7*Kosg9S{*fSU0(7Vt+|AfV4C0*Xz7OnB~0GIOk%5o0dk z)vpQI_$}`2EGTH&e`)JLPHZ1dc@{lz=orjVKanU{BACYHGhbQX>9#0$%SF&Gs1ObU zAbKfzCm?di?+0;K55o*{|C^y*?1#yh_!Eq0Qgn+*Ik<>5`+f0PB;zE@YdH8c z3(%h@Uw1K2X4JIcpI#*2_wbD$%fYs}cxK}!asPnJiRXe%aZ|XT;i`}Wap&W%!qtJs z1-RGXzScgr=DdsEo;Odcg2sKWmNTR3aHzfL7Jk0F8$TB(`MKm2elDHE&t=Q`xqJtH zu6POTsTa3iI9bt7|J^=vragNoLDPT3&spE$=j_4!eCtMj&QUtwewUwfNAmNXTd5@M zF*k4k>1Ifg8T;sye|P_)aR=w#Y}Odoj~+)oOMnIM|n)b$oS$ss+~ zT(;bB0Z5H7E8z+83LUZ4kn9y^Kh%QMLN9QvlhKHM(p(mL@Htx7VqP znI(z}8c#~Egdf;g8bPvmkr*o@(z}85w5F&mXxv((YcX5T{=P5ow)ji993|ELJ9n|I zaR7E4M`)BJ4V~d``Z?=g28-|(o6fd%W8DJ#SihzS;6Yfe2(#BX6;TEqzMd7HW!P;d zi5h>WSA)1ldY^(WD_5n0r+%vjN|$RW>l53 zL3d1Ay~!XMoP&>w!ibh02d(KikO7PNqGww^+qlJXS6e=RqvSaxeM4J5OBQ{NDp>mT z*QkOlWf46TRd$bRVs&w|4jHH}7$u~nDUgXrY`~L)rrKaK9#=0?4Ao@nH`q4A@(80X zL$h)=v9?2kvcVqyV)!Lk!(%B}RpwdeUa8>YCsZ!j^obXm$3#}SuXZF>wFMW0rrLFP z$Znh3Lc?WV5l!E9$D0($h&RA}IRV!CqlSXtc)RJq|xy3k4)tLeTUoS;btQdQ~pMzaz19+Y(#8C4i6n3dX7F5)ozd354|>csTu zftdMhJj*Zg^>VE{BvfUVHyR$u-c>gN4LwhL`WiA{v_Dz#L?&+%sP)~{jTi@liE!I6 zO^Mb*0yCRNzQP5Xa4eN^q@uTf{3B6%`)3P3gCURF;8b70bKBt88~>R?V=0}hvvXxQ z6gJpFJJO?RXeVpZw&0wl)H*fYXJ;GknpdlgcFDe2^gjvds%EN=cT}nv^IHx?;?88p zZt|?^kRV1PPu2TGdNDR<6Pe3Ni)rsLlG5n}hZi*N0n?6*c+9TkkGng|^)vH>wML2P*3T>800;qMbonqlLgA5)R$?d4LhkRy98TLa9PY0WtYUtiBmNuYp42%pZQY83y=z4qg`$G{SzKnV$HtgnH@J&%Rd7- zhme@!9DG(_iIHHbls(H8z>Zuf&*Tm79Lc+k!8d^~4HF z7u|gG`_tX*%YHzTwK5~PTPQO!X_Y*-W_OmzOqjFz+4B$l?6oOBdw<5y=z;v~vx=X6 z7x1&6mcrHHQnNy;aUoBuO;jVErsi}6y8Bg;T^RU-bqX0vT!L}?v}!v z+fukvOW{FU3U8sM@RnK%S1FyXv=kn!rSOnji9JD;fICsOfjilMPm$YkCX7b8r??}v z{^5y#_@(c;&#c#QIA@;_=`?MzFm%6=7``l#ToLWs)yJ2p2mVD%)TYxd*`8ul$72j| zF?QKtjL?FS&Caj?x%*}Cb(AT+@FQC^(jb+MYc4sck!4>ccmAEL-}!; zQC}lQp^I@n>xV|o*jAm4fhT)$ISJo{jt%ri(?b7oC!&inx8WBQv!5YyjKO`klc9-lrZn$U^)p>9HK z`ot(ZgMq}&20V4RBPo$pV#lS9w?{Hk*E29N#MaH&46J$pb^bkb@PUkkU-p;;ox~5f zv%D;QjS`s*7V@LwLO!oo+mfw8d9%_rw*CFn>otX*T+s1Xn#Y)=@i?DZ?ffcUk>FIb zvU2O!w&ZK+pWl(4%ZEg$CB1~@=H@nR?jLhIb$JfeG~#hrO(y(B=t_A4`;1}oNu@kF zma-N}Dsk=nt||ZfM>gx9T$o|+I(QBSQ7dG2h4`TbO=eq+(zU1eJ_4Cqyxwu8E80-s zA%>bzP{w@aYoa|}3a;o!wysyks&wBi&Zk>QY^X7@p+;iEFduX!qqXF@gclnU-G~jl zGQ~$?!_=%jXwz0~NN#xYF44#2pgNMNGrLSs8K zeEyrJl>tAaY+a|7_4jt2Rt9}f)5?z?&YM=gj7=*KyJ=2T6ql+ z-0&4kvGJMgw6ZULrj>rA+;v*njZ7HOzNE(fJEoQ8-)LG{eF$_?v@X-ipT6d_GGj?N zt!zUKH?3R&d$*dr>&UYdzhWhU)W>NVN4)jF>#&#Q#Wz_C#I?N*BPVJKkqseW_9OZ zso5TOHq+Fz?}pRVZKUO@RC&nNq|K>>)q;6DtV&E>cK0+9pPXZkiP~Lmow@iq}_g7XZ>4i9LLL zM8!&d%a3R}nAg@nnZ|4)Ux$p{5pBO&jCFT9!Yy-N{3GK+{G*%=>!w-kC%GW)wA6LT z=6BN?dHy@jK*V4)MB#4xe74#~{L<^nWyuxHTP5%jt6Uj>c>f+Rg_-QG1#;~@ zNHWZUfMc{ z^Dx6oSZ{0pSQM8f+KY@lr~yuM$cAuF$kEn0PBjH1`Jx)P#y4NMrVqYh|=V_Muj*EX=UO z>2XqVoXh!;)}hL@4pq`R4E9=w5e(7pnEVv$hSiQ)sfsdH1ujibXFQLD%{WJU`XxpH zRY#e|UktF@)df4|MX$2cUwtGj5&k^S>A7v74Un-_S6!Uj|Yy%(c#Lto4Hd>KE^mtk|NP&SgV@ItC>irNIyT zi$643KTlqiJ9I90!7tH89phM={b%m=CBHwzzc^9K%uYq0rrP7S(uR zmJ{IV&`x``hA+>QjWsp2O0`X#O;>%*B-kH4uxV4r_~nJJ8T|y%Q# z_&39kcn63?;EU!o8%HVpnVqAcOT(bbWN@B>*nal0PH{oWUlk24IkN-*(D704dVk{yI3}1 zvseg~<5~rkm$j+Wqd)onSG5f{RAMJ8B1xh>IBsFoKy{R%AhR#^S?8pvE!de&kY%+d zE`Dqbv;q4EuA%&i3pG@gHB_CAP?3POOmapjVBI4u8j6=0j9a1+_&?NAoBBzg=KE$X zCF_;Gb^g0s%4Z|)+0pyq9$o>~K#xk@YShmMV*d+2am|>i&c&dp1@4iNBRocTozTy0 zJ+}0DNQ3&Ly7OAPo=1DSZ|NhxUQ5gPX?HCxaTm^uopK)$opRsW3DhHry6ERuM5o-5 z^i>(N@9q8&`+aUGcJ`wk4>`tcPcvjYxqE@&YgN7f6*kMWX*ug%;kqDZRqJWvM(ZE# z=^yjayhi(;ufgu_M7^6cvgdVQdfqJ zrXiIM7wh6XlR&^P7?Nd(NYF zPZo^gXiCRg$km1fHnkV)v&`wvYfZG_relOyQ_#4fCVNIg&oGwRZMl&M%s0$r*onHxMmfJ4@_Aa5exst2KIW_P@=VG9=Szg(2<%Q>%iPzF;e zgkzE$*XkJ}%HQQi$PAftET^<3i(fkQRH@KPK7WHl-|3Bj)n@HYiqhG%jf=9SLrmr(9wEe`?ZMxmIGfu1T%yHGmg zC?9VL%Ay#Gu1ft~z{Oc0u{hvfo&NB7JFqe&Q{he%o^q|ti~dOfS%(_pH`9k`l>JN8 zr}czR>?l5k+)mS7R~F-ts93BjVlhd{J+qiXVX^v~LKYi_FJiGleDo0ASnOXnS~w@I zKg36MS2aoou8q}moz-(?&wO;oowW5J#|B+mcsxN=<#k(7l@a50z8E%oH2JF0Q^EC+ z!1y|PaWyQnWF=K^k^RurTDPYvM&&1+dwWeucTMnP$YKP{P4EO{ z37Zk)Qh{Q#S@z0&yC6ZITyulbcp|{>mZH$&;`hx74EssND9d`opGwTXa%%D%=8?8+ zk<(*-+)a-2v}DEJ`Jmj|aSUUn$nO>8J3b=jG)K&MfbaMF`o#QdVK>B_$RHYH)tsgw z{g>y3HSodpRs&N3&g?1E{U;`Z{7M+zUA|XoA)Tr?ukxE!!hsPzCpmg_^!eSsJyb&X z^gO_dE{_e4g0D7E55G@^_3+MhRu89e2g9O0)kZ3K^9S(`yC&+e*L7FA+ucd)t2WOqopm{z zw^2rK$#mQ@N@g0X@U_X;Am6X$nu$jBkc~ z3#;)h!q*;*V!Y8`TdvABj01**A}d& zo09qi0<;HrdpH@qOa19@adjk-OdSGw)emz-Ab5+h+wCYYBKgWW#0sP0Unrkd&ROzV z<(w>^RnAd{r{Y_T2KmMqo_u>4o_sqPo+@Xkd{#M%(H?9mqWR<9D@Xoj&MA=t?b+}u z7qGc=%6xc+ZmGZapd<3#p)iBp;(cww>k4fPt`VR;NP0LKJbSG}4t1lfsU#I6+I=EH za4q)!QpCmkNis;{W8psg{f9|DycjDw-OX5K+SXDdEtT9ka>E@Oy_ZwGNRY*)0*CMA zD3u!p<{2)e#c3vlvq1LNK>vyam_GkkI+)S4ar$QSbiL^*6aK-C2%oy4d9xD7PCB1= z?cM zOqGS6dQr4OZm`NlUM9kxPnmYV>8=>H+(A`@COy?6A`5xpz=&hZ4x)yw6E#KSu|3f6=T%u6)^i^)hlT>tkQOvXLs(7i=`FTn+}~u;4pV?^y0RZvOBlRDTa`L2%`8vd1s^PMRm9zuY`RYkBV7*v#%jM&x0%i_iz@ofY!#47 zEdg=vj|l0Kh+Y7z2iINz6WN)4jQY&(>E|Byo%Cb#W{#k+)rj}Enjy^oVGH%CD}e}HiI>*{?1th>2l9brS5r3SST1V+bU}#*|zS- z_m+HzTdZZi3?0*?pJp*rR#4h98NYTIOR_m=N3V>{RnEymm>r}n$I~4a+Rb8~Io`3f zJU|kLnaX z)pNP_-%X2}o~PRHK(k#y1~f}A*J_R18z7b7(b#U{V(y~c^lilN7DIHy=g9@u_W3C& zocT)YOE>YPw)!EfnC>zweJoLo>GCW?&Ye4p8su&S5pw!M%KAd{+Rmn(Qd>>vA-Pm; zV#&GcKdG&@0zDNB%u90a9D=(ei(QezWjS;ud&KpnrI9%q^#}_U&8@+Gcrq7smv*dn znvTE*IEeG7bf$uf6g6F#Tj(Bh{iYPc@>nt5o5h12GUz%4h^W!%^Mo3!_a7G=m(@NcqM74uKgW#I!n+71lcl3U(B*_X#sqhK1-3C z{p*yb2?p=>5O0z#AEl_)$SVACmRW%`)y?j}4~kwCW5k*s#;VGTH6VB|JFXs=0Vq^a7E+|iiDBlr^ z4g4o{LAg0ZnIIG!{rB#I(iEZ$w^TGxS9U>}6ryY-6q^S=Wm*o&jcRZE5by8Wgk&sr zb*|a$W#Ol~t@BT=@+G}DFV-Dlto%A(62`h9FVH5Q}PmxICWMSYh*l@arTIwV~r1Et!GO&Dz@eIX>E_iE)Qd^ zh{v+LmgdD$vEOX*#lDFMd_T;0SZ;+c55s4=@N2q+|0E1Q#)Y3Bh7&i1KfBw9#GWgu zBdlUwqo3g0AePaxm6=3ZkG9yf&D6~xs&jDZ`#4(StAHnNo-~9?qGQWOM++)5St|{D zZQ)X)4D6Sow1JL+$lwg)XCRIjNgQXn$z}3uo6x&s7iSP@Cxgr^0#d3`OkT{L{6MZ#wWehqNAc37+Ox9SNZD(ABf9a4}S^I29%)2d;u zLC(Z8_?zysY8v`WfPvl-^{4i#e zLsS1QQJVHfb@_f5Y-g=)rQ70M0m2&Rr6dqPEm`JPt~*Ft`OKu1&m^sU;-wYZ#u`40 zt{TholxGSZ5fU4%xgMpzZhHxybN~5|DV>STT_}evQfm`(m!wwrm{juXCuMY0rpi*m ztDkL;66Jyum5TwM{9J&U6Cm48iDk6sQ|>o1=Fe@tP9*_1e(k$7C+BmivT~jFE-!U< za+hQyENK<_FzTyUTez?#_u(Aeng};~&9L@sns(l<0KO&t z1l;(4+O+eUP|wlDv@=S~gqG6?YL!WUa$@1^43iEx0;hv>UE=t&_M<;+}&0Yuq`w zzrkIOt99@WxY~1liG&v7I!g=ARGy42wA9=U6nhI!Irtmgp8@y|t_GyRxcB4Ui2DGp zvU?EsUEH7Jj>LTk_f}(1>De?ys%PL;&67c`)nB3XoAScsFY+9jaMyw>ot#{$N9A-( zK=0!dP$P5{>)S;|#VL@x!d=GTRF1A?&t)_8>Rb3Z!nGZ#D>Gu4J~GAidgH(BV~O`iyO~yJ|-U* zH-PR{s&`@~CIPTocHMJA<`P1^h1{4KOp5y8IkLycj;)?n=vWrTub?t9D7Sg-5U168 zVH#CxJl(hnIHIL4vkh4Cg;j`sFxNnttv!y?5e8~vRhb{qKWBE&4Y*(c-@2r}Nb%{!s4F^&Nq+>eKNJ$CiG+Rr}N)lRJ$&YWjbTi8E z$AUdBF)5{56bnVe_erb_QRRybhJVZ&$%mJ=pzmhw7u<50(rKKojTc?; z)8A4FGU@v;DxiKMs2El*4JZs=!>KUJRE%vA-X^@yJ>UXLj44b}tc9->i3 zKFvH_>Gw2zcN~>1Os~>88j5>NNPAXY3v<`(|M9}~g2ueUTs2P>9CD~}lDiw^W=qOc ztb(@oX4)Ls~XUBQsD!|_}{HtkX!XceqpT0J18FS5kIsu~F3AHK4Ha(|O9VSPr zH>hg(!#g_bZOD4Zdavfo@#bd{@XzVtBA}&a0zjt1!xV;lxVgconP?5#gIDD!AgGm3 zo2O+)$l|d;qs>#&o@i+sA(Oo~)%TehPC6@Iti66WUmeKJ=V%<+AJkan%nT|`De25N zcihzT&)?qHFu(AtJ5SPxGt`$^EO<1gsM%TFdhR&P;fbBtR9ZjG+D2G%7PZKa? zB&jaefz$_d#bPc?EPK5uQMe*;+KY+87iGQ4zMoacb19YgPt1PLs7q~q3&PMfHxIXk!iD3(gX0=8W{CGK8Nht2D?_9fSc9=DPbX5dti@OzbGBKh zXthQS?GF=qU6;tIS!&h|B8>bh1aSjoRz+m46PfFBHW^AEo25OMoQ&eTkZ$K?1Hsxw zF$IX5L$^cV2=zKNE2=*Gux zXlVh5F-rZnwogk#T))t6XVg^_FJZ*jYq0$a(!2N4I$sB(lf7JyDO1CEUicPK>~>J- zW)AdNI`Ug3(b$R8+j(*N?MrOg%h?Y`7>b2B5F%>huPmb*s#S$L1@IM0T?mgiY`KB7G6{&f!zaXMj*_U3CDG!N z*lI&b1dCK#A+tzvxBfg6W&4u$0Y2?aS^8u~7a%)(2oc=5q*bPDn?|#}@6HK)z&u93 zCQ-Sc$W^1RH4kmQs$JXoROi^5mF)tmX3su_w)2L1P`U-j@lD}vL;nMxct;Dk(qQGO zyL8eQU0OFGb_x5F?t*NauXhvrMMz2&>?4}oq5D-DjGV%3r9|@HsOOB@WSJCZ@0-Hx zeJRX7@FVY;;>~zEw&6}>Q+}z4ylARw&UxZMBK!gc@`v{}=aYA#_fiqY?{Ehj*TGNW zt`5!QOAA@8rH?35k8o*d0d8r9ePTDzQo+!vBMNpX02#DFV){O*A}~X0oGr~(ZmEz-;CtFeFX3e zmel*fV$n>u_8yu=1yA`VgQw579DQ_IsGDb5Cgw9#EWSvoItgm%3@zeNRE+LDb0Gcm zWGvhJ;#vvb1yu^u3VHxz$dKMPhMWiwQ=Lc4$&Mm6Lkf3V^V*AMaMvX`RAkIEnwam6 z8f26Ch#~V!I8~5e4GYmH`0Q2^|I>4nk0;#`d^s4IAu*g6gd-u%m*_+gQo*-Q$}Nbk z??r%Se!0y2YDmw2*Sht+Acd|DIX^@ad%6#gwX=F~$R~|a0W`SQ*h~$ z1HWTahT4%vUDmlidRc)xk&9Hu<%>j^N0&z--+|0%ZFd%^YD00QtZt%G94j;S`e}9#LpHcU08m4G^WlzoGBTT{6o{PY z_y{8SNH~`DCUL{Tb$UG7a?iKQUFgbxegdNo!KDmv$VE9KFn2n7ad4k@iPO=B+9oVP zHVq#A2}bpl23^CaqY=UnZ)G6DNRK(6KKc>4Lx8Ch0_=lMO2U2qaIY*69L|xZo*S$SV$V z0+0!L6_J{yilDPiDZTP;lG^|hymbPVIfc1t&y_PT?H03b)-00iK9!sX_aoU$vls%p zqs!zp$04p|{it>)5i&Btm0uK>x0+_Mns73Onpk>UD;;DGuN(?KK@SPMf2Q#xp%Y5) zu+X0oN^M$?!yTzw&1^{$nDAn;rm00og-Bpzp*1`^bM^jU=%4YAEMxcaRz=dDUr))X ziSv^wb_*0sX5%oKXj^W&hOLD5nn%{K1}h=?(V{MqDynf}EsLzeg7p1g&~xaq_HIXg zG?}%-8HflM9L*G~o&ts)R2>E{r3jPAIxKfvw+vyF(YMA2+-C;=FML%8F zQA^^&D{QLn32!u78b}v&*QpG+wJKW2pZKBf>tMH9MiJVn+N==Q0;rCx5Z6(z&5++= zNLfXw4J9W01gR#REOf!;Hj-PdWlkr+-q)?q-J-dclL^RZ4Hn#-HoH6Z6lM>4E;6yz z^#YoANIpWZrcJ`eD3mD?drr5mIb8(Zqn(A8tBF-tNbzuGwy4_ATmup4GldHz?hn)1 zg5OQ{%Moyfd2Qu!u%@jJSqddkEd1^?ckW_}O=ZbOdm*TL;OMGnw0@~+TqkGP+Xu09 zua!~s;Y;}0UY5~EB>1U2o1Yzy<7dY^_}OVR*kwPiy2#8-mA`qSVsCzO13{Jd^D}4> zKU?UzwJmSsr)o4mTlL{*@LBu}X#v|R7PmodhdWlT1hjOwyncrGbVC#g3C`JO-09!C-)C(Z*^xbur6o@(p$+OdNp_>}F;E zTywBZPXYZ2fDyiM>r}RCOu^oq9!=@SLcmzY_twu`S5N3{G4`K#Cvk<1_C~f%`IGS6 zKm9DtsG81L@2IyZjo>MKT$tjw&=!oW8?A+!pPr&u$1fou-_`9P0xu^};`-*P3gId7 zwOYmoXYl0{(x4UHaD+}E7b%g($UN65XwP_G&4&~aYu2v#>UWN3K+ZfAJ;3kr}qWH z;&c;s?gqkc&xSdEf_oC}4VvK{D{(4`%}7DTRFlPW_Tj862)8ne+umSvZQP#2|E;vT zu@+Js*NVK2{=^JS#H@u>T2067i<}*gaWEfW8RNNl3_Td!HAby#O@xZ2s?PM7>26H1 zs^>jK*9K5R8!$#DQm*;|gyt^1m5UgPy>b=erLg=FKAUZZJ#^U2lEMrJjKlf8Z2LRQ zDtxD7_AeOm{`)PIxY8eR=Kp_6|G!o1Ir%bw{7+b1IUa4Y=U+_A#0|l8!-4-pG_{}f ze~+eJzk;T46!RSzMV>4xXe+6k(SNTEgiVZx6)%>AxJ0A*(t@p-o|2|HIuPv+!bv~p z6w7H33gz(E9(;M6^R)$Q<>Ol7KRu*9_%QNyL|E^5tT!Xb`|`C17GO!P_CfC8%Q}t+ zENvA%$LXLzd+>}8#@m+lF8AKH;A#2Vf+cdO6!t50om`V^dMd^jTv{KIR=5RX7;cnr z3x>I9?Afuk))oxZXJ(Amv{j8J=r>O>)u8DW!TA_{LtzHXa*WJN7H#SdnGKn0D;RcS z|EOSV9mLZWd}#M{ja*4(NZ2;n0(%vh*2dQ{+ateKjCX?F`S>@MpPZ8?!mZ6~H)@ii z`jc@Z3ZncTqHnQc8Vmd_;E0zMB*&Xpd?bVZ_zCGHCmD>ekbh56$aeVKf~ovUpf2v% z!exH5(jdLPMHhb7$(tEs;P#eqIf2WiolM#)(umy1>DW`(u;n1l~I*ITN0#)p90p}^; zh2hJRE0RIIh)4xn%Si^~Exd}~WN;9_h`g>jFXE#xvm1r#;|kTs3Z)J3500@CaXUBo zD_)hTZ(DG%BB)}_yrRFI!JV}P&6f(UltYC3h`{Ila`^n6`+UxSKHxqdl%qTQt5r9Q zzs0s%beDwz>F~)da&=Ng$_sjh)8u>aLb?0_)nG{^nAFRO`7obX zA-CxOX*)GTS30>XlDqE9wug}JbVzn}Ua5yEg(?F>y38R}gq7so+76xR3zJVZ)NNZ( z%vov-SJ0ni39&FEs|oT!wWE023u*sMxLU@UJwE*m%q&wP^*o)zwH_#o7Ga&Vr$2ee zZ)S9C5k&2qZ5JZXC2~lLS6B57d*%Wr5{74Af6`_3YT7jngyS>Yg(U-LAqlbDr`Gez zsRw1SsAvKDsoY>Y(<{6}$G{y&vW*3bMuTK9??{b{**0TG6udZ@EF2(w9@t&*fI@OX z#|qXfq+oH}vtjl?`+4zWwbxETYwYl;4<(j-Y54Nws^+x=OTTv~32-#YS^(<@^U(rZ zT$Z-l@x#>SWK_rlV*$jsnc+ABv_o=UHq7f$&O6rnPs=#c=1`*wtA+B+Av&tn%$FVf zz#v(p>VE|QI$A+yQ~!YWl5tB4%JIk{BuO5KIKH`H&^nJQ#y{1 zl(y)+3x#@sKnai*N4UhG z%co(^JYxy)l_Jw~_^4dhVWjD3c*7YuNr0X0aSxwDlR0{UD@|BaiSZSu!8nP|pdhb> z-NBT7uEuL!5>ZW02y;DBL984ZBrV>*o_!*-ug~X?Tfcg zq+IG35Ug5sGKxJJV_oDhzq@K0&vTE`DFJu*T`Ks)K7VlCU| zrm+jRBNy?2&r=hZ3z^ZE5Md^R^AU+Wn(yY>FLh?VAK_?tyslq<9qOqw9VS?f6E`h9t=+wvFn@9lk0BsWc@v})erU#jbm+dc zMcJeuAs4OvBJ(i^{%-q%^p6CMOtQq9tcWdNg^I){wJIBltBUwSmA=DpOwF-@dnMYClAwAb3 z#@4z=cxyYfD~uT1a;TTh6``ZAi(P#=X+^Q`JlA5&n!S|rbsf56#E0xkXBF;Gd%>gz z)SmoS}8-#jwB`tX!oqi|_xJ}k4 zjXw-vV}A*@J1>09x6wW3JHsCHy-533-_@4Y#d^&55V7g0K;$DddQ$3T}IC~oLA_hK&4&kvG#_lCj$IcEU zzfZs&)rzMv#L{Rwl&Cp)vxpSO`y538E8}f*@sL;ING}>v?r|!Ob_+?&NAxpm<}$t? z034Of)rpsRl9rGg7!PR+e#Ht_2g58vOfV~3+@K`f!es4XCYT8)8C*pSSie3Q%*IC_ zyZ|S2JPQql>z0h%0@wNHoJUt8NEM(Uxna<+8ITZG)duyZ9R6};iTHYG0i%lSwKukf1+UNHZc2crwo5$jaNy~0cd zw+L<)&dQi18SdSo>&7jgNcZQc%xZp?tmJ3u3Vza?Yw#J9s%UnR8>7ez(X)A;Y}`5) z;Zz5Ailp?*$IwV(=~S?%Qb-1;LJ;R0l}>OHenR@Vkm(lE%R)| zBP9a!$2bz+nxXISCnz9YDbOF@vEG|=WoF54elr|q?e5APPLZ;2SIWrv3 z|K`n^R(D4Rsd4TK=N0KIomZr=FF?LhtlLJig*Zh99vrz%*cKf14Cy1&fG@?c=K`IfH zQ>=vRA;J;Afs>l`w6pZYPJnTOOMCj?tevg9M~`>p-klGnDjkX~S8u9xSHG@l4b$YE zb&)0Ac=~V8`8qfV5Ou&WiJN>Qfh9NVc|aHfm2q? zFH4aZyu7~+WPgx@hS^^`sh3dBf$f!D6UA=4Fx@~foD>-Ze;~;0r$wAfFv?Mg$WaDF z@^iP+Ht<@7yL0p#8#P4Hv5o9;U9mx~NHSI@L(J$E{5U_m81yMo}YIF+?62UGhg} zae_1T$iFr4;27xR$Zd^Dy-mry2;+%hlK|~F3eEJfq-yhlR(}khYBv3)OJ0nPtnUD! zc1uJ8x!$Q|hr?z5w*rnO?md7AmHt z15&eKHm4sBuQc_+!BoG$y>vI>9LVE^(PB$jQYjgbP+jIoe0r+Aq_F{C2_rBcb!Mr) z&UZFD7%*zFh9KWH`W>jQ0UekmV?di$2+?jO6s?&^rQC7M?dom2=rT(gf+>j1?%zJ7ftv{@)PQQ8a)-dbMJ!il~2tr(ycpPCvE!8E!$_$2t#~^@^fHdQ_6? zh`kwKD{Co`tJbq$aMjA;1kQFw2(N%Z3Zs=m=yu%YDla^6Wpz^@7r{R|z|~Ft;*E&6 zWaGY$Nk&j*Qo^51d{v!J7;c1|Hs{b7pbvxea2NV`L$R2`j7KtFHEg0UTTLov35dhO zWcu>4UHH+Dk6NntlEvFINf8A(r3@OPzR~v-g)k8eOFq^7#(w5owss@XwvEtUfLm${ znjod`t{!{42zxt+yG<>cpj01VdGWR7SJkUq~a_kj_Y@MYR6#s({<;VA zPQU8C{?z4;x7~#9ovGsJOcrx*yld^&#R32106Xh&JQc-sQ-bMh>&0~bhACgmI`1-vGlO9r>{=*Zz zd#)GnCx^ssg=0*1l($F-6vz9R16Ru@trzdl61>GReLump%X%>#nP8%ZZV9rNR&ST! ztX(h8FAt7e&7@T$A>redenfPIU4rso2P~iWBr@Cysc6b^Qh!(d#gE(D&m6*Ot$!ZBPV=!kOP^poJ^Ik{hlJ;O^R@eOGeS-N?DysfgYM4 zjZUT>SRxhK+b16)Gib=R7wR$eb8YXhYUXE)z4+Pk7=DKRke}g8`5Cd6pRFF_XXIhp zoNp5oPe(Hr_;R;NzqA=M|FGD#neR?CD?gqHwc@}A@#bc!R%Nc^b~;L^t{}kErZBl# zSQDFPns$PAUD21}wI@Oke z0)fjW<%ZIndiKnUcd%gU-BFSUuudn%YVkNM1Tx5qpW3bKaZ&|MwNum!Xs7Q|+tly? zvdh!0yhVG`^K)p=lcpA~zVN&DcYw*oS1Z06LzL4&9l&9`sdjw{@iv~s@ieEplabvT zTrd&UpAEjN2Xj$xaLcPp?6Jh+ei$Ebaa&;0CD_-+gLo>naC7kcEQx}Wk(V7&B|ywU z8o9CG)X@r@=w6cB64FggNH^6l;=YFQ2OA#5SH>7-FLF(O}%DzuCvz5@q13uis zofWoK#|yKStEy>F@Jk>u2fsxDWdLD#Z4qu`fS6{xxj><5wrR@0Tctf4W5SP)P*u38 zqn~BTAG;uB`RuOIaz1i?TUBfg4(5>!wpB%g0~D1FHnEhh@QRc#`CFaAdCHh7@_x2B z=8ni#zPq*MTFJw;^;PoC4-NnvWJ{F_Z)kJq{9tDyY2p|j)J9jJkFcQKZ%#;u^fu-> zKPdT{Wxvz12hZV!;C=!X5&V@fh-bN!CoSbvOL?4dG?6r=G2KSJq!c6a|II{z7gSONOb^}MH9y=%=@L%z$)HSIb#g0mShH6q@o{@rMSL&a3 zrsLLoRO%)m7$HTEO3fmTQQPyV)G@s!97sZEP|vUNG0)VNmi!Y_S1px9lI%r#Zs^3+ zu9IZG2)H%)=T0!3otRop$f@WcQYq85ul7me;o*&7#oGu*=buQqCrP6>;je?YN);$z}`CrMPwF zpM;IV_|v)z!TZIdu;9#F#%4OY**W<_dvPqlLOR?UkW!JovX0i3+!cbDrubc}%y z-yWYZ9E^ec&3zlVABN7dw#*K!X8u5^ZvnM4C>+k*~WOUe||4;o2y?fOSg3^$T1nVv4MK?p?Gx z`vcI`n%N3Oqx)7Z9rCUU*>Jxm6@d}iM@D2zjcOBv&D9xoS6M1|5lQ;%-k+Rc(!0DW zTw2b8Bp2u{UDdaTj!WU0vV$S@}cwatHEF zXzfz!6K=vFo*&Fbk#`0c^IOtA(bc+G8_7{pA5_y$Lj6>Uk9VMYt&gT_{0~JT(B^fk z@KjSCH`t}U&@Y8|!F0QSRxDB9`e(DMUkfjUF!EWO+u|ncg8x~|hcLugOLm_iio0?C ze03vg^UZO(E~9Y}!IcE(2Yq%lWAT$6EPf*KA;I~2Q2v>Qz*}n)xwwDU z3FSTO37Alp8O8UM-MhTR!t^x#vP7Y_MPRTvQ#)bfSWfgB$Us6!a(!)ic!tXpsb*wi zL{ghiD}us(_$vr^XZ_zING_FqQjN`^=N5XVrof2!YLH3c4A--;nO{zJ&E)<)AT`ph znO~+{xN7EbM3FVKTH;^L9PXNFS*#83(1xPTTrehT=C*`r<~aE=FeI47P0-K8okcJt zeplGKE7h61rjO0!8jrB}Hc>-~vz3VY&pI+VmA*qh%=9!2A5riQ!9Zn|P^`_`yE{Nh zk(0PR`@v?_esXpByhTJxLDz~-?VIuw4&IRxsc~(2J2lphg|2YSLyEILuJ!wfYCG#T z!Z-!4v#vA~!+MykJNu>L|4F;28QtMx|on6}+=c^uuL~V3a;$HwCMbY(Y zPveeEZ6{ge|7#8H7a)o;8P0x)!Xe7QB}g*%%r`2 znNstG;Gde=tWIDzf!cHxok~XY>x<0$>*kaxI@?6nl~zH4-J^W5AFvVrr5*ccnlQM267c*_t+I7A~x&FFBW4sEOqyi@4FB#`Aexav~RHZSy92VEqlg`!g zQbx%so0&C#zPj67H?F(4H3>>oyEH+#5Bp<%PuKgNu8(?}K&kasJ(O570Pwb3z2bOv zdl6K35mCjw&UpZ9ivf$X0b|h2db5z`POiz6xBLMdRP7^)lV(xp7_93w3C)3DEMEDFBkoL}K?~muq;zz!)*n21d4& z(tBXcHmmi!FEySjZ}~H&7Xw4QNZ-++vq&y1;g4A98c1DrHW?@a@sk*0h#FV~;=&lh z8k0MFJ=Ne~&|yVTOe#Pzmhm-QTtg2<|6gc zcxC}*;_+}l@c|UK*^dI&VUAb3!htZijWl*Ep@*;y&G~z64bkqM!#v0-@|l~tdsEkC zZ0^pt5)&)Ocl4W%YCQm5{~`PrIVMT)%96-xdanB|EeOeC?V$Asqh`mH`yulL)CQLDiT#O-H0hA8;J#5iWb8H>csO>dra};{5UrlK7m*NMG{$ zVD;K{;l{KXfGYu@Fuu(VNwkw??A%o)?k*GUZW@wlqLH`MFz@8gtmEz#geaVf1yhAS zuY7jR;9F+%WfOUn^B z7_8b=_ebJ*EY@Qo{3OoC3-^{dX05T*8fD4p8#ik-MeYk<>$74dq$3K}NO-S-Z{Kpe zvR0~DYu&P9m)~LsD&x;0LOEhko+fQOgOgRs_6!-qvA-4fA>(AVs9R1UE#W<}hy>UY z0mrQO-j-s$e)jbto7aAA4+o~f$jJA`fakZUFKxJUja^-zD(l2jrJIFACO*2`Up-sV znfbbV)|Hs(OqiDbk}TG|20))1@sY}Hk#=NPPqeqr`)f5mwHBSC>xALZ z^@_cXuKfWhr0Z@%gSfcN9LF+7!}{Og-2J86_qOV(hA8@LioQkB&scQu&^0}%UoGfr zM}1vvS%CS&J0i^4H0GBSEzG$KA#a)A@7cErZ#CSF^@x%i(moh~@G3yfj1t?k|JX)o zTt%f?&*ZoP*ky$t)k~Ds^Vv4TeBY=^Ckmc4ncQw!z0Pa^B+(F-15n7i@g9B{Z9oKU zaeyZsXHp71qTHS-^wPbIzH?mj`mY_=j1~YJ5dFgOEdZ#>qw~4uj-jeqaPp7Fx|_n| zQFFB=03Wl{3%f)ZK$U5W_+;d+K00A1TX`6r&rX-^CNQiI>fo>OqhYGicm_7Iia=N0 zU}GYMrGr`x=13cWqlxuLK0GRV@jDrTQ#4`49H#tGj z1V|x6mWsM!2582fV4NSp;lgCYyr8;{(c&D=T4>yyO4icvLnsviJA=iTXP9F>=Mb8n z#|rBTXWp*fr&77Ws-VS9wKz(LBixF{tb`+;n1To>odQ$zn-3k>np!62s0Q5JD*0TZ zBx4f=>IB1cs(&{4=QKT~^rpMVaRxO*v8vNKoe?ixcbns-YBjPtmOwhhFTm=2UYaq) zad~yjGQXVY0VT%J<}y~*XwNE$0xy(+p!9Ny^%`8|LF>GyX!zK|D_}_S>wySQa`X(Fv9$0LW zA$jmyYGp$o?P(l?Nab)N0IkbbyeBkOZVoXRx1-m_6fl$tW;S@I1^zZ|c^X*baeu>L z69^5&Nvyjr_5db5U-E?{W`n6JcvQNEV8G&~Dl1+IpJje4#v=@2&Z+~qFlQCBonRP2{SmD4!LDFv z9IEi4&R~#2oxw(Wv{h?WkWrcme?Zqm`7#DDhZ#2M48p3&D#?}8*0R>%3t|>q8FT&D zZBkWPLL&1rRb?ST1M3PF_+VF%jYIQ%s57`+q0ZnkJzQ0kE&LppQeIU~1i%?cQB}?* zCa)^UMLigsj0ihq?FecO)e8_K! z(~}P`aR;qW;>-e&*aY0*xOw5ges|p0h5%OY0 zk+(G+5JmQhBUd+Z1VLHncJz%S%bSK-S<(}=RIf9rRejyE#kS4b)5q}Je3-lOx+R7! z12&?Xt)@;ls>wk_PoitgU%k0hL6u&34%ai*BT#O|P*IL`Dl}(ju#C47?quTu4JyxT zWlQBldBf=nk}#1t-bn`XUv2rDzRgHGi(s~)e>S*~0Nb&4>I}{$WI`LmMkRwZx_`Sf zn65-O`>Zv+UD-$FJ(rZ%6-)z0{A|ta-W0HGWfgJAvCs6e;PMt73K0hosZBCpS|LFx zuU1WF%n}o8DtVvV(cctOSMW5i`hy~q{Igci+4tR&&WLKIktO|@Q!s0+wNUtS!F0bDPyuL<95y@1#5$LuwDKv?16=rn&pp+9g?R|`t^Ofb*j`$RYTxpZwa%?95mNj&EEYHN>cYjC*b zuiSnfBz`p++HA@r!OJ)%4wd}{kQ)2Oez|Q(>1P-)hM`8ba_y#3Bj}N#O49Ayga;7T zmNJ5$1Eb3zgTDzFh0QHO!P|t<5s2Dg8NqDBCfVR=0!S+Fjl_NQ77?+$ad+*K^=_AS zV}if5plxxPO;E_0tW=((Fg>}3Iy$+{vWs4w*t5puX?rug+L33O@a2!v`Z1~txzW+n z!E2dmrMvqC-rrbq%WMXRB@mYD@~~*-aAS=Pa161!1y5H{MF!D}KS{KPLz#~aUS|_r z9=7~CJqDuuI)MQ9lxdrCXHvE!3o>De!%~V7!r4L9sa$m`Z4H`L8SYQ;b=r?QNiVw3 z;>AlH=zlsLZx#hqseo8>5iw2?PN%`vI;M>Dh%?^!a|RYO9f(@Onsp6nCyxKh!^U*k{A(AG|eb-$gZ4OQxsv(s)Ji z%u}Y;?$| z2r#ctPmH3IKD7yHb$*|=8ArI;Ap0SmTb?;B#sPggzyjWZLEI#|VYs^$Wwh_*(Oq?0 znm0mOtd}nyW_K>-ADwOP(ZKqyjN>pMVxzshNiNaCGWk#wCDx zf5g_=;Hi&|8zwO=8NOgRa>!N+(5$VUt*@ z{??Bj52e;{wge!tO$H&<)m1E+P`HUr$--OuI%d%tjuQaylE(mLDME5am0l}6lSB;Q zT-0)1Ofa9crF+*!MdZ4`g>Alc9M;ZtQJS#Yq__~{C6|BU1Vp(N7oqUwE>|Q6jndqg zcrS_+?u5alC`YyOSL5Gt&$<#eUK64E%VvAFk-j#cK*J>|pTOKcqE0ZGIL|~f)13?b zp#DttZ!&oo3%Apn}YlvXLHgOCnYo5TsOBd?BI?@iyawh_$ZJ(~0c7o`x( zRy3zu?weql(Ze#7dm}hV8M2jiJhB6+@r=~8qb_@tu3*C&%FmvqTES3q*nD9S0S4ua zcu>x8bA)WPG=}?ud#6jCy(rRt$opS;k0`L3imnlbx`IcDwh))=>6tr=vcE{GzSKkZykFzi1<}@mX_RFxIFtY__`+K7A!6kV*Mb)8i8X9>%2tj6 zf_tFf$Caij(w4mDutNv)L}IRK4N48555H>cKL;3F=-w{FiURSti^XRxJpBAwA>J6Y8T6eqb7@zstyIU155?YMI|JT^{qr{{v0C1AF3j@cd{51TWWzE`HL zGn?19_N&?VVGV(OTbDm9gJKCsL7X6IS9G`wS5{H?DwveTyS$AKw(`UBFXfcTih8Ws z{Qd4oNH#c{c-mLq@+nf8w$un8B;H#;`-u2o6NGQ|c;2^8YD|&x`qU{;Hdx&c9{_Ju zqApWDuZoI7%lC+tljL$>$o(d-R^ETy`*V8t*!7jXI-*q%C#*!%l(1?@(KH?HXj*5I zhcYe$rypj})Qg}8y0360?oKM~!F}-x1bgtST2s}%3DWJSfMPO1b^A96k5|}Nab~KD zXQ`_8>AAC#Zl9UdyAEDt28baloj#1*X&HAt$R^{u5eb?&o*<1L&?#a{^?V0?nb2Yc^_y~6mbSS8Q4@A zQ&dK=rh5hUezV(q?r(Y3y)LC%rpT1H+)Y!m!AKBjlW{PVKx}TRO{Lr&R({2w=nvc; z*?y1TJLKTZx>dF}&Uu_(_a3L2Uw*l+`?tWQ(%$xIQ@ zpH`-{>G?Q6_Gzm*DAYYUKkeT>?RlkD$7z^~nYRDi@38Q?%>q=n$A^L8lGRFFZCzN1Ukyp5nfll-Z_mGecMrG*vH9`3m zw~@(pac!k_akld3=V5^gqZVrRB->(OGV7kr&BoqpPA5)JC7wj$sp-U~RN{Ul9+*zN zCY6Y$s~nR~Orh-xE?mcKj6altx$tZ47USVas{=?e>AVqLj(D)kns#Q#EkP|N5w&w^ zPEHj?POI5jDZ_O!;`TPCoszP~wXV>KG5(x}y7qM&-J@Ad8Qno_<3NR$5^B0A{57A> zVG;XrmU8c8@a8ak2h} zG#k?2O{*Mrtg?~*){@!i*5Ju6$HuNNw}%6fOQUdvuth{)@?xC;80)wD={IU;o)2nt zxH|C&>D@C0;gwh&@5l4*btJ-k5_uZv3+b2|-Wzx}I0dC$E)9`_noI>JI|VgK3Tj%U zpr-rG(;(ts<~ap5U2=80DX0=kOB9r@*(GzW@^rt>4=*$I!t*q*pl0cv%1>0JXy;r<)E(H_bvfokq54 z(g)MU#}kX{rWgKU{d1OhV`8kEsKZ&AMs4dot2Nl>3kYmjAi+C)rrJh9t{x3kD-BeO z2Abp-1Il2k7ga1Jm|>`PojCHdB_`4tJeD&ISVnW}lpWeKszI59{ z7n47Kyr>8XjsJNOQ;QTan(c2a%!$kA@s!zi7=;Z}d)(vz$vZ4H2#rDyV+i%Iqd$1X zTHp?GMdL7DJ4aY{1^@LQFFd<~PkgW|__q&r2LDuu#b5V$$35QEgS>a@$zNA+hYztu zw3{H07xmD<#+}by$l1y#i4c=;pgddI;a_yWad4MFyMkMJIBdW0A@h1xci@M2#`~^VTS0$K; zTBfMJLt|F!3Wnq%pJ>Q&{88EUIn%DYOxzSa`d?~y@Q5DHnf5rrgs0v@cfcQVrrk(F z>`XiKLnB*@@_9A)m7QrHeQbH_$(wej)$$%Y({@N9uA|w1nI&N6$ryCiN$W|ukCgTU zk|>6rO=i3G>36?%8}Zanx;8b5t&^_es!}b_c};bU)oa8|5Ej5P4?e8?K{^(c-j8E{ChlJR;+46E5-8mph1%aOSD zU+TolPkHq2NVM6ykuaX5m(P2Jxml#{W}3SDD*Kp^WdEyMl{?}RCzGO`Hhv%Tk3AE* z<*b-#hQ9A4QL+{{V`C?Y3KrRJkD_7X^{mD9=U9NGmpqbaOn;n$m;8OqC!H?x6zpR@ zgK;0~3?ua08-T*GU1T3~^K7h)U&1fle}J_lKv@~<3cs!BTNM3siw-{eCgt_M+ExVf zb}{DT(wNI*%=;6K`NLM`jrHhTK5wJ}R^Crp?JvblqH7-)sdy@fM+}Rl119RuOK(on z-I0&Z_I{hk@&p7YMF82lKI9&mm$+Y&s7p~N=OvCx5(koaY+hn%lDG+p7o-#W6>Q7? z^!wtgWz5^LxqEEOR_X?}WoJL|tfn675E6JQ%oc7^ZeN_i!f;;WFqA`glWPX+MP1dyng6}53y+%2iS zcE|Ln!rcNMod73Q__0zNQYmp2?95eZ*!2(H3m!~+K_j3;3!%C~=ARcs{<-dZouh5G z%9?YqImn#F01w(V-NM#=IX~hzoL7k4c(A{S3&f(^>I4AR@8Vu?fbedn?HnKdutjTy zSxEedk4CdC!d1BC+9*RgZUVuwFHbvgUB1Z19&P*M+^&ngW%rwj<0|aexlfnO=)JV6 z&Sq^nED2vmIEIHsqKuP+iq^E;cqup1WQrj0qnq!Hpxu#3wduaEk?g^clR$Yj z8n{?94u1fm_e$y1fEv7H8>5-cs~*79Vv(J7BRC7^AA8&(~x8nf!j)QH8oOqRcm@?Thay8{kS0Mv1*lAUBDlxzc_L^ z`x9rnWugvLsO`>y_}0^-LBOVKBcs9`I)J5_ICa)l;5XI`YC-*`5nmwJZPEQmJWb*A zjJNPWs{~*)t|H-qajGg8hmQn9g^E}(ypMv;l!R0`TRAGQB4P-Cu2lOQ%G?J1P1LyH zk&~PT(h?merUcBYXv6d(m)2itT02?DJF-zwn`oHWs%qmHI{tR0aIc^NER6tc!}NEP zE~IOm1Y+`2MxD!AmoHt_r(}7F?k#kJt#M--Q3j{9ybF^F9@sC4`=T|tkCnL8>+O2w zK>Pc(u1&62HQBT7tx|xLYCY9#B+L?>=5rJ7bJ)xru6y%KF7?0=3o}iH=7h4vr!x!8 zi7xV~>o6z8lvFp`0^rSwbIGjeWBks5s>Gb2^PSzml8>_+j7=f?Nra|7PtY&binV+4`u=y<0_Rw;no+I_YQMX$+3{KrP zwd**0ts8@?v~a9Ex9Ur-_6QCEzxW~8lYm(Kt#j${u3)sq8{JFu&cTXxLUHjLh1PUs zjyQ0?Ddi7U4pV-`xE&1y7#DAOLAi#_BmD>a^sc&12E!J_jlyDkuLmOWx5xp;Rk2Bo73-oGP(2B8mmlMCWqzVU;1To z$Hp&1GP$Yo3wid5U#4Vo6XF+ASSaua2H9sG{L8SCoIC%jO6mN!H-viZHj>5D&sjWJ zKSOGCP;)M;3evRIX8H8e557mpl%o4(*fx&tYqpB$jsaHRU#PuSKs78FVj9x+Jar%H z?ICBV0k`yxzLBKRj;8LhJpsVrM2P|DJIlU>4V2Wcrley*nUs8{^)ILEY9F_^&K38H zB)cO=UbRX(N|xuDa8wXwadN<^W3w--*0%v} zuKymBT@h*CR@oOEr{mYm4&>w>Z%IzJ_mgq)tFxSO5&2KOui`S_AI|d^PhU1SXAr|C zj=7iXd{sqvKT#b0S@GyIuo{uiZ+>0UvcRwS86MeCQ+fcF0T5|_)+2)7`**Z?e3-7< zij|oE@=V?A6rB2|nq?ZcTkCzY8iqQHaTcw2UifTqy2Ir?C{Q$*rs|jp;tAaqj-sLH z1?Pir9Mc(W56u|xm7{@mJ;Eo70cc%@`fu-$#kM;Q@MV^2!q6FfLXAvHl&YHFpqh(i z<>ew}&=u}S95r}$nzgqdHqOm&Br9z;Q)2IAa3zsk>CqH~TQgT8;(J6O<4PZ0tfF-a zU_NE(d6}M4lI@zdhEv)oK!Du;kjTT%;MXFSTR{d4$JLIspceN}Dy~#!(nHC8O@QQY6MPJ&b7+vj+gGo1)8437c6nhIOpna z0+By+60amxyOq3TStc8t0T>-s-txSNoDGgs`I)_Rfkk=CV=itxnL3OO98hw2l(*bv z@m^fc4Pj!I1sN(|9;wcV#OOmE^`u3DtTY;sxs&{4@hBV46vlq!Ow$%lrbvLvsyFU@ z`tNLgFk7M2z;L$Mbqb}%vH~-Py&W(uc$StLb*SX<61%{$={onhsn|AvznG^+HA%SI zPt4%@(^nbSw+ul$w;R)JEp{Q4BfGY<`N{0vrigQu^|l*0+5NuhFp@Pf*da%$XpqS=$L^$ zb5ki`QUNPpZ}Ss&Cz3XV1B7E0nc`T`r--{bQk2+pSsd|L<4UxrF;Hrx*k4s zH%4VH)9UID`e+!t&2;}?`MiC_e0eR)6tt|uw`@;qS%q2_jk2?lm9%U!O^=_}vdIN4 zd*p2!q}H;Ebju0>uXTX5OxtVidryEQEjv}|U%h3y0SjY}a-00?jibEA)xa{9%Rt)b zAAVrn5C6begLsEPcIRz2`21BoO89kyHwZ*SBw0NW0lH9fMKjF?u;OaVD<4XxjKSFmh?~(M?POik@Y-L72>X8WR0hTvtAU3i)2JPt}hac_* zxSs)!d&yMAVWi>=;)qSd%=12Ws$HoRRojAdN}vk;YToKEGcTZOVZz^zDFBqfTW-9ngGP=Ug5bKb<7C}>+k*P3)_RCcGa;gb(0L@gW zrFcw*YAMxC$m7eFsleue(JoW4>SfoIF|H|3^Qu2@N2NTE=JE;7{)>5cpVru zZM^YF*6~UyvWe4v6J4CmIuN16Yz@Ni_!1vF#fW!&UWw)otnwS85uEjpE>;6%Xj}-D z_56;WGC07sjmLGS!&UBabp@3^)ENv`$Se|lNv%QBQ&L!Gw>w)n-KrjFsj1S_1x-H_ zOntw%TCc6I)wizrr2a0aKbkf#(U#f9?PeUj;!9ob$5wNlGFQF2hr6PC z&)di6eQ|j@uNvLG3j1cg<@WP=f0~z<`9!As)(z$D@AIDM@*WDctEsUnO_>T7Z)=oq zJIhx-Z%<*oF2UwtM`2z5aB zySRjWWBOTRMiZ-Ur7;Q?Z_MT%;SUXA`Mg`e;u@nd)O`)F>!t2+pMPq8g($cC8ym_y z%IB@f&kIY~hZE@!^$b{41&wN&;D^uhC5mnv?J+#_w8-JiB0rF{4Y2z;>apJH@8l6I zFa*&c%+!(hh7IMd^?8rX&)ZDi<2RId51+R(KQA=z9!XwJSSq4M-zdFM{$RyojUvQd z?XvQD{h>xG9jDm>S@rmokx?BWMMjMS1_7tL=5=Gb2&j$aEtrMKz5|I;K-XVS=~pp% z=Syn}Vs^i5aDEI2(Iqj3Ff-TX7Gh!HDs~lT_b@lzhB!5#@|L482>`LqqaFG6oKL?~ zom$nxgrE2oXhpR3Lsik1{%oAc2Dd*yRyQX0<7ocR2zCay@>|mVFIW`#-sR-pp3Hau z#fFQ9_+*gtPx%xqJ}RPo7g)aXd07gIs));WwqA>NkurXjE*kNaHNB1+K+%I#Cr>8V zMfyC0b&&%3U6hV-U6hLPT_l9+BBcnio^+9lOS;H_%3JOs(wB`&E$E`RT|K7)6ScoW z(28g)b6s>QDjPq+bJj%_bWw(2XHdd#Nw@hJi;}7?B2_%<)_dM5KJU#1dFwLWzi}+ld)|7V_f(e`>n*gwXB=CQkq;>C zw%&}#`ivhxVJ+nv3s+*MPi!vnIRjZ?I0LZ5*4VyJ**t5q8C-4H@q76aNUq8thZCV!d}Kiy~eO!c6xZ)6gE3u9Qln`Z6EY&c#sG#i({oqtZ=OX;h!*qnc0* z)xXh-u2wlywZ2xezSF2a%}1r#bdLt!8KYX1Mx{wa8r4Vns5Fi3fl7Mb)#~eMRMiEj zUdu-{q!_9pF{*)SRCNWY+VfHEUkufg=tWnnc0#_=qnZKDL)QGpW%9X*Pg|Yy@8T+&0HyU>3DvW%$)*c1^hLo7_#eP zWZ5(_?2rOv1spb}7_#~p+1_bnSR)0<3V3XfV#q#6eY$3TOek((DTTi{X2Pk?898ETM#c=BUi4AO3-)6QJMdV)%X- zk34Y zE~V_zzcki!`I)#49O#UrPoMMWOxy(9LpC~gki{3AN2^mevo_W`1&=w|S;6h7(nkiW znrsn*D%zI|8m)$a@M(ky*1c)7SABM{-wa3)YFX4#K)PLlwsC1nn-jkdY92hkTeA4e z{j}^cV_9_E6V8)7I$Hm2(uMxRxuRE_H+JaOB2;Iv^^-UkEsI>a)`0|HrTvZ`&^v;Gw`nZGp-Dr~NV|e)i#QPA5BsL6;-$lSl9=DYlsc)cq>x7Q*=9#Ye8y zf#Jt3w%qSdkfxbpQ#NTx~t!A_N747P@@W4MBLALiLJ+$=8bu2~= zDOs5Nolp#Ftk+{;;}ktg8wVKPrUle{NT#usTN%)&je-{@y1IW8 zjNK=qGE_@<@OdNZA8yKBQE`;2^E;(ExVlBq&?Sa_tjb@mph+m_{0LE74mmt ze_>&5&dLUNKFR_eqmR_dt+w7W9%j@VzMnV`OljR+pXKvIZr}SBkHAOY`G+0f=2I7} zpRjpjCfKxc()gGylnq!c!4h3MqwjR^Q7@CFty}|~V+>TjF@dh7IIUDLIBa>l1kw4{ zsF(quc|R??!XW*aw(G+(Zb!2d%f&~7;gk?T`mkN{Mb`so-Gg<32BoCzW(X0eV1jmffuMyR+*0MGEzgL7ZT(y;w=(99=5)mrcg;E@ z!xdGpg6ok~!Q54ADb4oOpzAlfM^LHo)|XX{LEBoIhN@=EzScYW5e+JLilCGs;%w7+%gJ=fmD<=& zC|oF~Q?}1AKz{Zox82E4@#GwKr+xo@KqRW2i17fMB{HVeD@F11BY%KJ9H1FkG^HzC z4hoZ*CdfO3ot7b$jo3+efXD{?8@*%s-rx-e(Ru$5AKAn<*4yr!<7Dn7rY;-B5!rMWzQQ68zx1`zd%l z!Mo10;B`qW3<7+%&3`O1RzD~j`5KC z?%zW<+5!>u*A*P=L+UPV2|*bB{nzv!J%%2re1pTIB9UBR$Pg^*Ib zzKN`>`_T1fw_9Nwi{Yc4UoDm7*OE@dk~%V)si+#=6a$*+&SeC~|+C zQn&bPG_vMAwu&104RqpM+B=*WG0}CmB}~*x7$({S)2}!a&9OX{B|Bhs!D`Yq*YB2Z@W&eIvjOeOlqQ+=8qc2|-x>U!r%m)r+o~rx znKfg6)YWtS!LUR?dDeBNb@ng%DlvcI&j>;D>wo1a#7@P^D+xoPi@~2yq3F2e!0=_V z8mS|D%{2=|hounh>kv)o713@KQ$s59eS1f-m4A*Z_R0y;+Lb>aP0yb;CgCyF+Dg^N z;0<^EpMIHi{e6Tf@t2PjHmphW6%K`@`iZUR?ptw;5zhD7Jho!W(Nm^jsFcZ8X7Irc zd_5@q&LQ?;=Q3h+(60a9Qukb^-UILe59n@!J_yV<&C9tt7rS~Gw2Tpa8m4)>biFkL z!oN)C#pYZ@3}LQT=I+qPIB_$ds0$DZ?sl^ap_&B1ubCElIoG(UBXjmieYfI{KT7L) zRvGPB1>`>aY@dBrD!X}QItCKkYpaw6^x>OEDLFjY)5eEg*HaEC8$4Qt9`ID7^6^UU}=nzVZ2V>w=)>Z(~ps6 zKSpYG$5K~t%c8NFcW3XH;$rFa4&hC7`UaHs2K5Ds_7AEme@_2s#J6R3aQ*W8yS-Xc zCk4MV6)SLR*VorBoB>_D(dO3aOyJMdG-57Wxo<#sH8N&{y?^4^e2Z|3%V9cyV^A%= zd2HtAm+Y4bf76wqQo_w7{8b5eT0+xC;U6u)D3{{$rWW|Q&^X|@*orrrX^-I6*o z#jd2qY>1u8wh7JkXw}#}ID~{e8;^F~NG0^A_(c|S z;X8bo=trVxFMVl!kv8A5SPI1qhvERu4#3$5*3KI>-&x>nH}A7L8V*XLy25QS_%Yg4 z1&lVUNz)*@^4C9i43Ybuk1nz3g+$MU9df7m=)M;HJ)*@WxkG()KZ`zvXz@dCl8+87 z`cR_94Y?6f^rceYE4M+2m%{dHJeT)j%P1sU#*rhjW#-9Ni+X$>MuR_nI_I$ta`^Rr zL-VMq{V(jm+;|OI1Yn^@5)o^j$=p%MHT%r50@ zjjdUkRy;(|@>^Xmt>~%G2_2g#Yq%DoALGz#!p4a1c_!&UntaEyXa>&dh%nVDTORE@ z{YIyKWj#+NOv7LOeUF9@u-v(FN5$v488|{Ghr(AeW>??f%F#ULEy9%3)T5kY^O%Tm z``k{8r08UFTy4^2(4Hee>f-!7W+h~{s;%?$nCt$~>pZ4}@@=}+74#u^+8krNb@z?U zyy}8q5Pacs@nAqYpDR2)PZrHtpUC@4|r@096LU3L8Z#iu9=r#mvG}y@iBzb0~K!Ni>BLjqOrR>6il#o-!@mbFaK9({tmID6Mi?=o2}^+{{UnArD># zxR7|8)FczU;JZY;yM&e4#3CGpzrQ7kX>+ZsSN{=tZ#wJ=zF3*IIl%`s}NDY387-YvL;pZ+;zNDJy zwgyPmUWc3wCocL@--#{H*lKP0y2fp^@Kes^v`TI}CjzwUhL8V(bFAB|Fz33bBermW zm*fN91R%We_E7poh%EcMXDMlu=z!%+G-))3t0EymH<+I#+;l%uBViDIPW@Wy4)^Wm zNTj_Y!QA=K#$PJf6)qen5fTg)0N>T~a0A@ka?``jAwqeZmhS%bqsY5B1)Qxx%WpaG z7F^0N(q}6e)@uKUy#I-J{3$48V14%7Nm`G8U(2#9S@PD+nyhQ!X?F%jMpNdyoxw3?jiB6ztAK1T2_1UrML3Gq;x;);8a^nn&YqS2Jb$2rTZ5?o6NgKLLgaSaUj>7Uo3EM>=| za<<1Lo9i5h>GeAcYZZ;keEa-y;N%#FhMfd2xYB6&D8Z{;u!G=p1UrK#3Gq;xX!u8- zvd20G`o`x5lmnZ9?-U{ zI94Y(+HqH9!k_#mwteS3CTh6#6C`1>QHSweMGEG`Dt}(sUb@1MuBWO*4&=S<`J2uH zqAUFVO%|!(`6z}Zo090i&xvOjNi*co3$!#dgm^?oU`zd6Kd|6(>F$Pjj@_$Bq5J0ah!pXA-bx8mIj_)x@{G!4$K7Ws*pI zso+yJvV99Q=j=O>oYAsOb?iumR>_s(x$j}#A-@wp%r9?Kf6`Jv%Zoa_65>R&Jncdo zR#KRARzc3Ft6!#f^K-g}&xi}|3WqCiJh_{NN`eK4aYKJNf}0I!1?o9}_8YF;Dz;e4 zTi#Qbs)yP~?Q(D?90hlICsKLKGuCm)Cq#d6e>n>|L_{6aEu*BcCBL|}I1M&UwS-#` zg|eh8m9O>rO-6WP+B8UAQ#1~I>@qF{(S0~ZpG3$o zA4?IV>ZdU=8aL_;?%jmy<_2(o3jw#_klHWQ6}-xNqjW!V@*f0$aka_GmkHjz(1I%o zenGG^c%2XrrAbac$5V3h8J=EFR`23$;)b)+ax%Xs-SlXi`<$Nl%jnl)PejY;SID+_ zFt`Y`1ya&mpI^m$@#kOW_vyX6I$^fgok?#b-isd!`oH77IMbo;)qAn0(&J8CkN4uI zGC{n0xJu>;`vwklAYiH|u@rSFr@QRoFbM{gU9wYmDJ;Cio*4 zyoulo1UrM<2=P#wc<%QTSDh~Bb8Y4D-oDBj>x!^IQh zy-|$~UN?1x|It(?US_Mc_%^Y>`0st2=M>rP@tjMLMr#djza+UBt6)a$)q60^S5-4= zzSF0wF1n>hRlVHNDN$Skq-)}r(yAw-Pz$G}$KI?V0>ZklO)hB~Qv_nS7-Ad{c|LO{ zcuwiYHbZ)`<3lwvn$fnH<}7b%hBV>*!1@Qc)Q;-GT6I<-?65ueMpR#y9xg3dK)Bn5e#my;2i`HCfFI=M~LyF zG>w;E@zmVw7d*W_%*<-pM`q;*7XgaE9NA_=VHQ;Ybq%7$yLNneN{h>BCrwm;h1 z#n3#Y#(>Uz=ANa?lD_zeFeJ$IiZKyh%kSr|>%k8va!n)fhyeclXt5Z(v;AL_lM(nj zanVpM!k_BbxKGaT71CHb(N*ZXto!CSG42y4sQ$X?!PMI3rC7q|>S=F=uHoaT-}VlL z{-{u9H$q<$3Txf?E^}bJqCp(kIE4&s8lkjjMx(!s(eEVf%xDh9)23&U1unl#HOLuY zQ{pdIk5>fm@|RnJipNXFhZ`coY!Q~>xPTRiP$W9LQ?^JEX=My%3 zcg!`G8`;ANMH>4bocmE@k8dp2Sd6p(PGh(D!M#F~IO)D+Zw5?K2Yd-&f)-+l) zRb1Y^#&yU>h8bOmtlZw2pQA z)rOsb2rF4D#T9%^0qCg)3OlzxTHkj@O(gkk>M3bJ4rh|Te(!r;pCp~EV5l@ z+EFoW44&zHH#5@$-UK@>uK3%uYrii~`;b}v^cZ@`6in%=Is9z#3_n|LEX(@8_!+)A zKOI48~1kJgQu>rOHpQ<9MoB^ z))n<*`2N)sPEhh8#tQR6`lZb~Z`9Ie(~iA>x4xbRzQllgthiM`<67i`bxWgUe-Irc4jkI)z`t@bdeXPY0)%9D@ukY?l&o7*_Z6@Gwy+cJUeNIR2VUD|UJeHkVtmtj7g!lN-mGOn~&-M~8U6Bp0qD%5VpD9ThK1jLj zPe`Rvsz12%Q%n0sDot*Ecc|x5(!zWBRBk;RB{}Gs3Gd>Cuy!S7Z?Z>y)+Igs`}X~~ z`I$fW(e3}F+B#tI2;!NNF5ue@k+nEru||2c5n#?^qLW)Yz$7kXt0IQ~kecxA-I9^WGRJKHE zzgWD!JNx?Xtoq(feRs}KU#XplcDC_QbE0AuzU{Y0zuqcbf>MZB@{-()o)s?dy~3lY za4&7S^Q5A*&uh!Iy|%@sQ=SPle<^7?n-4gbu47+B)2U9(UP${FZ+90g_r$~XnKp@D zjj+Qnpf~~SC;&6yjugOtF$Tp6pbP+;B55SIsYvG~)e4A>>0}ly-DHOSmG>N{&Ti-=b5@SoAOZ@ZxUheXXFCsT_}`bKKG+N78mKuyC{pwJy6#MG|7o zUdG58HC0EN^ezvfo=D#{=0OhG5jcRpU-?Y?aXLgyU)BoLaqup0D zv0uBHGjBG-ShUAFn|)HQ*O4vsx(JfX|5xht^hN8hQ#2N1 zik#?H6D2=-q&3EAd22RLXYtHQWON135PTIGNANEMcl@mdpCDLuk9>P82=P#we0z`b z{9>QZppB=yt-r0#%f)Ig#%TN3KJ1PX>To*KjKvzPCJ~aVnU~LP8O5SH>8!*zcQj#q zbEkni-xXHePddvO7aYSpj?wb}I~>(Lad`j#ZxB4;yB|0!yDIGSzHLvc311m5BL;6) z_;*4CU;(~#&qXQLi0*UA2dC5^PsT?(=uRMxnaQsD*-dN7ESxZW-DK*rP1b1|yDQP- z6+PNTU%S6W?}lpIHB;VF2?~O{5gbU67JRUJOs4%a$Y|xRdp7*j0j_4X;rt30szVOe zi?lq={lL>4D?H`0wOt)U#NdDRdEMb0#mw+HrmIf180SN{e2phk0CO#wdP zFq*9A=j=iYiPWj(^M+uJ84eoAwJ}rWW3ppE-^(U@K`#{%8)%$;6q4|C!k)+FZn7)(IG4OnL9w|JE_qLvTwRdtD%5CdlvZ=scR>4$ zE-rGqBDWF4z#|wmbC{41Xi>GAA zGM-*`G<(_c*3_iMZrju%6@g7qYU`0Ow)v2BuDsZ(e^~~e^LsmZ9yI(&t4i*~SNiZ- zHWo(De#_BNf~1o$G~ArJ=F>15{IXy=gZ`xZ{Z>ZJJN9)>hRrW<)U-}MqtOnM-AI!t z_$D5VolN&GU|?>fXl9Lsl%gpwLxN`8JxX13qzxEoRGs^YKorj@TlAq)*O7H(H21QA z9y!-e^Q{-{IT6~z(|jW%E^sIPqvreteu!pD-zZ+w5fMrq!MDPT9I;#7B(k_ZP+brE zfiA*W%33(n+h7S#rW!30EuF#rZ;r{tz-@PX!k!2Q=D^$&>AJ0WWfsbUaR&lBgEK%> zV&8^}if+5tW2k{q5e26 zo#%;*h}Dk~tGCo>3$YmZ$9nRYJA;borGRI*b>#A^=HrS3t#!=;sMx}}E(=$2B{W$j z=%Ax3DQWU=^O}4vI*iN1t&Wk-z8O9WH_B@M%5M0rEYQQF<@Njdg1rHEsrNpVx6BY1 zw$%KL;`J%45p!)VeP@DOzCI>1-=*lP+)OCd?dQnlE%LuCmRjx}2?j*Tux?b-Be2P0 zB00QCRH>qt=SBTHBx?44X{a|8)tndgS4DN?MLnXZHF;6LQB>XjXt5_3rn z6>6Ifpa$cq2o94cOloClbcK&yj%&a*6xxaseef)(ZMg$|L`lN9FAn(RXGGS1#D2FsER4+e){koqNXQN;b8}_^(U(KC^1{;DInw!EW<;2 zV*=P-u|4#E?K_-FI17h}k)Uya)gY&RC|i|;x*8^04H;-rs+;W3tup3wY+B@OpXC|c zdMgj$bLf;a(&j?R{y$XhaJnqh{R@6jRfU^oYG#{=(}|D14(nM(pw?a-LmlCuik%)= znLw2~sO^g2`n`kFHpKYjOt=Jk9wYgl0AndxCocEfROdM92rDQ|F@!q)F{iN;CZJnptj$7VKD5naLU1h0SC46t7j{9=g( z7ZI%cqinI?5aOY<5^S-b@tnjSjq7=OTWpoL#is9{Z;M4=Q}r9ees^M`Ic_1$5IhPb z`9m<$99z*)_(jL?GTpcEL+@1;sEfC3!YdQU*&NdjbmHh3)ChumVv#KO6=XTaXQ{C) zJw!Zr>3L(JXX&RqRDKg^m3;VAFwru*Dm`Wyx%!1nY6};{UK&3oxv{Ytt}#yZUa`+* zOKJC;b+E>ujWu&G)384~0a&mPI2%ko!4X&+VCo1%;E!kbAaL>1W*e5EAI?Z5=o^H= zer*rz1@i%aNkFaArB&W@}Dd?h2XseJA=ar z@lcxP3H$IAZ|=d<@4>3Bb-vd}>hLkFJm}y|yHJP!;-phV#q{Pt$Ewb%auRJanhaOL z>f;mUeTy)yf8pXDwDl%ICq+ou8S`Gw3%pS%?6#MkZ}z!kUe!&i<)@b<26M7Sxm)IM z;TGjnQruaH{t0Dpc5G3BcB9f`?wsMdlNr2STy@Z#WF%MTAGm(^xP-}GCJZ5-`hE{W zcqXerz8tk`Oy*Zt4SW!Oal%?fkj=QgX%u%L}HAtOO`{etnmWegeo-iC!^IvLS>72r=ii2fXM;%@)zxj(-wN}7y|H5nuPH2EF z+$ljEKmW2DbIRwPNX>048tu2GI9keBt=#z^m@ju69CgOCxHkG_8h516DoLTKrDt}W zW@_-$Mlvo_4EpfJIL8XRt}J{NH1Ecd&q7uFn|Zo#%td1}cGY`VFqYsg9VS$^C%Ag4 z1#1Ytw@mV7M?yT5CiyZ_&*sixOP;%%=x&?o<;#r8$d`)_MZO4i_~X4dEMFkePmf8Y z%2k9JOzju;7))NOtOIc@RsN!m?kQDP$P!OU71c=WKLvlapN5yWTuEN5y;81L4jEi_ zb;H2L(@E^sj49l4w#|RG2={Y=im=HA3Km7sn#z_$r4 zeBU$MpGHd~DYYA?G@~WcAl&WKFMYG4<8QL1H>|0reBHHMlCzdD?fy1<1@jH9ro-G^ z=U`VS_Wopyf5j8mo|>xDn{pjx2VMR5Ldn@d3#{quR-`p~-dOvR9e~=5fF4*&aO=lx zfPGHz)-DUKA-LiRjkOZ0$U|uwYoF-JSo@HtA8U*JSX*7oSet(sV@;^T(R=c(W;w>( zKFL);g} z)L(zxDXPj(fVc_E9 zg={rlPU0;RA1wz^u;cPNP{i)er)O-~ z-8m;hTj=f_@4KhMS#MFVy>fnvzE4wH@dl4|XnSk$CD6Bc#*bw~t6x*TQoHuIv)%aq zNf^b29zlY({ak~@5@wQslW}7BDPzWasv5U))5(3S=&*0_qY0)#Uk-F`z~WtL0LvB@ zHH-B1xDo4Bv54aHzE#wX_*G=~e2j+ZDBx@v5Dx|)oYUJlloAZf4o_s}uHiJSHk>N>>ZZ;z;3zzV=SaLjfNO(8l z@OCgner_-3Cz0HChaY%#CqkbE-Wb&Z$wbWW^>HMt{(EBngd-9$evTEEFTt^>4F3I`p3BLEF3HNIW{_f8f zTu4xVoxx8O>I{@7IiJk&>4PGWRK-BlM&qg*94X_E~3fy?T~C_*wmes*?@lT&8RP+Yr6 zs-g`NeD7T8SiDu<;{8_2dKsPCx5pAycw1w_3Es@Rlk&se4o%0)%;>&G^@=#?W$rVL zIB39P7%-D-lFMyV+tbHApLkorA*BblDNVJ&?9! zgP-##+;aDWRDJxGyV$+tcGu?2Q0OQtBC39j%V_+ZjBpmXUG| zDbAE>_CsOfhspZ#sLo&^fF;Zu+@4ASIipAI49DW|&262noJ}go4gi@vj>}RY0{{`b zRwV3t)i)ixR(N)Oc5Py8a}Cv;_eYC-GPT3X^AfJ}+$w$wTkF&D#;yI7DdN^0^U}qw z-EZ-eFf8BFiZ-W8rc?R(Y{yu#kp6F*@0p++lg{%o3k2p{X)N;`-F=tIatA@aLy)55NXCTUDjQ62fCY43CP3&s zM3^~ObY@RF-wcT3&pD5Ye#xaEUBSU*+d{4E3JxJS^shD`4kGwB7o0*+fB3f)!oQ^l zV`CpZo1K`-Om<`A%^huQJP*C}_Z0?3Z?f__S^X(ldGAqfM3kc1Hy|sIb6InPYr#Jd)L&=tCxto# zrHLQz(bMxo^Inc0p4-9rp$4XOdG->}S73|v$jXaP&gYEr(;R1fh^G4rvU0M^-jh4F zjq$=A7o4Fl_+G7gGpJ_qCXuNlio71{UynW7iAgDs8Bo$V9p;BaH+ zqul336y#G(ihS++d0DxNvYo7aME^3Z4-8}oghuP`Wjla=3=IiHf1 zk9^&Yh*wai8<3SdxvV`$LuHJU(GWtY0$KUC%=ND*D-YuujD*WXASWwdV;Llg?fXI9H+0KxyKKQ}y)xFmoR#D}TM6@xw}XZ0WBv_!z4H4`t;Mcoou| zG5HwB8OzXgUqMz@xa>W-&Sj)%vx^0U(; zSy{KYYx>J?=E=%6|A)MHfwQ^l{>RTSpA1H4Dm2w#FlAg~gc=cpiBqYjaw{q%=}GsQ zC<+;6IuugT)zej_bVaH$L4RI`;R4+qscn}ShAS+*E_yNkw z#+SOehz+D<<;$Ji{(f26-xa%pC^(6-vKmZGR&O{E zS=kt*YY6nEc`G9TmJaN zolI!;e^FL8?Qc<0aYp0<#ToZvBs>6Fxv8Hd_jAWPDu4`9W~{%2vT`TOjZU=^UzC+s zQiUHimg>)x(`;G!JiOGrGP^)keg1lntegi_kd+JIptCblxlmCA;gcOzAD)F!;2#2H zst-F+CL&6LtgOWXADFD1KGfj?x2!aP)#8qzdF9jj?(hSWm5*be+~PdYzdTnnK@`TS zea|avpq?&SIi2krHExw=u3T~k2yDI#_K6y!*fL8O)5q0(m!Xs*D?p}D9gsRMhF$61;yHRSc2Q~P5^InUvW!H zmI=$5iYs{0J>vXNaZU!T*6I3gN#Ma=OBkI7MaYlb284>yr+mE?Cgm`H@2MhSM}qMw z7zAli7HX*SrF<*6qg{^`{?;qtqnhd%&*;{3?ww z@FJaG(}PL>^-uq3cUSiYy!rhjAplAY;)c5CVDTFAJAW zKnw;>G_jJpbrsx-!b;;? zxY|xyf%YZ`tT+aOMpeL=hG5qij$CD<$ySDM#m$y3`l#EK_MQl?#MOj6(y$#cs96de z!3I%zI#B1-5V0(ssdFXkk~!p^3%Y@yYN4KTBdhZJRyu`xKNR^Ljo#cYkNL6xkwxY z<1BRI-~!uYxM}%f`d9e4{;ICsljJ&|DTC_T z#>q9xI01FNp8f+I#8w*&r2pIme`>vtLGOIM2qRe7`g)FEDKM$2aUcn;|JF`%4{3c7 zU~tcm+)3-%#U7sYnvd2WF0$&MjMnoJBe4E1T1OctsQ&a1p!GmI*JQNrm@HQpt?MPp z^^b+Yxqbuxebf3arrZy$A7Pw;y53Iz09s#7|75iO051e%b2?_Dsm?Xk(;3a%8r9j$Z)65?P4xyR1NaYNd{=GDRUl`xZALpJrs^f$z*R2+7v?|0X9yunt@c@ei$!%tpKUc)q}hVvQC zTf-Wx;eGHAs^K`sPpDxH)Q|@fgKLNaU(lQdj+rw$|FL)H%83sgZ=H<{IU-s4uxYyBZjR&pMTuT_}MVrpCEj`DP_Ye4SPKH-d zGhM@|u4Y<7JA(Ns?CJ;GNXI2$0=pjpFK|y*v!v|qG}m`8`RWzaTosJwVgoeSbM#8q zT+{q$ea$t}kMn$Z1vOVUM)ftC*@l>u)gmMq8U!bgd!HWrv zv;6Iqk?f(tB{*+jG*=^;AD_#Ka&d+^O8~4{F&(jP6hc5ZmLPIQx zO-aU*t1&6ZpK%7eX2vnPYns^B2S!5E+98VUqA{Np3`}4k9 zsQG!8Bf~yr92a@e_{-rH#BcK$)yHo~z?=($IU$Vsmv^AH@gf>Mjqp}A@v%vDrB zz?cX3LIUqR7)v@K#!(i|)#o7<){{8ymlA|KYSeP!-2-XM`85&+7OHr_`TFS)QV*`?Y&L;a( zrCMIp9?BPba~f8=ov1Sz9oj!hHBMuC2Qmwo-artgSDcTSVY3nAs6EIGN!Z5Rr+^wa zP+#VF&!2!VYe#J9X-F^op%xb)p{=AlEl>6!?-T7GT{YUoJ;?Jqur5IlDEEaz%vPYk z&yu1p+^z)Pmla)Htv(6UFIxp%fvTxX0A({9Mw~2G7A#gb$B`y! zfWcztBbx*k)6(SVsImEMD4S#E$iG8(3@qkaT;Kt*#oJH0zwtJJa9c*Ib=O2+7kwO_hAjs;cOWm z(Jq;)T`gB>w_vzE&3xtXP-zT@tL0^dmY0!3 zECYldBVZW7T2CK`ez>v2bu$2i1)2hfmj$dbEEAzOo+%~~i~s>cSZ*RycXgp}r_e74 zf?)KAn_C~&%-j(ol&y9U%)C0=VdfQp*?)Xlm3VIu5@y~pTnXi-U@@DSuZI+Mv#5to z#{+L;GGWYU4RG)-Ax=wx%M_Rk@Q`0gr?!CLFpP9+3O99prO^zFg7tv6e2HZijBlOVjE=X47=1s&~4X^8ji3 z9XuIJJ1~7)5x_UY`RD!e4~4CJk$Dnk+`sq;B$v?r-GfykMp zUV`+L!$pe=kkFo_K7OoBQa1=PUN;tic7TOeCaIWRuhm!c)ezpABC}70n?==u&w55$!7#A+ zlSUxbW;mD?>;<^h0e1l8FWwPFTFhj?N>9h2d>beu2IZ0-ni+W06dPu;;t`z!SrM`R znplwn6b3QcMXQgZ1?Mr@&ZEAAjV0D>mx7y=gbiWRgD<{>8H;b(@1=G?C#9Mx4WM4Y z1fOVc)^f6xajHx()fI~@CfQ8bLbYXnN3^<%qucp3@Dpa|Y%8`0-A<~p!w*()4)#1| zAiGnUQl&QJF@Pgwa) z1C6EL*2=H<3Eq{T_q^W6-R<%E6M#=vmqGd?fGMd0t_0W@V5RXHAUF);c>NCCEm;3l z!nNkrJ=MHA@~d^QHE725a9yX(X8=Y+OazYLHs|{1<8BAF{&Asir_kplMPJ7}>Fz&8 z&CiZ-sQDgX6tf(~^j0Ea>Lt|dbEO*DbDOxRIU3T>J@xX^h-Z!Toa#D&ryD|;s{uZt zz>xrd1z2g60D{9X(&#d{)yG#FL*Z%~4c0Vz+`eNXh(^Ehk!ENysb}2+7}aY89Ny}= z*Qjj^4u(b#xX|CF&{qIKF#0-X<@7&AqYgS3_PFLMmkWHk1kq^qRf=&SEr$q=Y6Cp2hJa}R9|Blu90mvu!$_m*a2tX~d%D^*nxknH`ek4Js2^U0 zwrF%ZV9@Aw;0SI+_M@p?4u(cMGaU3)fPr98QuKAqzSI5`ji&2dNTW$AmtRm!ZzY0g z)aM#SqYVvRG|Iyekeo(wAa05w2&<6q0j^FH!h8pCOickd0i0QzH2MJ$9EOobU&0-Z zwaHqz`hCLeUP{&t+JXFIMqkEMxX*RKvmLOv1D@u9JvFFCDql~mGRjIh>Sp*oRdK$PAN~IS)?_p53XZ>ek0W#T0XXFKj0SD$nKJ}Lw ze-hCwm95<2EyJ$&(vwZ9M!Y{VPtCC!2E-~?v1kMe2%Y2LXqz0zP5Z<#NQGLL9G%i8 z$t6cQjAzexT4Kfqk~ZRDDTrLYt(qAs!G+&OI=uF-gaQ^Dc8r~!eBqnmb->{F4{yA9RO5;t!u}M-qPFH1S?|up}h&u~uybOW4o@i!3WzJ-&gxvks zzx?4asAu0~{7`UO0Qvup)gd~Cx?EW3A1+-F)Mdc%*a++U&RTlvs`=EwDm-)kW54M`~1wAMbaGkspNuT^n_vl_V# zt1PE?uEbJQ_G&8jcHe#SSw3FVRx*Drz-@=hAo3}|onZl213Wc@(0 zYkeE89#01A@gyDhK9m<-kA)ghn}u85rUZwn-S<^OIGkS7k-S|1gKe({Zf{4kZn0Vb z#1yGu?@;_!{0rz06S&xr^`APS!xGUbv;zt$>+II4w)pPB*tXI}caU?fQ6m6-6NR2@ zwLlvD#M!YeA$d!sHS}l^qcnVYUoA~loDgBcDTk`6R5~xD!lB$%f0Xj~ZF4x5*-H>a?HQJYn@V0L?5lwN`I;<|M4% zY@0;P_zb)Ak3}Aseyj!f_F;!k-P0ze=MyAgsC>2B(2?j#SQJ%Big!LpdQh z9>uNq&R|*Q1Mg?p*UtIQ-wtv3`y#+-{xC2kkXg?xcju*Ci3YPcj8Ff4n?{#|3 z@_5ZnNQzkZ(5u1|>(+!=BH9kz`u|vUM~d7B7^RP(^xjs~Ql$7i5f_U^idgLV(_t!A^xEWwpCgsS_ zfZ#BUa^yR>=R%Hr1y{?F0!j&Vq{8nYM_w3pT4)JTn`7f5M{YpGkxGsX1jrw99iYKV zV+bJ_4B0#lFv{^+p0927;Cs1wB;+!rk9x_yB!WckZbJ`y84ak# z0=%-}RbG^FWoXGiJ^pEo`kv#pqyTZuchNgU(iE%Ljrkh=!R%l-T-SgLltWYvj`Y=SSc>C!?G(H?#1nloTW zK^yi#rTg%m41jSSBX=FRlZJ`cgw;m&S}@rXHmLbA{D3g;(T_gt%7>KO@0?BN#M<4l zM9O~y|2kfdeBbt(h!mz%V+;{dzira;M{8 z^B?f9#YgzpatHpk;^*`JV=Of%h>KJOkqOJV zc8GLbsb6ru6jKkxDM-P)ss%TrW6ECS@T3o6&zUeXr|=edA$cK=Zw%8(9^f{;*~Bto zIr;ysZhiVvlEaKVHYcBLk}plqQ_m3`^5r$)y`%MZPe2DlUF;hIRi!HSfI4;>;mnd>YT7Nmw3u9Qg8P$4dY z&n*N^vdc!|4L|Ht#{u!QvaFm_%Ql``wgyd@55h?6b=$j2sX2-UUf69=!k*o2En9?| zu@Nx-0xWHy#$SM^Hd5m+z;)R&{sQ9oONZkx+z7{CxO)7p(Btp&FERd_H)8xHYIFBS z8GrjB;$}7eb|MayYd*l$4T--SAPl?`hOHQkQfcHVr-gEI=t!kRYZE;1RvLR-AR1=w zFJK^|S}PY4_Hi{fbpVFo@%LAh2i;7qOkc$Zh@3cc|E@0C7O3^(AFLzC-wQBwS}W7h zk*G2h2Bd#VrT34$cP0c7>EGa2X5^zTq`7QR=+9_e>&lI=hgKT(5Q;V%NC*7yztj9! zrm)9ZygQHbr`lJcZ$CP5oXtcNq?0t@dOW=sLCe(|htaPJHI;^!2cdS}f`KxR1LaXK~A{>d041f2|&=~Wyk(}jTUfxRws1<`)r6<`N8n01h|5RX|PiXWTRrpkKq{ zWXd45$#Y?Z z8Uzy^x6oe!nP*W28cpt7T*;csHgUX9Tm@=i!p6r(=g=S9)aJtF51^z};2Yv6z7-C* zT!T!v!h)kl&US~$nSdcJYO+2aX<-q$4yJ47o})xa*EEm7C>0=^wZ?5DMi=wS3`Wtm zllzb>*lK9g7S49UyN^O6qed)I1m|v~WXd`M6Q%YCi=1*aiCXVCq!kfVK1=bARNI`t zcef+7_J*C?*PBUryf4av)N4keu2ExS6ClA%%mfMv=h$hyBfc^7>7WwfLgEup!gx9m z4Mzh$EDc!IA-r&=!0sn@6nUaWsZrx<;KV$;%oq+}ICeWR9S)KkXT{Odm_!c8hB*4k zb;~6$RvMeP;xSJrhxicmqLzgF z&5VV6P zT{tTct@jiE8#BLc9_qNPxD&?w8<99_d=78C&J?Y86GG%>EHqF^ztd#AiBNRC(RLQ< zrKT>-x6JnBgHM>NWt(T?l2*KY)uyVRGSe)LWA1Iw<&MDIqz(B2Z&kJdnM>BH`9$8p zx28c;h^#PXo=wN~s(s9O6+R#+$K3@0+qaa#_GN&*ju-F+fZbYi+=mI zTx2siV7+E8)dLe>!i21#@N}vX&jQH;lAn-}{1Kh}32*XelO*5HiMp#5AJxf+dy`+u zM~T2*g7$H7gtDjlRJ*@^?=Zp-fFZpe2KHb^cmd31esq|gDwqQJwn^xzLMa(B zY8(b+WHheSvea&uJ;&(XEVw|;*ocpW@b}%}|MZ71aEDvxFI@Paw8Mo!2foPq0RuS8 zLP@@ngZTnu25@=XBEj|xHDX9)1DU<^E|(;q0xc{AX#Uke>XGDgK~yzG(UN=yjuEt^9&9@9j*9rw_NjvNTOGOOt~2W`~kel0mo_3+&0v} zDqXGN!)9oh?Cnbj^7N`OlJrNsJ0N@LVJQ)8t%do6C-GaCxDp?ZGh0WYNR`IpbnNsV zd(;GAXX%j9tpLa7iRfe5-c{gOfIqjT%$@`Yj+7fRdlWuX##b8G!PRS}!4$=y!7J~g z*<;2x$X3_;D+m120oOU;XAbxYz-vzE;nI8AYdd|aa|I?9WD?p!-rxiS?-wDFmr1N0 zdDz^gmNbrBcB^5sq=ZqUSmUJbY=pu&+mBOsEN-($re|h~euXNMthjztV>kQ~I#V28 zvUQA|ZM8pq>A{3Q?oU76oqmcx{6=^9SbzBCb~p~+9toPUKB5?5!`mCo&c(dL>Y6

Q{LeSsP^wmr&soYR4+929;&NDRF#GEqegwyLN@Bp>o+uDK58D1# zT-iVyA2p_}!yFLM4Yi_1DPZvhUbyY!b5x4jO+8*AOs*`7uT zJUv=g5kb;S4%?X%E7Abx0L(#&+m5H8teX=ltH$oa@lT#NVzH|Fpiqq19#^hLs`rKl zK}RW*LrZV}1c?hD#wshSqb{P!MorsO=HyQ_Q&HFU`r(_?v0kt`V#H6C3}#4Vuo0wn z-fNNMDw1T)Os#p8^0S?bo`4bt6<{KB+N%dZv15}^Y&a5^c_?<1@;OL~tzYX0&tCErD!bI|@GubiYe4L_bi5wx;F92BcBpE0A1DupEU>|@tcH}s5As{#m z}1Ji zHbDL=jYk1tY-1RldzCXyId>?hR5`cM0h$uHJrtVj03O*%FkTI?r2CNNImoBYruUXd8|E?7yRx$1+uSsGpAh;*PO1ic~4h_E8(o@-j7ja^^7&j z^4N_SjmnJXj1V=N=y+O>Hi@Z$CQZ-)kTC;_mWJH<&?sciy;zMCY37r6Dk#Ig*t-c5 zRrOTs)|Gm;x^d@T>OvY~Xm1$eoDwL@t-uR@mB2;_Y!oUyeN(7Q}6&?D?V#2-0`e$Ut$qsV; z1>oe)A|JN{{7!*e0cLcejQnteK&s16L;fb3-RlZ&tTvf-vG#G+J3G(7Bc-iuxqd)w(g9)$cPyY*wVdLM1 zkA(c!yTdp7!{4{VD~rW6iZ}9duebIraHt->C+N0h_DVRy)E=_TN+q>&etW7 z?a#Gkop7W%u8-3@YMRgBi@n3c_lnS5Q!dE_Ynmxlka~zE6J(qRFH$q*NEs$oRG3AJ zvI$^HRD=)lDS%HO`dCrq!-^*p>LM$sAP*?j)CU;yM0`w}29@#h@m!ez37$NNK(m`h z@s`cr0+$_9?c4Z5jmV0_(^E0hX(JN${JP=U_>8OM0 zLck5Q7dG!8CL)YvfGliAs)fxEBt`=bLglqjiSikYv3#T~YzAU_I#Mre5N$A;XOLRZ z42v2|K9K40FfM3b1`J%okk1I_gUEyMJtE!?nd4&w7dDw{n*74#(`3>!|2s~T!;@+w ziZr~$b1!a$LfL9@!}V7y3@3fA=i-L#%GHg~jofN2F4k9*{1~$ZW1o z7~Dn%9I^%iYxGe&$@28%`mJwv?}Z;;i%>a~??t6JvcA0$0j!UmQbo|4zhq{98xl)G zU>H$WRMUc6VL^okx`qt|x0r(-+|l}bEZulaO(U&H5=aCn8MuW|K9*C}v0ZEFt{NEW z&H$~?2o=`?qTbxLSjAzjH-}{v(1CT!L$c9&I~&jx5KRGwXd}F^0^ddIdjYySKl@a* z3rJ+=jprfkL@0}u2q?!!)L8*AzFaKO0F+e`z(;+QQfwTU>zWi*HWsTlidRIQTE;@4 zE2hCIMp;vqN~vIjjFf#~p0H{6-m2F7kDssOS3`U&cFHoMRD4_P@f@u@M>D7FmM9F$ zIa>HVJPF4;`9#Jwp^_6K(FV&d5bbti4LgCEbQ4rASp>#jL?Z6}2$j@Z{w`TVz2*qj44qv z1&AiDy2k*!IdqbmL#d9%GOfJ_+kl!pc>t?zZruU;&P4ClkL-FPakZTebYP?4)i!G8 z(u=f@8l&G4G18u5WF%muY>#~MnGYg!wVfY-RDI;T^dpuS8S%BOwr>%kfCTv-{RrfB z;%d7t2?7BfGmpDkTPUjrd!ivrD_vx2Bu$V~T0n+@L7gS|Ll6cI)$&QT_KIrxnracx z5_}pdwu{;0UqK%1ZTL1hRBWIpAUrKX8t!7{x#x-BSTBk{cxso7I3^SG@uOWgNR(ZK zH;hU+URfgjXDfF@$oMYY5;Gd$4A$|$j(K52fIsz=dEqetzdBvOOn}?Y;JmOgAUF); zyzmIPT>Bpi7i<4CIBEba&puPF{mT|$?LYbsto@mTxpa}N{RbY>BGj8PaEBGZSZ~SZ z6oC9y8a)AFD$6i9Co8ADa#|}VS2<1S08L}KUn?{X0lsmjsslj&5Ft~8(i>%J{2#b# z6+0Xrmkg0*)JXYI&6;vCYx;Sm%$mM65@$`8uAnc6Jgmiv)V4A<8Ts+dFV(WGh#zyl z*vQtPx#V*yP}_p2 z^j^p?Sr{%ZK*DnTNu&*HAwl6{n*YDt}nrM(j1(WO`)|+N9*yGVCGT=zeD!}REV#4W(dZWoi zq*=@u$T*5ud2dkw@y}P${Yt6=CjgBjTyA5Ku~dp(i?M9Y(jWHVIAM7OY8QNG(M9h$ zUG!YQSYh<2maL2Z18B@aKk-_JEikH?R|~j_;2Z(h0z_*}Pw}n8Zh@D*PAl_=-{1~E z-yh!79p23!-r61B)*s%`4hNAB=1|Wm@2Upk%C9Y8G*A=Z@~-?!#$ob?-PL1Mzl0=n z`sEbJ4Dlvst>X#|*8*nPKJTrePipnWkT{|8FNXQF7G!RH|JsWMg4J9Ne)f^;}b zKegEW)B34rRMkX3^~*9;&DKvcjAQqmII zq_n*d0VR!9e{PRDEoyyskI>>3uSJ~F-S-LTF;U(4nO4pO>QUQgC~PL;;&h@`b5Bc% zU}RF8WZW~HSb=IaMA~Jozjw*vx{oypDpQN=U3jl7Q(9Q!#tQQI!F+NhpR%o3=%lK3 zee=&zI?RVMl?3~j*Y)8AeR5JK?{i(h&-z+zQ3cbq7O5<~{ZR)W6Ss2T)tAz!?iS)S z4lCf96|(b6)zwb88qF;Uiw7ycDD)Ff#rYMrR2RA(F*#K_3_O0g3?#xNR?l?5{)l~y zxi}Z)3xxfanKd==mW^|>4U!`#hA-S6yx#~NZ(Gi49=F+LMU}$JA+X4XzMXePQ ze*l9q6E=PFvy4Ut;o`^fpU#PS+}fvMzniIS+~0JpOcgdSz}Efgq*W}_W`q==pWQuJev#? z;zx_zRY<5`$7Lla2W7OshG8wLXo1Y+q~&0mlqs=%$iz_)=*F>H$kdD6b7+#`)C#<* zHZ(;@ZSW3X>|6=brh~M(h`_a9E4mbi(m$zI!F@ZfT@>`muzlV`WHnUOGQaGugkv5( zQc7x>+bj=YlO<(*BBHZ+=}^@A_g zVTJbU6#Yv$Cn6gZrjfGr z9E=EU*h11Ua4A~(olh5mT|?&7JEYHam8kJ*Xmr(F;nHo06X8CBHeRYqZ>WndpO-W= z1EKAchGrr(A2fmTi`}g~QJE*;o(eII!G6)tdHWSmE-*qmvQJDmZe1g#P}NpyU1{VPM*HNoSf?9(Dl10$|sMC1d6*hvxw z#ac?wX&L_wS>u{~%&Jfh)e8U!m4S(yFJ8GQQR~o_G4HJljYji8n_<=#jV1&2@@l_v+=I7?1*qYiXRB-5OP2%8C z%>cP*7L0z78tJmPM%V^T3rQla{WSDH;Nyl=XEwB2>u8s_$bXA1Wr~Ie4YEr&&~CbH zb2Cal6OE9G{UG4VUFzY8-3;9jEvO4QwCg&Yh_k5A(hb!)*25c#3ev(0R#BI3AY8fv{8Zzr=&F_-9*vjT(EI#)$@aFL7eU36K>J#1?u#Z?bed&i$d z6qaC*x5$btTZ2Mem05?%48@#UG86&36>YWyK9aTVvkN8Og$is{bX+NDhnH~}Vgd&5 zVDKm*^NNJv9c+d@P_!9c7ih{L@*b^U>5H-C9WK%`fRSf zU8*?jRG<=ixdMpd^Fm6%%HL9O#tPC|Zw5A3toEUv|3|tziXWue;c#<)&kY#By?8!ref5_xPd^7FILk-&( z{LBRC{4$(1M4Ri$1CsOx9bJJb5?In$a-eXC_f_)-P#d})d@SObwyH*Ugca@xuQLL| z!Jc}*fe5UaaVAc9wV{8^I1AwHi$#}z2EZmm1dIS2I+XT^a{$3%82W_K1MXJXBf7xF zgjwnzN>5Q-Qx?%&cplzx^NAjSdAxJ2-d1;`)v!UKZkfnjiNRL=Fvxl%co zDQAds2GYT+OfYn?=;oS7AQxjscX+o_$h!jM55AoNey@BxI=&}r(44TviV7GUa{=2QWa9WAMaxWbBX zL-Ds+ZZMNYelg`fgSn&9?y6%vtUL+d0LnXC6EE5_#WOK;1XCm`mgfj=wQa|jM^BZ9 zUnP9JJHXicf;2;-{yEJqA$FU6&N%42nTjJ=(lwYZa#@$Dht8wWPi0`6Sb;?#ETL-> zI8+e=Jv0l2rnGIyDTHqS!#Pb_V7#?CS^NKjH0Fx+&g!brY$8N}u))f!mAUQ<%CA z55Lk52k{R^;r#BasxDMGR{%zfUJG1ajt<)BXtCch%RyA7G>(~9d`up#b7UtV^(c~8 zfLWytEk*LRIDmMd2ZX4F1QVpA^+V=|FF6FQXI>w*4{oDtHAIA}o6S9!s!5WF)(mpi z4L88XzPhJYnN7l-8<u2*PPyC>5FCb4F1MsRzS1}juG;%jKA6%MEiq!22;|u)3V*x~Mlr=)6q}3k+2*3vy*WiQE?|VHah{H+bvR>*<}kb)qWg8pDDyeI zsA=``%guHlJAE5dM{Z-o_^!>)?SI1iEvK?J*{lUu4XwF6V}zKwxR)wMymJQkIS8oxY+T{kiFw=<+>ix?I) zUR2So26_}oqV?WIOoZKoFnf}D=}Js8>%F8x#z+!vNQihHCKC3{`Qn)g}w0M(}X(*E_BwQgXT63dJ!2nJX10wf&krxZsO zQkmZF8|H9pC%xwU8lrZrIzxRH9~(7#y0U$;9=I)PJWH~IH+KFYR|;TRV9e59@zX?> zPr@gE$ex?%d8B5-<_xl2tTcyfN&d|EMPy#(!OJuxz~Zf=7`to(^Xc%c(?4o0s*j}c z-|>&Db7)|(SWlI$o<}m^EBuQZ&5?iEQr7~E)i%!oo@j$QENax)^JMeTYcDP79+Fs! z(BFA7YCwE5m~iwn4vW@UlnJk@n?aiuK%r>U_$!At6Y7#SVfcVHk>@3|8xd2}rs_x1 zW-AX7Sye7>9yPv%heh44z!1Uq2DS(5f7fPtWGfY)@TG&xGuWB~-vUMb!#Y}hH!j7C z8I>pmf0f2^LX}3jau(4^X2$#NT0JNE9rGd1NstGt9EwLE$fOtjubS~h9#K{&Si(dJ zbU;4iaHI5!Yrd8Mcnd1H{ zIm!x*o!4!1d>ju0SZcHXq|Nb)LT1wsq+fS6GjQ79C#kzzjsmKaLW zqz1%)+4yKKf8UX({mjC5oG-7nQRWXc5wzj<-2=2XHeVsuMydy)hITczvP)_)yz|vW zYhxGN+W5;~+}hZ)JLhbyJjf|$9GZZhZfj$Xj^XHEB}TBdaq|m7*2Yh4-vn#p4`^A; z<%6w_Dd+UoZP9ZF)F~e~4{>7>vLi(Wdr_io{};8Mh-2W^4XiK5k(w`z%J{b12um>DblOa?fX2 z`v*sTO^4SwBUoTOvnm-K#ISbtTh2nF(EO+CtCcx%nb0W1oTY$7rC~C|TI@qr3YXIT z6?oZ7?CX zv$$~CT+mb*(PHM|i^)WF${PWx^3x|Yrp-t&tYt3zlZLg?_c;WuXC8fxD9uF+tPN`; z%qO5p=UT@xtTh-2!`hgZT8Y&P3QjSst$)M8RZAJx(r|HwSr7j#O>>}OEfuZIn>3Qz z&_;X!$%IIbUCsaDvZ1xbIl#6`YMlTueY{AmHUI}Huob{JCr}o500f6&l*P^Hj;}PD z!0jjkpnQ%N!Z|mK-t`_7g+EBd84h?Cz{75pY^DJGvQ)q_C&FzSOm0KVpQTubHndiN z!8#8ik(YH2(uTH)GX>qj*KiiGz&Op1Q`^w^+7TlBffHJ`4UKoDo6nR>$F6BE5g?iH z{gkZ&xB_`z!O;pqw*wtuBs_Adi(X`BX2f?5^El`+a$gI!D&E_zi1>pdaz{Gn zM)Op-l+woLeKgmV%oXB;4L*dhj6yNv9Kie`E7>C?XIP}4Ua}HVZ(u_ytK^vHIf91x z&~{B_>g?ylJIjf8o{AU2&TnL>w+cBibDWsXt(e>ZZq$~5*xps%37WB;%?9?a!ji|C zqMgsJPtsY7k3r%)?^cnHY>hsE%s?aKCi)>t8ZOboy$mZHdQAD1v5e_amFSBPZOh;- z+UtYk5hG??flvN`(Wc9U&DqknrH*Ov{qCfS^3YbmHg`D#wYCE0K@5Z!@KOt}5ik?} zc%K1TSw=uI%@Q#J_6C}0gEW>3{rnEU5%4QdK4Ju1L1wuAPKSYOi4idV0{kIcD}Y6@ z==m|HNp9Rl7VQNeuxP;y$?sak)GT_AbemiRn|%*=u~}o?6twU0hf-E&VsP5gfOk$O zhSD5mOf@#)lRubM<&Hss@w@O3c0zv3fq$bq2&GvrZC)bF4e~@?!{RFL{Nh=O>fyRJ zp2*KSkzcSP3**g@05YB`22Xpd;;caxidCpNl48eWAvX#b4LI-zV;_2Je zP-bZ`XXD#aidY)V8-ez(rosGhl2ebrrUo;N8puhOAPwf=|L#WpiKPygP<3`azAY|s ztIiI`Oo9sxsLl$O|94eqzc)jF!oapq)!DQ6??ZLg9XCDdy}TH^8z1H}x<{`ddgTbo_z@zV!)l(yY^X?Kb3*fucxL!LJ5FCbay>=vA>dp>_ z3*A{d9IZPmC{nt!E3by`tmr=I&X|Mw1h!rvn{msUhek3+%oqmnrsFa(XMLr*aDD0NaUh`2*Mv;4XzY&+$E8gXZqv+#Apn6lPx{FcP(Q zpl5MV)9bhlz!(u51CMvL;Zd0V@`7Ho)qatHZw{;1d zC-6wQ;-zG)sPXL*RSMUt`XhMRtJ($r@WlNUg_y-Q#05z&tKj@w`zX+v=DQ z>kRJo4wV=zTwhk$$s$lvi}fq%eN=0n&C3vdgXvYp|g?FOCjk1VE!cgAAvB} z?i!;Et&K8E+ABzo%E`49O~6@koD!6ktz2CpKCjRxYTV8_ncnmL(M>3Wt)SY_kW(XL zI3q-ji*-D`f%Zmt^@dkDR-!T?JN>i{_&5^{k##TB9R;Xo@mN_) zc8D5%5f?i`iNHMmd#)vWzy|_m2U`aXhck9^La#fwcN@nc5S~g?t>uC!?#x?d-@BvX z&_!$(HGX={$>MFi4`wT%8o)?`Ssw+4vwxS%CbNSeQwwwRB>llPn|T60u+)-up0zx) zbY;hJEov?9EKd&adToE+IB60QdU|co?Px)3`_JL8my_1wo=v0{_g4cC9@~>L=oMq) z9^dMC2gA~>)mkLW`^jwLnYTDp(R+Na2R%03B=o>j9sj`LI*T3;;m)aOy_ewwdJN;J zkKELnQ%EvjsC_rWqsCNMx=WGHi5fFsh4JB_m!~)r3A*uzV~>O?jZ>A=l}@sKy-lEX zMgMAOHhn5#U+-`b;(vNyZw2Zq4F9M1^$xg8ZiToh5DU7-{`U0#`Kx*KpxqF2KL1TS zx4Cv2s#)Ct?-CTdAe;+LAkH`+pk}c>T?BR#6$19HLf*8$L5U|S9lGE<2jA9mvVdwk z=UyIKQG27JuTcykmia<=3e{|x>rS-6ykjkyuCC8pNzsaTz;yg<(J`xu53 zC!M{=!XeEH(oRMZORf(Jl|$pLl7`5s|3r*@9R+oVlDa(zndjQu*@}nNErEE zI?cXL6X-vrb?U7dqKGbfZ+~Hv0sI0x9Ao8<&O<#@ZG2no;np)fbEBI6L(jDJr32G5 z^-q2wL~k-vzy%8^M3J7ps0$&AAXDzH$H|n^GZleVtlK;a7!%zVm#6AN+a2N(XQ+?%RD5sWkQkApk1&OkY4zT?Kmp_2p z0WML9w>rK*Xwb~V%Ph`HjjMLi!NN+f-f$B`Gw%z{lvs;v5NnxU!9xP}k!)ap9R-%w zI;bgtF?0I@d3aY0mJTY)(T^*1blU$4WlS*;%Fz}mq;^s|D*@X-TAZ;jq zIR1k%2P9mmeE)Q60MO;MGRneSXSPcj^&t=d(IA#Q07pL?2g~%rL@5TJV;BV4(Z{L+ z$76f8egu>3N28Tk)E}owQT$KmX$bET>uzVtua3tRaYX7`QU?` z#bX8iq5#QO(2pzpr$4XoyH?OA!OLDjclU?4afcu758wNoEB$ZyNLZnN=MMkgAO5Kw zj#fOF&0Y6$%tsHPF6$1?2NoEg1DCf41nIIYCjI7CP>a2Sr0Xz~>``aquek}jtZZ}^ zp_--3>NMS}%i7QLP*hi?k-X*u*E$QXdgdwWM6`QzSC%>G5SfpLu{a6iwn8R797%=0 zCgM~nJa!WoJRFr(rE%gsh#`-k{{!zwa*-?(teEi!Qgi?!2&_E-XFnm5@OOZ51?~cP z_)`>$)zGLEy1&7P3ap>u>IacR=PGG?Uw;f{F=GT{D5RG<;81|Wfe8^V26*>e0S7q| z&ex#TH~b2$XE}ar1=b@R+ZPzuAd#2U2dTj7uW?d=b%w&3<;STP3tysE$n=9}Tna3$ zlp6P}kL5?g%kEPB{o#cN6W+|9zOFlc*dM+d#kBL^i;sjZx!De{G=6^?Gy}H;Y^v&T zt<%Ap14aYiQ8tXX}^7r*leV9Kr}uW3S5H(w(dq zzS3RE-j!lL(pYv@Wtq3(Hge9V(#%qL5z0^-H!K7X0Rh%g(6A-k_cR)3$1VLxjYV}4 zt*RLLk7NE248ujU@!?!7CidLxbYSYSrlIYA06SL|plRk^Zt1a}KwRieSYh+hPpLP# z8$J*&t%wqBjj=+ecUyN*k97kA;YqbqZjwXmPjAze(^Ya5S{+?^{fY|)?4hVPj2LJH zzd{QeC(=2j7gwMAqF4jPAe!8`?Q6ex|O9dD~Vtk@CR% zdQUkd_zD*hMC)b12PAl!!#h-0OsA>vHzDxWClO#N?BskpJS-|c0u)Rodr-g=KRzc~ zEVd(j>EL|&{x@0Rd^$?OU!}2u5FW6jlT3j%1PVq`U=5x5|33xRePjQc3am((+=JYd zQ{EiX8g8z3MSX$QYCF+JU}b_narGri22zQ2BEB!ix3yN4)2faVYXJ1VUL{sf_?XT1 z2zT@V;-;ba(TqgRRa4&9sLvPeC5wteEL^$+u!Mt=xBnqY+d+Pv^8|ZUxb$cQTSbOg zN=LB@@f~3mki*$l(c`P&!4)r_Pg%AdeEaKqOr7q>2eb+#bK^XYbJLgVh$wY z_nXn`#99jCU>M^vx4o!w+Ea~lqE?{sf;7>SiF%M)B+$)P0Vb=wQUNB0?xVK60T&u4 ze{)*xfJ?gfRhdjwCP@vb0!00w1#Bw!H#Y@!dT1>mZoK$k)dF%w%;v_3Ob551aM;fT zBiUWcTsBqsw}tts0$QR2H5}}8DBg^7D88)@m8lWN-x7Z0T`^FjrfEfBT`wnRDn($p zY?{hadM}C~Zq*2~naqXE=YGR*u$06L!jQjIZFN0?32;$|)hmlTQ4?tupqhj3A)+hH z$*DR99N8+x?1gV^_+&3oj}T7M+*((-wJy1}zUJ0k&>EP~Gyas~@vDoRw)$%-9i{-f%(d?~ zfZ#BUOW;r8Qt!A5F7%G?!qIxi4SFR!H3GfkhB?qXG6(Y?JggNn8X;o(d7^hr1-Jva z;hO^RwAYzUEkJM>2EF5+hs4>XoS&4#!>$PXRyiB!0L6N^`~mzN;6z{pxW@7QSc8?u zRfOc;_;RLLQiKwl)vm(Xj7wooch=s#xatL>v@W-&)GcBXY9$9qM6XuTUX3MFTMoxW z{eB?W%g4|jBr5#OEm-|ndPa1W*idv8tPa-r)~T{6^#vsM-7 zK}~A!_WO{tJ5@&9Q8oq%5_O~75F={*7{`mj>Y234(wwJIMsA~@OBX+Y^Ax1sb>oNc zUAF{J^{$)O6WU0=>qfME*NuUE*G*jKT{i|-lXu-%jugD>CT@6=-1ZgKCwWVA<{&hI z1jn+5L3^M#=jHM!s2B&n4qcQN9CGy$1ZSkd@Go^S+A@rf_w-A(dObsnC( z1l?&kTA0i}9CfA}8r|9g!{eHUm#EOltjh81ftZjPAJ0b5tw@<{ybGYJ#-byTsH!`f zZVmvRB%te7GuLI=Y&G-gn8LZ$%=b>P)XWo>vm*y5eQ-{+l4+VN5LXG8v(OzZ#frKERBNGgkWqq4>M(fODyuAicujZs=2^b<@5kbALK)suE>fGVgjyEBP=u zWuXXqUCcWSAb-OPi*QGy00oD%#cK%_m``VsvJ*GZzL{QCSIQqBN{J1BtN>D~(ljLM z(1{zWVK6#WyfA}HVFc{d<3J!^Iub5obRt#rM8cPjl;)09-4h94I#Px^QmQ8szI3E) zcO=6T312!=fjiP6o=EtTNXL#xleweS@I=FxipFu#9ZlNFZU(NK*r>;b(2VYAH9gqy zrK3S5>W)^+6AfQFTADXnZBI0O>1Y|=Xz8A4_|nm`z0vA;qTx$NEAU1;)DsO~IvN_z zU4^hG8oom4Nm;z38Z8$>|GlDASu8u0Do6tCx8u?if=x^DU;X^kzxSwL!Dk5 z>~bU$U$?9WbK9M8d^l=crN|+Mo5g1#7u#?X`w62_nQT?FhoUU0oNEDPYSqPNHg1#vCb_Vf)}6!AF5}TlstV9Z z@1HG=gk8!tklL~f-2Ns_3qRk*de=FN#9;BXdNC^Z-mXC)GXM#&-_d&{J8B%Q2q#8%yna&HoQ4n@3G#xNz?(` zOLE1Y(MY!5mSmufp9dzkaeOLi7Be2k_jmv3K}H?~76V(3!adt}IxSugR|7=rO@t3x zd|h9SUbpyBaxwLA1PaZLRv19D^IRA{!c7FY=SX3=KLNw1!X`NgbZAD+0c(m9I*o4D zr?CxaRSicV)6-^VeNSN&*hFjI9Np6Y@MLJM0m1U9}G$W}=E|`FQrF20AJl2)X6R)`l zxNCX>0l^l#$rfN1XFG;`;5_xo-~;|DjgtuBWeDXQubigJX+S5L0dVk<+5k9Yw9Kg+ zA;V1Kj9-ZkEZyjT^=9fAN{N>6-zS}l9g<4}LqH4nyN34;{=YH+9xC&ks$-QCypesJ zZzH=}nb2xsQOTTx>*Hy_h3TqM$P9ysvVh(^ihy^Hi0@|R_F@UhFbhipW6%cHC`E^= zkxF?fR+!WRTw!G%uSpsIFHxZG#iT%Z(#y$c35xCS9KrR0MUaGbT|o(VgX2v>icKH) zlpVNRcJR$G;+MRugJpq^;K0USns z)}uXTFpx)Y;CF-yZ^;z?yRLzRHx9oYMu^(i5X9A{9=A$1pTqYiE&;#*oG`KY<9_P+e9d{7p zscbPQJ|+l@Iv^ot?Zga}ZMCFErExUs26X;1FiPhXM%gt9QDDDrE%xiyuwS>)_ReEr z?+iSD5uWrJ$_{4EMGyZoXD~kP=8)&FX$q}}8vNgxLhmbZ*qx@(+wpC&yW13cTtw;p zUS1;Qb#< zHhlpu0EpW?0Kw47FgWKbr?+x?DyKj>Co88t9bn_ zntfq}wB`YPwCB$r$Eb-$wscj0a4xXGI274=H8Ga;vXC=?snCR|;}~orj*fl%fF0@0 zkGbdS;}|bvdtxN2?jAwk7=W~)IQJfdq={!7YGcZ*jFZY*XkotPGMBZG&r<@?AUHud zVwm(f2F}K+7{22e6Ohgc1Kr^l`NPk!!@(p6W6kQ`L)C=} z#S;Oe-Fg9+myLtYR9Kug{Txuv;^B=$$x3ymu1K^}Eds|&ud}RF-(7qFRw~EXlnYX) zlhkIf0xp!)QYh1m<9<#@8Q2gJ;wk7a=C#|YiD1t{dr0?+SI3>Xy`TcX@~nZm3z|o+ z)3A(c5Gu(uzXpdncxn^RYxsv?yh2%P(VO&`i+|?k5l;3uaf;OdbCZU}S96^fG8^Jv z4_Wa2emMajPc<{ENk(|t?K}l|%mzrI7knzzx8TG5DDo0!Hp`uHLk%fd)!{6r{bgN& zqHc)EL&J&E5CsgAd1rSQf{Oz3n|x5(R_gw=4#X=nMl(XxxK_v0O5I^>)gM(WiNdsn z>zd82yyy@4U{;E!1#2*?l&a&<@@er_Nau=aKt*a%k5vtGe`gpoS$RSiWffg9HJzDg z?U4E6HnlTO?z9$yn)kwsP{Q>V+~3FL3Kg8tasre4e$RB?mT8r+n6~LOOKUut(>}=G zrm{ExrZLbZrm@j@F2MW)M=q`MQbqg$g7;vYsXC8kl!?Ci$5K_GT=bn;9c3j14P;xy zg!aoImUEt>_Nx(m&^a=h9|{2Nfow`0jMH~zMl}SoRG7OaeaUX7&L}|x*)(b_#}y7% zW}BXLDX>oBZ4pWttzM|h13j?sBk({#XT76dY1lTfQ6B0n^>-^8dqXek-iS|y9XHp9 zN-hA~%sA1_Qje@9OO>k4_jWwXPC!IaW3Zh9+ivRo)|IWJQ>X^&gs}ll`^}AP+HmQ~ zv{aGjaGzW9*Ak5>PsF!*$UuI#(1`rm68$eWnc$MU7D%5PuH1-JD z03#%&50*#XdqJOvVHWpFo)n}8Zr_R9N{xp`tA^~zhP-a5zaeuH8j|0tA>Tk!-8z3C zU^ir*Q(Y(ObSLT!DynYC(Gs8<(uqFQiQdb>+%^dFNlw%(59WpzW;7%*vmsRuY{-xb zHP`g_Hzc>sd)tv0hM-?{aN3cLqK^1%?uZ^{adUA#a6j12;(G9~apEcD;VJGTC!+?j zwJf%dnU8;p9byeG1$xBq2PaV@-}PjhE|^4$M*brdz+9Ox{vv|4MxG-A$l3r{Fo4J* znOqhYKXVA|RqTNDh#C*wAYy`s4fD-MDU+h`L9Z+AOh-l2V(Fjqz~&VQj~bV%bRx?p zF`aQ9d@uv*EH6u{?SIZ{h{^gQ0#s!BB;Z@qz>a%DaqnX|pr zeK;|*`+c}(e=h%xnJrccA_Rv>MKIi`Dpld_S0~L6_wOTSTX)RoaL^Yt48~bQBgc6p zw%%J9mUff$kot)h3ONs&7Bj9xP57%crVy%>Yg9su$HPmJvI46$a}op&HmZWqh>=PM zV^dl(!^KnTNJ>L|62nePXf^So{M+@Z_w=i2=K&HZ4ySf0r zbx|7P<|9peWt$kW5~C$P2XLM|z-yb>LY;{!xj$ph)Q|!ui=;6!RSadx7+_g40Ei`H z4H_7Os8}-Krz{z;6vfOEypNR>Ye8n&GFCw!Jj(_wPjOmv{E^+EQj`N(?ZnD~<9CHQ z{cJ18buKH%h_|}+=__}8l7TR}5VSDSkhl>LhQn0vXuamIVU3Nz2$bgG!tjC>*2kgv zsIWfjgcq0=oE~1V%Yti%7i_iQTHyt2EVw2TZ?Hbn@S#Iwk*Kp+SdbcCh$c$EyYKTMW>_mRW$W+>uiCGn>(}pEN*_dtHsTo zgqu5&n;n~7)WyyJV>UbMgkhGltu+KwfwbAEHMvbK=Lh!{4r*nVDByU=-8Y&!a+sF9 zdHA;EaJFTo>kF#8EoNFAhf7aH0QeDBx(PoE?l$rjuf+sty4Lmy!Eos|6h--YF9M8? zA5iy7Om+1=b&|>(BeGxH98s zEnk%%Xz2S2rA=b!yB9&iz!PEUgB*d}h34r%h&%B-P25=uAaTDu)=S(E@a-dRjby|% zQ3FNX@0YlVOC>}iaUZk&yrhec&xchO>zG@DNWXu=&f0Agwz&H~i7E%L6D_maXuEH6 zV_wR%_nByOC!OPz_z|&#Pni%>9?6W5Kmpo`4c1$`MRdVz z-n;J_S-E4RqTMx&Z;OB3cGu@ypwFS(!0uXn*?-sWdS9g)2KQ-q?bUG~cGvYsI+}nm zSzMWkvHiZP04n5v&)s*2qL}3IKWTS8vpE*YXkcx3E&H`>E4#s>;g};W=M=so5?)f6 zv)ng-SQLrEMu83k6&b`>A9SB+k@#TxRRrGYld}PO`fTDbli~<3>4O|nR^jgV$kL6e zk(9S1)scH7S}RhP7Kxq?%n`ak9LazSyphcC!gGPPC|j^1bw#9XS!C%~NWGFnK2oz- z+ylf?m7#b5)&LNn4FG_mPmW0(6veqBip#c@tz@lJhnJ=1n9(hAoSmgVnxsn|-U$k~ zsb^`CibxoS!V6P#CRU^nZpc>3`v2H_6F9ww?EnAiq_4E-=ne^uMx#lGMk7WuK_lqQ z#7qz)h9TC85d_`#C6NwkkC3s(o-y`iEHfg4B#7?VV;N!?V!u64n2ZTRLjLd1sk-+* zTL<6u|9!oF{YsuXx0X{?r%qL!I(4dQ^6(P5>+bmEIeWT+$I4h;P{uNdr%{i|*=SAntlLIz=p7OO}dk*j_2P*Wg<>vb|p#F&a zqz5~KyN|##>k#l1DYjNLFc@_PgEkwOvhPo@JvKoE^0`eC+w&C(B~oZ0wt@G*_%!rb zvTaVsPmDYwsRI$9j*ZxRC6P=IcA*}*8?li+fjbTT!r|1ed2)OjTCE{Q`EENZC~tl2 zyKS-4&{pv;xBl^`p|3^uPmBeYY{OTyDbd|&=u624CFS*MoFf+iO*4ow4(9c{3426n z^G`#6KFHO@pN5XAcq5vm;-{gzb|FD*n$X*NXqP(;z0E`MY3SmmcwA|9x#h}^08fFs z|NlKq{j_N7xGFhFoI~mbJ6k0Suf?359T5D!+W0a5F!i-AlBm=k9IrT&lhe=#zz#qB zG_-h7)}y@+^QWP|<1{Tos5aYIdK!8al_BD~iTS6YzuYr27Ku(nn>OWpUrK4**mXcz zLev9Ovd1Y|ZU-!Ot~cVz3pK9L?U-LX!#8%*NA|hid0WXRI@h~{@2mSMQM%8;x93|- zG!el@rO0C9A^f7}8v!KusA3QeHvo6-C=V^Jf0R|Hr zq5(8RhU1kWHeEPOu`5p<;bOCs<=5tjyj!QjE7^Hc8EVq~2UpQnl%&QTGg^+d2WyS3 z!(Z&3?2fGtvaOXhtNc_ZvWl?vq7zcUjvheWB^X@e+FpZi129#8;y3wi9}T|RW(n7_ zoX}`)VL*XK(_0Ve9K9dsf)$5wPp}QVk3gPC>Eh1G&voTkM3g+sqBrr1EsN$BhClFQ z!mlVyKR!GC*@fZ9W`~a{3_mCir#+nI5rkbX!s3x^K|#`42b)St=MH<3>X*xM&K;K4 zDh*BDOD*#GhDHf9Q`u!Lnj$t+`T0zGOndOMBJhrikC$zx(#!||d2Nq$K$h`I4_x@)-m1H($sO;LB2F;4L?nlXLS~e=ZkUyBIR5}5b0>Y}7%rK=oTyc}*%Chj= z7o$Gn>|lJ6bQvIw@dFnM!u0@=OOGZNRxaMb^l& zwVhad@E~o>-or2F^49DutyPaBN#Bhy76g@X~D#wB% zI;C|d&nu<-ABYb_(pWO}z1_sm2HOzcN%@xQwy7eA8+TR`%0nfC_I}xocGV1Pv}(f{ z^!M>Rg`@{7LgI&B@Fc$e#)!n%;^l^+91=gHx_=LCCv(KHokao(OH*b6R2o?TU9f%@ zdG9sy?mtrG)%jMcW9LSVzNF{eXt;YWWp{@r=ky%HN)#r)s((b;3Q|Xu{pAEv_FFqJ z+Gj2D%ckt>c5ZYbf%F)EZj_}|ku!*w-QX#q%>bEN&Cu!44Da0BOzOx2=>7AF1uBFq zt~ox~sF-^#=*p~se)7EXX!Gan77EAJRaW62ZUuDl8rhA1&2%-sH-3ohCZbb~J+VfB zU49*>Kv?OsWIa(RGM6y++y19!1#}kmq;ESbpjUT|%k=}SfX);3-GuSs_L_COw*nfG zM190XWgV{fhJR`S`Bp%iCebfSFc-A~`sP=0Ar8yI{GJ842W1PbfSz)p;d)9Fi$33D z1+>bV@I=A=tXrW;fls#sqX=nMKx2?C{Dc$}vX)+{zsQ_Q-_8o?CrKTylX&h3S=0(> zwIu3T7u6H;^8-YOd@CS3-|L!aw*+%hE1(Aqf!)xwRu1N=5$2*+Kxewp@D;6*@(9_T z70|4{2^~cgX9e_efBH$p&1MC3RYk=0@Nm$uj(9l73h1OpQ7d9=R`h?C70_XzC;o7p zd@Gau1QrnRzN@H zUG(-~Pr}o|t}dNf0iCCG!It@_K7#vjBHurn+>?YO#02F2g?^RDvq%^$E8&f+oHGlGTmXKElaowHLGU>176I znLWcJ)=2owzZlklecQfC3!HkkS|F-ZXV@_U^0no?MlFijrBp?xwAoy-Z7rKSrJc$7 z@!?4}6_$-}qSrVs7w&X2KYeKJWKz#>=yVY_NE-UUB5aT}bWs@=9$B6!Il~@$V}$H0 ziR@MqFkEHo|6NJMrAtkW3-Mh_|L;non%ql-{v=b-<+HD)i@ zs`x0f=|a^RUFck$e_XX#;;}CA>RfQi0O8daL)f*cE}{EXSGXGoALynmnRSU-rI=MN zX2rz4(8ovmU%QXLQR;Ja=>B9lRgAXi>Q&X~yGv?fvZ*U5wNxb3xhnf|gGV-uZ3OFF zo$E70NUaNk^LJeeQ=jEhQ|U8)8CUw}RHa@!diCr(mfQW#t@n0Upv?Nju2bx~ICjOv zowMqmwUtiQOWXUI>f4sPQ7f|=-q6e%$}pYLd#<2k!7|4g5!hImW`P}6)1+0g`bL0J zkl0l$C))2q3?fENY_De1<2??aV*J*}s8bBH`LP%}B*HqcN|SZXEITnz$@aaFJ%X=X@RZo6pm#hTwmTPxlJw2M;9N`V{J(1 zXtW*Prd)o}eel#c;*|ypEuL}PyJEc9V(DJyMb*$AX{{kz*LCuNgwDdQ!GSVCVoy;i zE81F!K~WlNe&Y`UP7$qHE8%!CgWikj!jTtT8g(12EIQ^;a>;*G%{DbEbQA z<<4;CQIb)_k$k-L+eDu722TT3VZ!|ji}c)xSN^iDzXFYW-Fj1Mn!G9Nc1?AYSS4hA z11zOva=YHiZinZsO@I4!7ELuxnIPtJ>*!>C!zb#t00gjL%5g<7KKk-8Ao^I759@h~wl*IF(UDnChtE=7 zZ(E66x;5==1_DJz+Z?>XRu7Nk46|ao<>H~WrUKqvyQx(cHo3HiYS6?-`Gh&8?N5$> zU&T`an%Z9;|DHb5mE+$B<%(6Gbqv%|cgU{b=zf->yKF zPqDdw-by*5cEF_Jb~~Rc)VE^#h}tbGrVp##y#2YlSKI$KxgTRX5s70vQZUkR7>Ri% z)I770@nI>rHBOl7RFOk_JYcB#{)Q@Hkz?YeK6(LxVBHv_sx7q#wL*^ zT;{|Iwx}b+GJ;Xm*a z=gTYDiJ35m5r7u(MoL|`(KIUlce(EcxE5MmECePftC&7t_M&fdx6Kjb&vxcdt!0#L zF}RoDV}?+%&r(8`(n5<}lX8hE86MMK=@Te;iGokF7N3_FyhJt<-?2#_R8WKey;~rD z|DDgBI?5VpJl_#Lv#pV87_PlF(lJB+XRVP|z1hz?^z?2o#DApUO01EF|2y7(ZuxJs zMjH2r|CBY->{0}HcqY09LKdk#$Pq@k=cco1;oenSM_2e{AL2HpdBVAT+o z0S^J;C`@)Cx62*Z5!{UH?;@Qu((OyMaiP$xara;lBGlnyIy}`GtVP5{iqRP?qnS5e z$M7!&+y$^BC?On65QX7lVI0-m_OA?^fx#({GI zUkA)G{}@FUdVEu(5M}s5r-az0Vf_W{3+!VNdUvRtc&hU5DQj9&J8HWXhrlT?mV{Cn1gsit)1f%E{F+ozv4!XIFVyRq?F+4@8Ea| zG05o2K|^(rEHN0GJM~vO__xFX&&Z!hRG1!|P6>-M@*L2FFAR`8&PMwC26VTPeg$!n zBdSxx)Dj4CXqWM=CYN8CCcE>E?N6(3aQcJIwrckF>|(ixtLMgX1t#uGuRsMu}J(jMjP zNesc(P%B<0ya(YkU&6};&QAhoGmNCd!{D;+tV&j}zepSzIIfCgnorugTzrV zxB)%9dWtbeWq5%Dazt0QIm%QVzcX8oz~@#)HTX(W*T{O8Bf4!#fBA(IO>{eaXV~*v z2-qI9D?&Or-^cT+`u$WB)0zJ#d< zt~XP3oi%E$DDB;BD3kVIBqG{B%#emeY=Jv%`SCF0uUyg2lceSv z?Gt+;@x`62x^rnzs=I4CcpQ&tlldGL)#?6s<3pB1l$17SL^2)AWjrv`9$Z48-K9~g zwKKtfZ(9$}tZWnI9yXVL=qAd#6fPaqFR5b_Wi8;WO_VF=3(Z1xme;?wwRQFe_R2R= zo`Y2iH&Ol#n)Lej5k^Z+!^z)7Y5yk4C*DL^-(_x_b;%~mNjoOA+~!D1%8=|fhC0LX zT-5NRHc`&hJ{V1#cQXi^D7~|?dG-ipW3AK~UOJNflP~l$k29J1Y|#|Q+v||R&}0*3 zjYA7VlT8$foN-@_cs+bUdpU)L#fafIjR{TG&o1oPom@7ahq}4ioY3V@aS!hrKXpP) zM^FK@!j{%q~D| zonp28@uzIQUYyk9|K_@O2Ws#?yRKCmGqTF5aojRe+yYnJ{m+C;w937X?}$ru575p!8UT83wC3jQ~gz4v<5zc1j+{^xUOxOQN&d_HzBTt zCyKlOs+$ml%QgF<;9J=m_@RI`@VU}dj+9=l5uLEDm)qZ=F2lG>(aYZXYv55#@0`dP zl2oE21*b#IV|JuktvuHPMVW@xZ7MBn1hvh1RkY6afSV7aE7I9 zhz3W^v?%VqK(wEqc>U)d5J#h4nJFY=Rqs_Pr|Pv3B>A3beB)StrrfU-4Kqy(_ju`L zc(U|tpU;?8?zke^cjCKVRl#lWuI(-G-KcM|(Jqc%oAeFWl$)er8xJNaJnLkZj}|3d z+w7BNHr9}|OKxN6ka^kQo-G?{Oxi_Crn^WQb;e!n$XjctPIsq+DcK>IKHN(Yx(-r? zCakpZ?l92XKC!>34t_ ziSCml{SNN8yQ1I0wVcXkO*_cxcXVaZtjhb*?+A7H_M6P&oxzveamq(Ac#jb9+<}IF z0pPWOyk!G~Vn<;(e|64F&UwZ;PdVpt=R7P2Z1>9D+_2pRxVi&x2h<-CZUOvw3ybgv zz#ZxhywOMK4C-TOGY@qHn+OX3_EoONXTl;D;9djX87$e>WziXY=An)tBPhI?bj|7b z#7?iz={o#FD;NRh9^kh0nrQwrAnTox!zqQEGNl?Ai21A^cG!)jM> z{=-F5F**N190r7HpN;7ftXxMaR;)|t%V4VlMXH4Ru_}rf7c1gu)YW1x(j(k0X~om_ zCe8cPgG$<X)UrSdbn5R$=(OI6R`A-vj*KlP!lzIPr>y{Uo?d51s;9E-~}& z_*?}#S#KAc-TUn_(@UA+;ah1T(tYl10cnonp$c}jqD3cGdX{&uTZpI99l zNQ?&L=d)@VS7z7n6SlRP?!eY>+tK%@Z5I zhR0%C&Ad=A`ON0ka1f^b_zVs=@izVql&szvkJooS3ugOn?Z;cDTXE8osHcdD>vhiG z1?|q{%e9+GfEAJjE14?>tM@jzP4#IHC-queiwm|m;oMtP=;LSHBj*@e>v*uUnFQ7U zsD7dJUVM0tAxVXHx%~vvOeC)UNcIyz@X7f9M8Fyb%M7zw|IbdYL$49H)+^xCZkgNJ zju&jIrs{{{wH98p z^o*c*>oDES863&IJCyjKk4@FUv4s8bK-HjF;TqT!ru#SH0|nmv)KMT(HLNgI#U=z& z4JjC^G@vB4_-(f)^Z%?*vbb;mtfg^}`X9d9oWgqZd@|SHk6UPt<|#*$plClWG)L-b zN5AnHEi@azEV*nEjPQSDp*iLKq#pk_7n(1==UawV_y5dw4r=4#3(ei5vcM%;Xl~1Q z#3fp2>YAVLUugb0j2D`3ZvH>J(7e7)qk$7?ZSm-D6>8Ej#v0D_g~PsD*8M{BgTKb& z&;Q;+^WQwbti?}}t08{KLUY?s{yP_%TYkPw7I1C}+RZ|<>x*Ss3(Z*O(rj0$!D|-g zFe%nVt8-`EIhx_Qm7ux3hZ8lC_E2s6)$VALn4A{5ncaOXt!}HezL_cY`>eVLo%}lM z%VjKwTGzH%;H~C@iJrP(0=B5k^fL((Yl!M^C_%+lbCBZhQ&jZbEQzh8BPe zCYP2pGY@S^Rh(?|iaA|6)t8H>#^afik7u2g;b||xBg^S+DNl1g9v)ojwmg|3abeo# zoT22a<|ki&Wyym?2LZvGO$C7tq+k2IA?;5b!~G+bGWaQ<1bH-8ZEK4eXVJ)KBb5;E zu%5nmobT>hJvVASt+1|V_>oUls-*&_U#g`{FAyW<`3QFq0aZ^K0U#U%D$~o5X?^AZ zsf)@PjO$x=GZ6b(`}zqD$pZnVS*a2M8g1d^2bHhr73Rr%H7wnaDWTkMs|${c?PmKq zwd(akysh-Cl?Y%ea|Vq4pE?#%sWGeZ#YFIB^HWnKW!SQ@GuVi$BnB&>GuRmLob7EX zx*_0>I~Z6EcuJ$z!2@F~~dOL|LBwNrwFmLNW3784+P2%OQWTGXvuK5d3Sk*5JCm7J( zve0W+*X;@Ot#plk?Q$^{UEil1Wkd{rhB!sn=yMdS+co+(J-&C1-b)wYL|A4~qe%aw` z7lxO{;k5pbu?=|iT}MmV2HXb>W2eBC%h-8KbghkSfDr%n{*2ai%kj?e*DJ&TeO5Ud zq&Z9Ug>b8N$Y_Z^YB?JI(kas1I*U{WHFvQ@xgVeXU^vJ=SF{cYJKj$AIM?Y2sy1@t z$44~-Q}Y-<+}P<>_15h*PSUH&DQzljcZp3i+CSXlp=9~%?`at0W`)DU4-QMhwB(-* ze*FPnlz$BbwsCKb|Edwj2+U! z+Dh+L17GbS)j)s`=x31_9RGxbo@hTe<-*776Wkf>Ppo5@z{oXGchqUXr>vw{m`j)i zA1_-08F<=VmJ-#OP3)t!D&7AAGDru10V}tQNnELx!bg!{D3e%YhNn1nDitEB%#~VR zbt_9mF-SlDG~=XRuGlFb&vVjQME~^dENa|jw*;(9uHkPPoFh|dX?M=Ra~d_v><*#& zQ#wbe&#Dtby|}vw^)@~b>Pql}e)?-Mp*FV59Udo`YUK0_>$miSEL`Vtb;Lq3?J5hBF{t+pI~2Q&CMb3& z_5(FdunfXS_8b~FXKR5HZUUP0`tK4(b>`#b+jBgUlaIZ^aJdrxjJ=Sk0lY~ES9b>2 zf&$Vvrh`+sz#!t${dW`T54S4~`mFnwGK(r>i{IOoR&jWr}Dl@y{?Mh75 z(ZxJ7KV~B8v4|*T6j_@Nh~cGj)>mL(8#lqSZ0rRC9VV^55V~1-q9!f1owUowl%}Gc zw4I2#VqMGAuTEcw6^0Olg~QrXC=UUBW(WInJH~5kx9&!p-E8e)8^Kit8^Mu`>NX>E zi*-5WE@RmvTPfBgW0;m_{D!5#Ee}N#=qrSjuV~qo?sOv|>0mTP>&XD!9vljUK9Aqy z<{V|2eI;zVA-o)>m>uJI+0?Oz3Gw{c^A($w?5&1qeK8(XJ5x8h`uTu=-_1nt^8gRr z!@#ovuNxxyeSocI%7R9%X$o>S5LwLLHXRg2g(64sI)H2ik}9uL?NJOISPLSZ>c+ z{)o_)fa3vo+skr37jO(;B9lJt_2v+Mdi6h*nbmwZA-5 zV}sjT+w=NFIJK>{p3KaCYi%93wYCNm%IEzM3fqI*alqjXRJ$*E&SGZgW0EW+2A0dz zMT2~_uBgM)s^;WqzD(5`zIDE@-?IQ#tMJsNwvkun<{L?zWtnYESE{Nx`+(bu#OV_r z<9(IHj=_7?k4Icr+lFpRTiY9p?uWoL+#IW(-|J@?6n6liw;OtwC#Zs zg*f$!gWDh_A8wAp5#Lf#(JO@m?mQ(*VLs`m-ZY$^18HmzzFCuQrFiM49>lbRmV${f zSTRt*HJrMIplIT3AZSpo$9z&&Fl-GfG4tX~H^soCJ(MhQ`uitJSt_YnbtRJOl7@QL<$!iRSQ4OMk&S(F2=h*pj69~nsYRcg(0 z(J@ZeL{5zXW$n6GV2N#8m-3NgxBa6Q2pwD$SQKIW>i zXi2(DVX{twsUmvmUNiQf5Sdf#3t^FKpc@euD<&SrUV_tz&;#~%>S~t4*1t)i*)mUe zTrsi3n;JHIQ^V#w7Lci7!wd8?8&lzfktVDRPt@!p@37i(F#`66-1`izYLy+X^-tWD zatGY7t1&^7QW-bIK;MbR7TEmjK>4m>3q8q2m{Gybu!Z-WZF$o*j#65vW7-B|+RALE-PJKImt2ZzZH|R$Yt`(v5Wn0u zJSrysOiYWP;qM22HUG*u_=IP(IM|en8;1(Xi{$}dZ)bpOWy$gSL(hecJn zEvl*+_xFskxkXiPW$~-nQ;RADRTDgNi*+n0nNC!!*MCWxF-e-FSdS5s4t_>dMmLJp z1e6YT;@66`DZmda)+x&3hZO6T^0-*LDotClVr^>0x{s)?ShoVDgPZuZVqF68!;1Cx zFNzf_XASx|$gnDAXbENk?l9bzXO99tvaf+N06X{78u1Ar9EE8O`e(W0I)Xpp`ZZ|k z5Vr;$elKg#sz+Ia3UxT?KKfc`(1VEeiqRQ-vf4m|J;VPY;O_xDf=_{P6o&JjbKb&{ zg{k{`$vMwB=P8AO?FoJQIwatufM*@x>HzpMVEE`tcCNx3vo@tVg5L@gvi{P}WWlot z7}5N3f^tRkXfe5&6RTFb)wK2dwwj9}G{|VMjvnvw$J^Fp?D~_*|$E9{#CcVV-J0cPq@P#0A-2?=jpn|zjAstk{UPHoGBG?rY0-KpR;1vtg0B{qfg`%&N@{vitNG{ zU3|+aj!*kJ14Xh(bhMrXR$W^shVOEP-*>}anOO&Z4bWUw<9R0IMBkvIWMgcGdAy)Rl;mqJab+`i#5~?Mhn%!pm2!`k85VW zHl9piGcBiPIUhMI=K~*0GT}9_(Ugj(jo-3r^Gsnd5)YQ^+S}N46*nZ?!Qd)B^hbX2 zB3pYcS;YItQ+D3C0_nXX)uK(8PaYL%I>WDXUa9Y!*&saB zivTMQwLC5aJOMB~1}Qk4h};oA*kP{}!6>gYfJJkUQ!6*cW-Heok zXWJkv+_{5nH0!U$k}B-Pkf%LZgGjv7&TnF^_7y?_as>B(P>7=r)~YP{oG*AdBgbN5 zCdvU4i}|8rY9ILp08>JU&1;^ug;0&^&v;U+C8VjHWVqGO=@m$x>UxJCyc!j;>tTN2 z)3hVY4G#%K1MljA=I?KcnBUJeF=WTa-P~M4_F>h+ppaRSp z=sB{jv)*19OEGMiu^`J!x{XWfblFaNp@V(U1F}&}85wq@N{}`hOVYv9_+owE=vOv_ zSPc;}Na7A?lVd3_ETA~C9Fihhc>O{R;VqTnza5Z&!@#~!$kZ+w8Ji7;JXb%%OJt?C z>#aTAxM)53e$f;P?-k&jFJuN#wKt~PHv&`btx1+!?TU%&2#oaQ$PG_hpO~3a zkK&bFzG%9!q9VPZMIWQ|pT&&F$Yz>d`#m$r7%^8Hca_ z07WVN0ZwvIs;gePxo>!4LMJ>C*nz)_wpDY2zF}DLy=iQAZ#sx>szTUBAER=6)3@^! zMuF9zC!^R%a$0EU?A90*-Zqo3Fidnw#Xf?h>tbK6%zBXfr6y*DUbCa{SGY4q;UzQF54Lc)f9m|~@$1&-NOY|dt(ucaWGf-D zXht`vSy7kT(S7-T`WQngHB&rF{#W+YGrgvGYozgW#SRB^ftw6ZISYR_B2#36?9U9* zl8G4gANk0UNuK(1GTpDy5xn;2I{MP!SDj2EZRwNv=)IyxalLTT^j)1zBPN_|$A|u4 zYA2kyZI04fdBTIeQsF+2nsCx9T=w+0E8yE+sn*JH0UGyquFd4Vk6koD%zn@J-}wgQ z_uq=PjbN~_43?wL4Csie+mdHLXt-={%!e)Oc)yWkh5Yv*g`eLZypPMc)Q<+a^jjJP z(2Yxvr-Kf{K=O|fHuK!iSGxa${4xst5htEuj$>#h>oR4HTkhRT?^empoIv)v%5`*B zkq+>FlkuZfC3h*xboYsP-+vQjN=WnM>K=U7yHD7+ya(Q>d+aKcm%;%QK^`TrJ=LkA zI&+p=b*fx-##89e9-z>d{E7*mOcp{03Twk^=1g!;B|a$3UL6bJ!6mJ0>654rA@~gr z^6B2v=B3yqU9EFu26ZX>QxQ?KQzD*4=Yt*4m7c}HLlL;q6ookOVEawC2 zk8I9Mz_SzZ48YHb8%?3^`nG9GLgmqL4Eis4y^puvu2v~#$|l|V!0eje(5y4&&Uy|N<5>v2ew>iRvu466Fhlc?T(iPTxf37>eZ`@NA!Vw|9GqOGsBE6lx z;n9Edv&xwU6pU{E9L6mwLptaQTIG~wU9lKUu~eAhBQJbGcKEA>;d8RXA1w^OBRl+$ zh2c};aE-J-LJxMBrZDOvJ=p%hP^}GIxjnDgy=xJ3{fVA#d@L6K?q#u1pSyMd>0}eS z{Jm?7=}y*!cJJCngwNdJiRj+7Mj#*P?p^!j#aty>wkR^Qh9PlQ9Y2mMcSQnhXOQ;8 z@yfI;%y7$TK}~G-QbnF}TB?H>;fhzy-(R$c zPpa!r{LH2mQ{mE=to?TdN#5L1k5@dm3@8lmmmOYF7{2`Ttn^>;k%#}o?C^IB!=I1C zf8^ZK^B$L%=9aJSHX6{ybFWr@_VAO zeAQcREFaDCBOXufzTmNjm5sa?l8R|oJLwlUFf1;h_qaJPOLu)TA)KAyx*Rw1-UXBnZsFHP-aV9a z(UEtRxe+#}yB?@4){Z@+kvB(o{R~a9JLP9kd={|%1RE+l0q;J^z`200o~*I=1t1)S zY3!XXm$7#yt{;2njB;b|^_SS#yE7qMonlyaQe>CS4hc9Y0k;7>pSb_sWA9Zeg_qp3 z*DK?gHo~&MXuWbOl-3_4ImLrT)+=tjZhqeS>xOqa9@luiCNSfK+AEjGqfuZm8jP%! z%NR3u2`&9dx)@Ur-Uw!A=H|z*arVgc>yBF-SV5Tw5J`zx9L)AUup5WTgRM{z2uuX z7?obMfU+6OSn~U4tiM0=LuRZiZ%a6_9T-kr_n+Ny;yV<)GdPCpV)PeIc%fj%dQATN zIRES!%ddeB`^@E*wFVl7S3FPcT^K$nJACWH@apXFwF|>bv%^O|W0Qr;KY*IdV_Wk4!^-Bd14-rQ zvAF}8WM(kh6wG6H5yJb+M0NAn%|PkkdVXylTN9x8Joa&n&CO$nD~qpU&!Y3#;b4=w zDuebBfCF1?+Bpnx%&7(*0+>2Y^VrdXIs%1h9#dUvn8)_R^?R^2hr4;~wF|Mmn$(Hy zl~9M}7bOS2{lY3)7`OpOlwaeIj*&DOtO5)peU-^)q-ZkuH;9pMoR!mkd>GdrnIpCj zecXm8Mkw1Iv=V6~dJIKRG`64Y4VF5?)f7A5!b!Um@faxGKyD77JQfdt;bDw3wl~&d zK!Fw{7O0)B){rGSo5{iyOXpi7oh#dDGjHN^(HLg7hVdFua@QXm)i#A{^MRq-6WpDb z+x;jE6-i}w4j~d1+m6%=(w?OIoUs`saDHB4G6mjq z{pw}6K6v%6OjF2_|L zxCGbtfl%;$2VStFmJ4+wQwcHs}|1FKI<`aln0T5~&a=e4F+sQr*Wu;)zU(6|q% zMCt=Gm|F|`KrhAqk$vEUM=S>|OT&XZJa>&Xpn$tp-Ur%+soOsA01Rtw>h>YB`@n)5 zlRoe~FjV{YlLD&6ec+*|eJP(cprDj-A6P{5yFT#Q+=4!E$_4a+b()ew{m?$Jxi78y zzy_|gzbq(iULVjc_r^_XyEE>APEj9t#s;}Qt()Zcfzh;dP9Jz_W_};gE@G30Vk~l6 z)TOYfmwj9fxoLET$<3|zZi9F2h>jvQ%ELxbo(zkh4U~SbsfxGWm}TpTMf4Jl&x0s? z*ofede~nDSYvPLmN|-~5X&Kl7e?`YMz5x|FhUImqu7O7b9*OC`f(K#dZWrWcneMaC zAoO01c(<67XBsUsx9KXd${pj{5z!yqgPf{iBcH4@JW@qeG|_rz=875HQA4z?JPL5H37Qj*2f|U9=7huK zGAH~R*Ut$}M>x6Yv2&Rd?s%R#L8!we*hzx_Pu$KpMlqOA0QwNPZX0veMEp(#J z;A75I=`W&}+Y((YjL8tfihr6S@%LZ!qE+)`{~nc%fuf%JW$W!416_!|pT5-={vrA1 z7yoyE)EI!s;BR`mYicsb-U!TWai1=Hn#I2RidUlj13$-Zfzp9GEdsB^{H}%kvKUrA z-M(P;GHd!o4X_0zi)Xd&Ua;!8+0+0lMSEt1Hva{yfp>@&*z`CtHzLtrnNDLhKn>*< z5o}Pa5vKfUemBKn9IK&fv|aaaT#1fSg@`6z9tNw~3%&7x)jU#BCofpdN&ew3nftP#kD)mAf=ycd)Vae?KuAF(G{TnsN4 zTf3>{oJp6uUzue+vqBBp{w`KDvLZ|eBPM5=OT8d@y*(KDcZ$xv$#SAAP4>m3Ngni; z(;rn0`>#V%?joAiOwsW+{NbW$La|WMcA*B*nqX^~XiJjo&mv}IE?KdTWiB(F#uohq`DjCu+nhQ#Rqt{bUVk+qXL0fI;8JcxMhGc8!&{Gu+FOYoNoivCpd4 z4DOsvWe^Sf_i`a+<|G$ny|%kRe-v;I1QUjm^t zAL>0igFQS1;otV)%yC3@0^~FVgmBvRv=#3c#A)u1(oC3J_T#RI-m{%Hc(`d5nLz4_ z=u5uJY1MqO{Z-`!h8Q!YV(rN@-F2freLSgICL>VM)bqBAyk%gvR(MKth+m0S@$ z=d5H<%zKabf9@@!`2+t`S43AZ@Y@0$)yb$V`!9BTxg(XiS3{B)nmWT2H>1$r)mq-A zazzf(yO$xxW{LdL8u)t!r0OyuvN-~V3m}U_ygN#+8On3R1UzBV)wZ>6=x&ye&BFHHRESw zpV2MlL*UV|Sv-znt5iZlB@v7@MH!pFLHO&dJ^wVCy3><5=&G^{So0(Innm z{_J%E{^U|qBOD2Mt^-E_uJe28D2@ffQJ8cf2jl8)xL+xP)oNDLkxmCP?FM5E!Mr6r#+wggW~6aZHpxTXVx ztMkr(ZK(HZ;^aMU%1 ze;T0vI)Xa|byyhA4esk|=ltF|Y3EFI&UrXGI(iOno5OY{;3Ez^4e*9*Esqw!J+3qG zB*2SqGw=jJ{ej^)4|W9gg2LN*p(g1BT2PvvC$YM0tDSFYNj>@c+6BNCJ^y|Awpy** z^rvW3af?J_ohl<1{fWVCX4gV>WRbYZh)aa3A`w7V<&m+aJl`mKkeu*Ud%)fw6$s|P zgdd&x3nqoAGj{>QI5UZ!%Q(^I@JD7T>!ZHaq1GxcN_qVG$7Z)(HHIA^#W zubK5zSVEzd7TcQ^9qFQ~)D&JD&nkb{uH=Qn$S@qa07xNu+r)Ejlzc!n4C}feigihC z3q?*!qz0JT#7{hLJa`H7#`j=8Cc=zP(BViPwqJvJC-QZgL9x2(^(ZRIXa+d4c#-== zh-DmPm5Yxv*i!VP%T%S*Dm(S>cr3?&(Do>J0bjYf@g7O|=xTMj#tG`&v`PN3|$3{f$00(Ee`M0&iqmn@^_#k$j< z-^8gVyB3fO4f`xE1+n^7d=|Kg5ywXV=mwXcU61^*C2{8##GRBMcLT+ZESqyq>-uX! zzsozdE7=w5my7!0-&Z8U9EWa~KjS9h%4ccPX?9h6&OINds|;VcElDIfthDPfa6zEQ zNzQ7c?M^=7m5)y|66$@v)lNke>kKQ_)lwpOK>?h1_2FI#$!qB!wi1nXP;fUv@fiQ& zBt)+5vP!xxG1?VF3mS3h2VD1xB^g4zL+P@(4fvyRrvQv?~S0ns6d=I*1 zhzN5lAgMMBw{~&N+EKTw+)luPo4JNt39j`Cj2AL}86vnzQdg0d+oCNx)I5IC{nU@? zb&~4IA7$JFK@)DZOYSdiflbj`y1T)zuQHNvtO)5~Js;1%CHMjJa#X9qTeqw?vyKJG ztQvl1+XS{J+ew^eS4LcoZuzy8GZG8xx{bt?B2vqTzyCI=e_v<8yaryRR}@mop|RG1 z^>o2}Bu#}wxJSB~Xj2IfxBgD$b$gcKwuAuRLxApPpN1P-Lky7of~Qi&o@>aHtft{7 z#`ty(hgx|lvgKLPrmHp;O=%TvTkge=_5_Be`<&AuV)Z}494G1}NZ(O{^*=+|olBUC zwhzG;5vN@_eD6j@{|{1FAHEd#Y29HnUtSAyydIZV)vM7cp;&jxYh;es)$*E@al-2d}u z=knA28}MO>97^J(DNSXtv`Z)|3HPnRmW#TKmjI#>f}G2h*ms+eCuMh=qx)O8$($+d z!H05)=ex~Ta2dUm{gbsR2kD6N^~n^__IEGeocb%&UmcZ-W3R`0-Nk+`j{S>4ro=1D zPVpkllhrM&^1J1q*a&C1%Sm%BY2smhm2Z-+xVj_Sg- z0TOD^jF#EH!aG}kkvBYZXN6medwo#L(bRsKszq2Ahhn0R)R^uw=qb^r|EA`w|GL%P zuvjNr@DJND^3{-1t*q-+6(`;Qxo-!gW;eeUbG#k)n=a36K8%{+-V?0}P6fYfg35uu z30fifr7l$M>q6h!){&fYuXaWj>n;39e6!#QW4&Jxogtg|PCD_3Sg+T+V!em(f%RTI z-LhRV7RM>8&izCfu2OJk@amIwsbRO+SgO?Vq_sxVg zldCb^pgy9KjC}`FnANm=K#xooy5m?(U1u-2y9Tb!7-RX8YX+^&9H=;O=yd^uba34q z+7v;f&qV-HY9ulnKXz%8_!;~YnI)Dm=6;}-eQdV1?AIhJL+>EOroOS8MxvIDMGy#N z-3vETw_OL$sHr{~ligHHDy^x`R0Q5H@$r09t^GYsbps1gXrWaFPy0FDnAB(FZ2cP7 zr0ww2FAAFK1iVOF<(g{A68oy=elzMyQ&mSzb-BY=ITV+QqonNspcUnVO3^aC{u9T8L+_4EE?>>RMKtStqyLFWZ880ayf69> zo@MkugQP;^c+eN~5JxQ`=J-49C#U61EB$De(3Y?Cy{sW4P-bF8Py zG_N_%@y&4=(^A;WWnzj<*II{C`7J?2<@E~A$z*HIbvOXcwTAM@ZLW&()?9O#tK;Un za-o`Q@?)go>>o*Un=5+_k`9g`8UrjdQYyUdOIC%C%ovSSwqm~WmBP?p#G!|CaF+`Cw7O`&G}Dj{j&xaCY5ustNHFzxjs#24 zw<`r2K&mMc6j`qP_3ESs$ESmSSv42|y6|GII|vWsSh9#ox#NY!Sctug&*?2!ublAV zgm2)(Z{=`tl3rymSJ`i$Y2>o9f5IhFq*!#UD|@3WJI(h;N|ZDorRHF-2niF^Tm{7i(yd zSmz|M%3Q3?io`n5#ggG?eE(Nbg~|qs80*`bFxGa1uimvflvdJTM{qC@HaiD+4`{!i z2hI2;?mY&?#L(5Owcm@M3 z*TmwnkYVpbtl)`kk#cSk)C*e;ruJ)J%;s&WHrAO9P!MUowOcf*R#Odey)}*QpSONZSPh$x6f~WVxc{_j5q0< z$||PMub2gz9iMd9$)X)9{aI^WcG@1r(x#hAOAuoeJ=JrZto9Y0zss3x)8JXWU)$wzi>UA~`J*9EY*P*;KnVEar zrh3;$D(>7ViGPzUFW4HS_BoapPZE)$_seY9O@u%A2-%{X-s@2AJk(;Q8R(id{bx?b z&kQceh$?%Fj1`KF!Nt|B8cB+l;(pFu(G>;|TI$N^3@EA?XltB@H=v-=jE^=y!!%_Q zw;Fz^;lM_#xOU1j9GFM>RB#6J6@iP9x7@r2!t~#VC$1}POkMKgdK%& z)*o=M`)qsi6u?UyI2Q0Tz>eSyARL8h5B4}**#jJd>+JzX`90V>_DS-yeSC_^Tw)ij zrGxKAGdxjM*#mqIjKXmfaOA40i`xUh+*xxHL*0W}xNdW}-uO#*xYh{|b1ZN2qc=E^ zeTlPEmXsH7Y9HhgYg2n4hxptA#L=dqyHj$ zJ_CfKFwyf-T&AUI4Ds5P)A?T%pagJ7cZzBtA)f{Z!3fMJB0pvz+fZ_JS)YX)a+ zs-?Pa=f~PD_vmiDiT0rOhl52jb%vYJ$VZ!izw_mgbeAv8EE;FROmx(tY?d+;f>*Nx zf?E%>a_2v8@Fy2ZTZ!$#c;eW!Um1z4Ge=u|za8hd_}&Zi;||Y{`%}e@ zw)iwO(rw+swK*M&Os4fI?a~u?w9#>gxE{sU+mv6kJnIav_>SVX2m2`?9sJyfCtGjF zDw^~%4FpLoXZ>{l|@+7`R~Pj#vL9%e-RoCEbyITUav0Y85vcbBpb+Gy{>LxzY1(Mc{rZAJ3~Zf69Oe z7N?T@wcWDp&KLW=inkUTPl2`n&9st@_^j??f}Zn*skKVOP1%ZwIO4!?Iph@E<;j~b zP+0bh5A-w~4#v3Br~FPdJU$8=M3`t8X@UoxU~iD4lvr-9AP;J?0Q$I^l=nztd6nmL^fTym_9)60^{hSZP4HFkrbwN^RXE!q zH>em<+h`oHCc!nHe?-&kO#ZtHI*sm(h1trIo*x!bmVEI+qQ8)`WZw_HvgE_8fZpLd zd`Yo!boe+>ma?Rp!g*!M(C`n0Wp+0wY8v7E_5+V|N)FD8JWlO)vtuS5WSQ-Dy9*}$ zXlJ!c2jAXF8+t|IIZsPq56-9Q)W=@D!Re+tf&=fOFrZ1c%PYlhZCq9@%7_;pa(MI+ zZV#UDD%L~3uoZ1*5HEbLJm##5w&#gRUTaxi!2q0eu;T%gCD;Ub)>1uWvse$=+`NrA zaG?tH!LJRazt?CjFmw$8v9t$VVm@cW!crSw)>gn41f+vEeg#HbtUWkx<*h3V*B)bCdb1%^J}!%7-O!})n7U`N zZirS}Zl|_jX?(RN2fxft15>^0Z!4&tUj;XWW8O^0-POX)-?AIvt8F9u(|4GWPoX|e zBz(n+CQX9a_WMoKR`&&w+}gtxWX*ztWXr9qL1Sx9(Qnjmsdpr|-hXY9Up#J^n^^HGF_KRqdzg{S@9vG6FgPto!jGrw+G_+FP@ zEZh;CcZ-|X^4Hjt@-n%@XR?f@jWXf&jOGOcik5L`Uh)Th^2c(MuS#+~0g<13@4V!X z`sC+iC0|(;pJf?97k5>>;g7|uc&m#P4+T&8OscXnp^Aqoc~Kp~2qB33`hMudv--MD z1WZH5bqc4p+7@8xP`S|ZEQ!9dRU2(Gu!#|8C*ZgQ9PB|wp5$TO1S(K|4N27c1e^+} z0Z=Cd+-o>9$LTXV${s#)U;>n8~I=;H91J`G;+5T^gTk{~kAGd4+rt7CJ$-+Na62L)+(N?MesjYT6pQ5VL$tLpvxsbzLTBr3emPd0|A!J`4(^3$! zK9e5^#Qqi2ojYM+B};~hyHHWxP)bN?MO#Di)uWGsocPM?B ztkk zhMgAda+2!y%gb5c(C#NUT378oV}I4@EDS-cLwB77lr$GFTes{=?B2u%>^)s z9ARjy)!aajx*jJriO{9EgzB3YyA*or>U;};Y2@ugo2SOP)qq_rHH1(V$y{42)+$5O zX1KJ?5}4g!L_AGK%_UF7N!%!S@^4UZxabq+l!CTN(dg6WQkg?v&u6SsG*2RT=4el^ zGCcN`#|V#UpsRxaD)D*qX=MfJu!G^_$E=>-Dr4doOu8|Ji87EVZW88>e9B~-ihf%Q zIfK2e&TuHibxIcVnc!cX_ z@v);C6%%!cyLmF&q?u(vvm)7TqeEyOd8>dYncAk$`iw>1&&$mVVt#))3r8dz{hhkU zIJR^+-h3q=N6ov@1p2bOJZHP#Ay3CIv`x@e_6XHwjQ^yCL)OZl9j=;Wt)y~5M?p^5pnGY%jHq)>Q(tKMZ*BMz3|CAL?TkVJV(A08L zXJ`hhq%gC?g;Ckvr8iv*7!1H2DjI))i#!;ipS3mqBI@jeTnAV{1o5}IaP0kj&yquvRmge zQc_EmJF_tu1vF1Zi&I)Tcqy$P>72U&pFR2V785l%uVvD#XajDzi z4YyIzD3LoK-s6x9nn15camQon2@lZr1>Pg#}UP+ zENNM%I5D3VCzE`h%1xUt{gs;8Ms0b;D&1)#Y{YZ9xON@*WR&fZ^IWk?=83Z$D!ZMc z_ph@FesKY_{R6BTHly6v5FbXR89!J3>fqlv11DC6iwV^;5ntKe9HG=0=!%zS2GZ3Q zH&2y$&{Dm5w{@$o>`Z({)P6Nd@98a;wj%MCpej9H>l|lmP{#&lIoVVx8!bXDyWmK_ zeA3%;qY<{rQumXTm$dc|cl@j**4Xx%u@R$OW=-FL1_?&v z=)zMnVTECt)ytJ#Ntx4>TQb*kKJJ4sk99X*^&p<;5Z6%#7Wow#XE6JL6u~G;%9kvO z?Cg89vP0q0Qd^_@Rmm6~{4h|Jk?~-cp_zA>v9V%VYV!E|Y9&V72I=7&QY{S%K?dTV zCJ}V`7%AC)$Y}8ko_ur9zL*5m80m=?l%rYI&MF7Rz;Y|A7>z1MQXH9IXr}-|uul;c zX=wXWq5r105n`~i;M3-NE)?jgv;y4#zfU7@bO+ zMEV1qW`M*Wf+hvySgzoE3%>Mbfp_2xA2wtkZO@DXmfyv4`IFyh0r*Xk%b)zl3cydg zIQ_}*bOHEHmCK(Nuj2&p2Y8QzD972g!-ugH624)R!LN0ZGSodsqaer#5ql&xtZAO? zPH8!wntXQc>4La}pU5={7p1eQtPUSv&M0B~a1I%I9K+!$4>py{ zcFldX53eMVYL)o(i@@~oqzp~{vJ+L2NKG5XY#$D%Mmf3o z5~z?a!RdtwYO)iYKmtV>rRIKMxceBbk6Zi)oX5k`{sZpp3@_q?dW*T(ZkU0i@u6VH zE!_2W>*>+4s>@U;1|D*YH?SDjU~sy5Dc!4z2w6k+BdnM-)|WDKQ)D)`5QS4=HAG~X ze27rAI)9SGVrOmOo6Spuuam+q+lLMMMK4()szIayy^kwIGN6DqtOyshhBL+m?z6OAl<_K(QE5#$`4X1oMx}^cSSgkXcR8MuJMFfM)qqQ)bLZ z<0`_`k%eZYYGt80C)K)b_-v0J(HvA=(%PF~+fvF@5uutcCJ(Z}>ex+4Bb2ZNqrA@G zCT<#iaLJyGKEd^XTYYZeHGo_Hb5F~lhs8S$pCPaBrFboXtG#C6Nq`T|-^;0F{fx$( zqG5(C*sa}eb`64-S~V5kPfKS8i9gCJ9%cu7PBRm5Sr3|Ga2)4i&l-wx3|b7EjGt#H zH)Fh<1~v*L_=w%oxN_uMgFMz+Vs2YnalPjH$DQQvrek-oyIccwWz8|ii-T%a`mQJV zq3E@e|#B!ut&25uclJxF*nT6bHO?a-DxG9pRAtIkiaXux=$BPY(u1!fzcd%)nA1c_h;$f>0uo{%~ z3*+=p{KA#f$D2b*uCt}7l1^{xAsP36h}TK!Ma0b3v-`at@k(2im|35?y+ZMZ`*YU6 z0tuC=bCm&8z%H+7=avF9t&ZLsr87ds5lfw6QSgrv}PT^P0Eqvyj1bxre zo$RAIJ=UyLE7Q&Wy~l9wv#@4p3Wl~X)@W7}lWr)vXMU2P>CrmSeLRdgeB4~_)OyG4 z)8lk~RchbfuA?cLYwy|f<7odF7Bwp*(Ej?;o-N1mbKa_S!2VsYL7@ptOIuoY9tTu0 zac&mHN{LQU7st46%)-@^EtEFth@+DCbg}C`h`A})~~h|Wsg-H>UnYO{=}wPs`GiO+VRw!_$FN&B>V_x)JZq>(2TL2qm{nk zm1mc)STTD+jQ!!CJCY%DH1$^awd#=-vlqrOt|UfQf(w+u#yp17rIOYc3;)vQPUr)L zkZ-(ODYvu9COa2}n!*s3`rzhN7`3^i`HA<+npb^RJj?lr%H~z)wRA} zZX_*3u<~9KNrXal*k&`EPTjE0n+-{9gf54G>NHMxvVENoq?s_MM@*hIHZ4g_?q~UD5wJ?i{jGhuC_{d#w`*Cb zO-<63clC%O7o$|2qrq^aI0sj3ypx;?8QPt%t7y*x3cai$@orDlqRr5djl2N{ltoT4 z;6 z)6+l5`NfcBE2dZix|JtfuTrg7Rj&CvmkHL1q_A&}~mFvAK!NX-Foq`iiSfJ(_JLVGDO(-h#54 zwNRX!%9T^xq4~v~FlQ@G7nL8g(R0||c5q`|#i@bwEMzT(>}esb|LJNRnPu$J_|yyu zR8Khx>upI`3%!K3L@gXWw6Y{elqry~7OIY+iX0{q*3zu+`4OBgVJ(+@^EL!tdiJ&v zxcs~U7B!Ni-rhn(Y@r;Lsby+dV&mAtSaw?CWv8DuaN! zp^B<;AHBS2HI7mJT!Lno@`qPL+=88})MvEr0-;%;76{?r@X^Ixn_W?n{% z9@c?eP{w4r?q_7if#pgWx^ZB+jRUQ>+L)D>^Fqa2sM(ysbi&f0qHP(J1UPR8y`s_f zgnjimZw=&<(G!*;R^6!X^>_2`S<&{O0i_jflD@l8(5H6R%vjMjDFV-1)1S8M@U98`L}ijN9!uRiOuF1@VRLAMQfm$qltQH|D#_R| zwU9=Um^@)ld8X0fOFRZ><;oeH(hhNv#u;i zm#%0v33`E(ql~y+f+vir{ZPlLmNG(ocy2}WjQ)7?H}3zV?tS3ntg8I~Nt&eyld2sZv4MH$$?@vvsOHE~;fYJE%h zWHGj}e2komGw?of+EE68Ids3KX&XIOD|g*@M#E^cxg%6tBekLSrZbdsS%^Fl%`m%p zXE$031jNX&?)@+!cs*6TZid%Wt9X4EsU%Dt&1qbEQ(fvBNqAe0(o zx2?|8`!yxqNfyqd)E4;PJi2tiV*ZPFj&CwEj&|ss-_jh|kCtG507HsmUb4v(eO2C2 z_0?nOtGTQAbKNuq>$UXL+?z}Kh^!`5SJ)J)bOW!}H*=l#xUSLrWwZComz3Y>o$?&- zl(Vf<=FTmjulh{~NkeR?FTdI&Y{E`Nx_okNM9W$>!=%bAW_eEaV>U?CcCP=ie3@uT z##B*|uiG*8{-2hw20F<9nS5RU_*Pm9DVtSU##w|U9wje|{Og-}p0Gjo)e=I?7Q_0( z;$dIMP!u~?l*UiV%M?)ZR}`?&>Nq5U^|)_ZNSQTq=%=vhgAndfBtOLu@|1n2^*@Da z?^(Mxf;883#I)WaT;>h*wcM)mc)!J-E3NMAK#p|~+{U6p%Ns&BTGY7UM+$49gesRH zSgeS}UAgq~I#MH+lpa$)kX^-7KV?~(9nfMH?s+dg*RpKRol0aE8Xvw{*Ks98p;aFK z57py&Gi!XEWASNq_1(-b`&z`T#dPoP{e-8=SDvjr%Wu=_ht-%nCd$Z&P&rQm;8BmJ zw9}wwRXE2!Y^}_}Qsoy*rNNq6637qF;gf!#(?f#DSf(yzhZ6b^ku^$`EgcE5>_E6r z4n8gwUeB@HMLb*T42W}Xlj;Y5FLb5J)}rjorkk+k(#5H#Vp&~(pU8@bgW&tk^nFM* zQEdYzUn|(;mf0J_d?TEhky}tnEOfL8!1R=ZD+Yub%Qi`8uRSvwYFa2MX@&$7m!>Gt zszC7suDVveh>7KxE_XuM+4*bRYo=?nxNC_eI?PwlNWV9g3aiU}@c;p7qDDEbnS@vo zRJ_&S8B)Jn+J zmtzfL)G&6vNM_Jv#CFjL4q;1O1+hbOhle*W30R->oOP*ZrOyY^>>W8I(=S_GP1G)I6zH&k z>jI($ZN08{gV{nIl7;rnnnpc4Wc2Aqla33qgw2c|=_igr@8$ss(5w*8%CWt6x%m;|5J!_ry-FYb;O#j0;Hp; zSWxUf+>j_6UyM@CcQGlOy3>}z=CX@Y+|(dTG<*WJS&ezfNiN*YLeFHZe8MQ8r(c!? zQs2Q4vPasoXmDufJ*f)o)N8K4Pbwzz1u%1s_H`6@a*=7)WxzcGw!uH1LXYnekP8;2 zPczyqm|CJ;bUE_^m@@2nF6^`~A1NL-6jHIP)EI0)Z;60>I$N`t=$1d`_t14u^1b=t z;>Y>MS+VQJ2^wai@8MnlcqjBpg*HLj^x{mTs;@pGtiSP6VU30v zH^0|Y!TWx3Zg>p5uNOhPD+kOBU++urV;hyavPBJ8>sTL~1PiF~C`yx1A_)>m-t?&O zc=_NWSj=8S0o8HN;{Duz;&0(1C%)5do7uLQ@Ul_sQ;fa?eJ#yokbrF`p531(@(Lmd zVP=h7?%q8R&Z)LSyckG^U6VTNH^CVv@tuy$j^&Ko)G-0Gz-xfQHnQg%byngeLd*57 zqmXvMvsbqg!7|1QLr3Td-F1)#j^+Tkb>#&0%BX{uuh|Wswa_}<&7Q}&dRF+)OW+TY ztc-hH9Zrgnij8kj5dw_B5dt$opu*?ZfN?dSFQE&<$MdKJ{;se|oajxq*xQl(!-x74gnRAqhf zd9H}m0KiDdm%ZRn{ce;bL+JXoR8_p;SW2(-nPszhrJw~GwicwK4*hL)rQy`}QOGS3 z*3`FPNTrFi>)16%m(E<}+g;Mdds)RPK6;%PVEguL9~OU*A|z#@c4f_PSztJuG25uy zM{SL$)1`EA{!BL$Hg%*e&>4A*8+Iq8)M%sAJFRWzQI}%YO;K}rs~w9Gh@xGh7Ak#M z@rCs3m!Xd4Go!iqLDZ4m`Q}TNUE)etDrXDnU33kdbgy?|d=pI|=lZ2$2bfC?d6NwC zAm5TyH{R{}0RY!~Yj$8BZ-!Aq9zXptcr zYq}kb^?ZO#Thf<;MJ$esvI&pD5>igsP+a(!B($%kRe-1iJt=c{a>`*20O>`YJbsz$ z`m#I;^9euy&kDVf&@*SzI~NeRo9CN&9>Md?Jdfk~7M{oQT*&i3dA^nBM|fVy^HV%8 z;(5M$X%hisWFf+_=QfRT@UnjCnNMzNNP>{%J3kCwv1@B8~&Y5q?oAW}goU_wNQgbAz55|%}n zwhC``nLGcc-N$_`?V&?y0Zr+CRySjt#Hzm~^{zL7E9)qnjvL0cMZ{TO$J?D& zrYp@8Df~)xbgh_uD=ogVBWr7%BE~-5;*1r$=HyxPd0^ezQ4C$(BI*M}zpj@ALq979 z*D^GB;aJ?dlTBOWbL&02$GVzZ+Ndn5va1&7=bt$RgFm+NU8f|(p zYfU{g?+^%@IzY-N4%R1Neur2`!&wrk$=a3xo}8@CR|mfSzNJJb&V$KLvF_;;sV`q7 zdd;cB&eh=5xzL?DuPDEP5y_!lcz?|;I_0x)q`aC>F5urepeFqfeTU@5mR| zRDTq_*_hpl_C@S3?K3p-sYZC=M4tapeS^#Z{dof4DaJrSG$3 zp`yZ;?Wu*NL3B{~I{`jLAirw>#84LWCo0K?@#LKCR8c<{#*_4UCD*%pJtVh(^7YV6 zee0H*u zkj+l4emnYdervXHKFYV#uj-5l>OR(T4|mv7t>Ze}ktV;fsf|r?%D_SQ{+=UTNnKpOMFoR#ld9m!F=Zd<<9DaHRtb_Sz`&Ws7ffD zf1sdE3Lqt{Z4}NwOtGAcpm10zhFQ3j*AO@ml=M$-(6p(-!Wo(V$AMfwl|RMO;Vv&7 zg6K%dOY@P^M`Os#LnH)wF{AYb$xFw0@)N|$~d;z~yc=XfMC=}iA$Bvi1cLp`Mvhhv+xjCz3OeL)m;jz>`^ zlPN>8(~*=N7m#cUNJ0)vD`Bl(HVGtKr;^IvFvE36VN(Ijw*F9&7%e{WtGt?3ydCgeV| ze4uv%-H*~34f;;EHeF#gIAnt4uL4q^4^;sp&#$%*Y0jN{6U>FzOP?=<^#a9&UqjrBie{`H4=k`h(u$T^i>e zg3|KzxItTy25Zpr1u6%j=xgbLEu$yC&%?x;iSJ(zGv+LLymnCej?_valyv=lG6gCt zjAjq~>qBl2G_9A`FTU+i=YOLkQ5m;Zc@^77RdJqG0mfL)^fL=gG`XS-mRU1*d|VE` zFdk_Wn4b}eO%jCtXYas=!YPB`&-~RP;~=rWBeC=kwRGOE1g~4Z7DIwhst0T);yjoI zb*b{{RCXbiff&o^HBOJ_u!6x>RAv?Aot3{wf3vHW&zmp_PsJ?AN*_aZR!C;~ruJ_| zUJ8{MI#Af?R&^|uZB#ZsFyM5AT~`scPaN#jHVfV6gvcNDA`*ruu=ZucsM)ZZ%gWKkh zVf4P%jow-1v#8a$(d0(&yR=LBinP5-8evQxS)?{k>K9Q(mG4#P9y0&PU=2Eu zxlFAtoXI*|e93_oi}f(CuBPN;@H>@$Z}SK9BL^$c>^wP&%?ix)YZu^pZS^Uh(BzHR zp-PhD_7Zg@#_cC+MfGs{J^JcP?=mbQ$mN~0WEI9WvQH3no{#VFf`P!I#wFJ$}NFc*8qSdaDHd+@7>!fsal>TDtQI$5w zI=PT>iuTcvsh{h|IR}nI@G|w{u?T)CoCpLPTX)gQI3Op+tdAOQyym{;+yuQz`3Noj zIui$1{RuL>GbHStrR6gfx0F$Tf?Q`k(AsUg*<~b(`k+FD9n<^>*fx?ZW%@6WI?2=0 zuyf?LAY2uOmk$`l@cv*9Mq-6E%&|~22b(32H(xVB#-RE@owI(^bZ331Fz8I^$-h~1 zj?vX_4>FCD`hU`~UO7*k4%?*g8fdza>Yl33t8G9GD~3{NgAG|GlXj3XOib(yrcV_O zMD~~R>9*rgDD=MjPY}8xN;49LwE(d>Q0nub8Oy7AoyO^)2rsxA%PT<1*KBhq0fqEe zkS>RsVeEbm1EIbJ;wBVWl1hZBWD{rU8O_90+F}KFF4b5ZdG&+gRB@Dg>ri8;flB|P z<|GugFm_%+QB>*^@k9;Z0nyOf6TG#z?&q!Dr6Q7sV8&}6tyniHLBRjB)}D6`c+o_{ zQM@x;qh;%#D$)=_zd+deM@Nlg)?QWPtXmeWJ@lv_@$@Zx){3ElJ|&o_5^o@@mj+rR z1|)e!wbnpgqZ_Dv)u;w4TKkUCKwnT_6baD?n*7>m7Xx~7zr{y??ABqs4{y~egpHFSNI53$Kq`4IbmnD7H79)3n%|l zUtOTQwi>7QqmMa!R*6&&kbJ^k*lT}L+2_G|bW9rQmQ`EBK9AC;nVf`t*_V*KAbata zEZa%K2as4^AK)t1u+g^B%lz8o;>npzHuw)&&ATq3ZnJ4t`cL1^&?CTdoZ12~H8M<` zqixX(>h8xJ*mV^#j_ipEM4FxSD9%DKowDoPR_7Gy(+Y>)%dEhsm+#v%oT+0hoRNdd z78-_#g&bymHuRw&7-Gz0L?IIMsmrf?HjHU|20HvI}mI*tydbQC z=r}RLD&Kh`(}ejp`w8S>JI@cUZ5fxw10M`J$OuLYdw*Yd%9ieM78&V$?msH`eRi2& zxwSa?e(#43aH&Zh$D9-((-Z_2NoD1$djAtHTwH9(Jeg)Fll#9ACX>FXD_3MaNFO-7 za+)iN-N4#1)-+(DIy(02jRx7_*zXE4iE`8w!^KDTi3%R>c!_X|Qmtd&n@DX;ro!{# z;+GStMh~?%8Lu1S6JUZ-TQ zDVq0YHA!LOq$_xsG%+ths_gEddHJa=Qtj0+zm4^L8f$^q1E%FUak30fM~&<;cvqjk;BCYH$xFk>{tD5!0c1gTG9#McVasgBU3m4eLes!_5QGH-LO>E z*$~YiLj>7b=rN%HusD>FfPE>ZY!^rav)ek;*G@&4{^FT6>;k3=A~U##^(s52cjMkD zYMbgSN^Rg#$hI^prYim3=)YjY&YgoHg0n`vMPzlCMCAf9v{2YIdjS!4ootE1en>Sk z+9D!^u2P1kQm;6gn~L(up9z^pI9pv4`hRcIFla~Xe`Tu0_G|0G&#~v$Um*)GmsQK} zvfPznB9uI0brcg#s)rOz87r4JyZ?tVY;Ma*cx6wNYxZT<+O$koV@}H$eM;Ke%qE=` zZHM!vchOS@<2D>cez!=>pUFPS^!fTM0>qzYr@Yti3xkSpv}76ERM^E-_P95kHQZ7E z>a&lVGu+W|?%A`J4R=gEZqB)9Z|Z1Fl?Kc%NbltZW%{o5_h-Y`5DuP1UG!HgU%Vfg zqRRVPdej!|_X%)MrWK8b*=N0C3IV|VJabLqr@tIvzc1L{4g1Aq-eP4&7!UPq_l;Qt z4ZuO1&1=nC-u3QM&DR(!$0FGpp=+oRN`6@=`E+BE6vUpFJm*|o!}Vv+Vk3c>{9;5Z z$C*thd1#gx1EWs4UkqB=(xZ2^MCc&Hlc6f+5BEQb!)O=5>1VJ*9}Aey+>2D?X-T5VkIRk~hr#qWqgs#cO8FCAQM8vG;NY)Y%}B_Hp7Hl{zIHnoW14ja>zv8vK<2?9>X zl}fJhf5n|&He%ftM9T)cWan4P(0<@01N;Q@T=L5z!N$i-sY)Mk&+( zD_X&aH!hkb+6_Q+mZKF8m)C#>JY1MG*b$B}lbrW1ueyQ3)sBAptxpdcU?FRxEq`pP z)#Tml?PtLm3TyJhP)sn&CJsAAhdJu~oSfM#m@FJ#8D+9Sh4!m+lSy;2OKOppSgoQ+ z@TVO%AJpgx(iD;2ah^}*8i#=sWOTk&d5XkD@qPBq-RRA%q4dvQhx^{kx!uZ1-$RUA zc~nG~dy?A(6Q2;t*)e)eX6h zJ*(ZoVZhVB2G3RQciKp0S6)hZYp&ir8Tdu)I^!&WGR=LX{5x}>^wxBWe> z8({{={KAEgQA)DOFMPpG&i1aPkjw~8K8BElR?YN1sdfl*wL2-sS2aW+YYR~!q+wbZ&t!g0OUg6anML_Si0LWqo3ddeA5 zol*p=IMky-S4OLd-L5B>a8xdr93cij3@tAh{mSfsi8jAmM6$p)p^L)wEZX<}#yT5h zRxv{RA=T)9kbNeQFd%afOjbiUmBcD(`rjk8N%_1L+!F2g5^z@E3eq-e@(*XOcmd#G ze9K+z5!|$=d9q9fAvJF3l^0LYrQc(;wMOr1MQ}29#GW+tk4zD0W(0Z{Ec$hVfAff9%SxrOMr{Nu_R9(Tc?e+HvJ~)!4cM6UApZg(qoiA3`N^8$wO=7m2pb$bjtkEKLB6 z5CgxP1AgU~AqINUMI)YysGoro$XIkRRzE*N)EnahGeC8$Qfb#(2hayC^} zR9X+HE!6Q`WO}fN5Vq8~vY3_3_|BfEQSK8m z%!yi`GGZTX z@WlofEagiO)xy&ZA@h{>wXiJ&R-nM>GO9%Y+L9*rEVDG5z3A1Y2UVqM69jFy+VE?? z$-%w+;o`H96?OTw6p`GBUDM@{{f^60kJY%MMbF)L`Q--fIM;UbS5}DI1EwVCW)*=> z`_`wu(+;YNXmK*yzdSf1rJA~#HmtT{UPD)>)issXul#Dbr5Cz5#nQ{IxWdT~&C%pf zODVp)K&K$?n7=Q#iMlxdiB69rn$}ltcN>Rxq4jO1{Dlo1?73O0{Z*}hLYAn>3diyA z>gsl!+k)fLeI(gJ+=$M*s1Z#FhKqALqeX(MeR8_uJ*R!l>1je72gU)aqQN)!A9N}z zFukKgByqFA9UN2Qc2u=RTJ0fz&49p*BN0+Gj~Bgh9?+ITSHmobuFjx{LK@ zknnE3S1kWwzhCRm%ek3V{qegkm?I=9DI@BI+!cA z@a*!#nU{dpd~E2Qr758f$QxYhj+y!Ds9QvHv$8hZsA9rEDe;Cgh0Wo%nX4~8dRN#r zCE&#@`CXFf-#?DJ15;l(aPzX3*1JZ}I1n#gzsF4!_hkBi7&Zi%JoP-0xaWly=yE~E zUun2Wh(M=bQ~$8orOZ`gekZ#~*ks`G0a+h_&b zYS#vB3vHiWTi9o}lG|A>V?)LJ)%cam7TwNtX%d<2yOKo~AvR(5genT(8K1>B1qB9d)6zrfngkpnkB#hqCFrLO1 ziTuxI-kaZg%01V-X%`vuo7t*uV_i~3^oJFVS{2d#1{IYpUp^SFB zR(quuC1Ue^g#7Mps2k>uVKo+iQMqxjyw6~H%3#H@FHNib8kM@3z7jNbb_~-6w+4H4 zj-2r(tKraYf00YQL7M=IFJA2$tr_`hH~At!hX)VX*ObaN=*jmW5KyF0zaG1mn%KsP z?@Pu$PMRto$nFpgCmB*s$R!LKh8Ob>yT-Dh1;&$3*(j+v)JmmTt}^h3@}V~$Y$wxx zHfgkBL&Y{jYh!*;%;Sv|S)(kp77-@y+6nZ|k z<%6=8^%aN3r`(e}O@uV5WGko8vsx&d0E++>s>W}1DrVja`9XlYKZMK8g{taWzjmV_ z-SYC$mhN$Fl%3v>6e`68q??yR&EP4Q!Pba#3q;N60~W)@8(7JaC8+`B-mtsl=ITPM z+cUGmB^=tpO3UfE#$U4cJjPseyH>HBrcXTnoUWMZ!o*#Aa`IG%+tYle37wq01mjOn zVCVkz9lNx1wLZ#l(s@L5v(-_9sNPvzO*5T3(CL2kBh#Ov4J%Enj*?BD4t{wV!@So% zdwBihn>CJ%cK5vW7Re;j7aL~SAIg(*cH{0@1r$@Q+j;0GPNA7yj=ii%l%tXp()@w1 zdzC#_C37P^VPd$$ZiSb9TPV9UY$6fBu*5WNQ(|)3<}!(Egw_l7$Fdk>AaV3oyUFw% zGkF!m{8G>O4n2Khhn>Lo2}x*-6kUmhDhN$~@ntmgN{jZH69Pf4@D^7}C{Itun$4CY zirz3uMq~Q>E`fHjzhmISYbK6;CugZ>5K2)3)mg~{S4_$hHmnEE!6U{Vr=J!Ze{Ujq zD!Bda#46l^2c?nX)KYd{-n<%ms|z&Nm60wd6D60vpCXv$it6Cw&;|oKD<}MnCEX{k zZ+j|IJ+~B*uz)QdH&EjHU^iBMHRF0fC|@mRN;GnDP>JF~C5JMdq9IJ6GJSnw+(2JT zGXPL&1J|zHDm2rp0JW+3fRra~@oFMs!WD6}3L|FFp7B&%qMR+X#r_nplgs`(DzkC* zon5$0%Qw3~yQk(K?K1s$vwD$#>j&ez4Uv}MGJTuy8OLSXzmZNb+GTnv(UHsa*T2;? z|Nq!!TBAb5%8Ckc#wJwAsb6)DC*7n{AxEo$BM;a!q65*;yM87{rG9H~=_?&|z4*Nc z-`Ome>AvjJaF^){q`Uap-yJ47j73AS4# zxQVM^WO6K+7vz^+w(alt%f9aaKYrP>=X(1^Qu#I-#3YfWn6>as zw)n1HQ@_I|rmd=7Q`fj_>NVvn-9FX`99&cHeHw+mn5!%Lj<*{;bPv4d1MGrKdZ~)6 zdX-N%RLbo@zj2q)tRn3!@9WTGxvx4fEvDwTYg1uE@!`*^dtw@zRt2@)e>S5zSX=%j zh$;3hfYJr<$KnzEX>#v0Tp3bMi&9ufnW3w`Y!wN!jiH@rMsp+|EWM~gB{c?+!;N9%?!RM6_a(RdrXLhTGtemm1rCUeNHgsQ37|7pjs z{RKEgA!UK|H_uKZ$v*H!2@y%1F-b0fkRXbh>|={kX{qvwqLs;cg&gw7<3&)_ZGItYw%CF`M^u6b%L~~Wsrz_skbCib8HOj@VlVmBhl<`7BRz24;!~u~z32GSXw$m!_(b*X#Rg-nv|?yKb17 z`Ei>LaMosTS}rQi?}K>bRWXRw!yIU(aB~TDFclUC94@JWj%XAdQecD@$+P?E!7KpH3iXd zx&w7*>8I*`RE7XV%OjVJR#lQVuPM{_2d}S3^=105BR^z>w+Dz*Y0ajgt)H|-*0t4< zFs-+RvAaVe-$7BY2&hQDBkz4%a?k-s8+2R~b_6w@RsJmbpG$k?S@O$CvwqvBFG&^u z_FZD}!F-&R)J*>`fbsa>DIO`wW_^Y`BxsF*Gk>W*9DFw40N%yqEp(7&z_Tiqbi97m z4jxMX#a>{Y=;_S#=ajWZ9^=+YX;gwyou#z_YdM_9Ubv|+)faANja%xi8XRIgN^h+x zdW=<_rU24B_Nq>)KD1{|G8|=9=ZA6X9B4)3HFLw=iHHe`_(q(6kD0V#ADHxkkT2p2OJCV4 zuGHnm7lbcr6s-ut{0N6c&r-S4wb63cBZ`)yClhUBt7lrPlcWUxWH|@s zMi;*AElgUauUX|IQs2Y4l&O?%L|8#Ax;Yo&5plOg!rNM2tU|CtupJ$?dyd8I`I_4z zHVp+r>jp~)2PA1^UwUhWaXDLhYYj_p1HQ&3N@%;V%JymSi|ElR+xU`rkc|Bbn>g_k zGLBk;6X{lFBsW1qwJoXN;zLn$+B*;F>YSt6fzD;sENDzHjqa%Hdf;(w>XT!<bTr&h<- zdF-<4*fO1fq9uma2@i(efv+I_y2J7F&J{`N6JMmAKk3tn5f9#Yl6~i)IV`)G#TyRW zJiV{Y2++B{?ABzz$D0LRXQ+|n;8o?^EuuA zzHsP~vu&O8eV<^R^MnT0IXhnFd$w(b-*^>$U4Egf=MNU2UJs6i^z{-rO6BgDbhpAt z-M~-eX-&VKSN%x2I01D*fO>~R&5faq-usr^Yn@hpFdX;cme_yTM-Q+2SVf~GKYBPg z$jqx%t*0uPDCwAkBX4uW=v;*#0J8*uHW-N1MCE{l!dnvYsi+|0wzL|*(=!a5d?Q5=hdBhHVkkj18n8f-)a^Vme3(AOcZh`k| zi1OSRnhMqK@q3}?J}W!m0orP2@W0Cs(}cN;&PXfHS~JtXH!wpgdHs+0Q#@atB#;v4 zjCNXn^2h3DskO9M^-jxq%2h~zcR%Z!-TTHk<d zKd6HBD#473$q(Kx$|5!uR=V&MI4sh@{kphRbRnzLJ=}8}u=+(Y3AW63CEcv|fvagy7HbvGKakZCl}*Kmd-TSM z@6hVp#vSqsu9A>h)1wGBBIPcq0CRc#waVYu(hxXQohwj+$Vj8m*4Eg9P30O@jAcV< zF8BevV;u^EMXKmtRMF!o>m9&COZu@!iS^u;?R?J_oxHu!qh`Rr^my(l48k2|NpHuB za=8OS*2(r@A^wQIL9QLPz>t4Z8Wk7);>e*|pV)+wz9!VvR7P~nr5%^q6f7XSkPR1a zj|4&$pLnU93EVWb7|XCp z{$(~+rr(=!ez!UoS`(a&HW3*Yu=Hat%ov*sn2w#I0jeq6IiPG64%pYq8dABL0;6^& z5D8M7Y=<r@DwEaf83xnnO|3O=Upc^4Axw3hBAioMR0o zZLtHLCPQbqzQvw^q8GF{qmGz=L=I(a%1y-!tP92Mo$2$L%XFKKk;R%^HAPK*EKQBk zVOI%|ew+8$sk)yE39)Jz#@U71N7oSBizy`1%}%NZotwf|xVm#QzM zZ#s=Tj+>uJoCbM26>Unt0oc0ow6$nCU*ARfvaPf2Bm#~3dg37qVfQ9zR1#Mr% z1#Al&vNJ}MG?L00OGkoumD!k<{_E6MTM6_}&qqZsCUCs*)%eL1;an8M)k~20)id54+#P8U4oO@Ok5~ z4Ucv~J&nL+CbR~%Z-hst=s$$eGQJW|S(pXZ(T*=qM|ZWS!txk;i@heK71=h$ zbR6;#DW*qER>l~!SE+Du#>8VSv%$(*Fx~znyNbyrEWv;Wr|gyi)`=MRB;o2A-WbnP z9X+U4XRmWcWcpT`U?s`p!_i4*tQ8>%X4vH>d%%q5`<%`y(0b;sjS-861TmIb)2%9F z7DWr?4P#2ioqPSAjM+vd<1@xDsBQG2mkSGhK=+ZPRRij{E!Dbvgbp_W^0HAYe`7^{ z%wD=aNbB1T9%I_H&@0x9JL+-+SJ2cb&w+DDuuWlq9g5Nlu)4-jvqm<1D@$rHShN=* z72U`fhRRl(9F58Da~l3mc3)0o?}FW?8YL<+Gm_{GzFyW*emmEE6zLB(?(y7VXdjP| zJl?yl4%grznIRyKB}J~jRQ_lAdw%xY{MNn5^1vkkDT{$1-7tHHPjA;#z=%1FwER7F z&5Q1-=P6~ID&4{#lIzV{p_#5k2J##4`Aw4|v#avc`dF z-oN20eaUQUAnk;WRfT|EL!E|?$(hgVh}rE`d54-Q9|Zoym_obr@stPi^`BJbQfc#MVJveUL>^P(2{sEQuCIytBtQou6dGWJhs3wQNdX z#cN&pL;#wh`S%S9WbW8(z0&Q76E^2J1Y%FvLLoSqC|OjrXb|kZ1Z58?cY6`fa372v ztd@uk(xuy7#-#5^Fsvl)SVndsA%neb4&|zY=#G}s7a$VMXYpVxw87uTtLAc=s@W&Y zpX@|Klo3C7Q1X5DsiRcj58>r34ROtmfvNCw=s=cFyGbTSRackPov4m(HxUP!qodiY zY_;njUw{aSKt={FPvL?@A5X3RW_1=A|ImA@QKUwR0&NP&40xrT$vEA@vqiQxj)$8` z*=w$P8|TQnOvT@bp7(LxOFCREFBJ|9wF06`tBJ_&ORLM#IkJCeFNW#3j1RYGU5*(e zz(Ym1jfzix(#tRcn^o$a>(DUtA)C7@VwKbpCAF#fSS#;~JbecKVS&RWXS1MusQk@6 zQdIWN65p+*-YQZpiD+B-i^9klU@F$4N=oDZZmzqC9!lh-5vS; z7;2YBw_O`pC7ou@Qk$LHTa4X_MN%~gqEJpRy^732V^od_$ibL7w4sRVUc9U7p1}wm zGxJYDc+BcParZdYeU2Pd_iw0OI@3Jq{kH4?9<-sSlIH7`-*a}#9y?6tc1NK6IVIHU zU6EdXb)~ETdm%^!?5Ybn5MhKbzlD=Ll zvp95@AX6g{BCVeqitZ)p79zFzn#re+eVndYzWPpb%lnxs>iYZC?QCzwHj1-Rn)&z! z!upNpyaVJ{4q-cA+#fgA2aA!DsSxmb7Kh{q*q}0*$=fq>-SBQ62;R3Sou*)%j(|)U zcWO&r^H?drBL(-7u#qxr4C~(AKciGd((U+UaHGlvkHbZCKE1u35xI~q=|P4*7Sgo= zq>3bA;Aj~J*9wE{$aFiI;HF^hEU>=zi*TW^hKpP7P$SUM;i=X4Es0W|%@pZtYqI%9 zcq7&OTZ{5Wq$et_ADh5T|56*Y?sA8!Uq@~11CQ3Vlm$V0*Dvsb*51b3Tkd^>_R=)4 zL{Ot|weXo*p91^h)24)QC&D@vRTK;PDZDii-X6k4k3`V}D_fcgyNW$PnQFdbjZ07E z#>b+IcM9Jzr1}fOqLA*GXbn|$n)_^yl;+dNlTv)>WIDVbLTf}Be{z`?Hzd>cM25wYY+!+e z$m30j+F7NO)Af1P4iNXsTG8uLDmwCHt1!b8-+(L*#sY)N7PxaZKk7r<28skWhhgG- zL6GP!ebx>^RUHX0(XelUpWEwL8^xU{JmLfG_*`!C80wEW@%+ER2^-fv?(BRq|BH29 zBekE5+yq>iLx1T{?s3uoGG@_(ql$hvaEs~ULbh%k#{QZ;EMVOX2s)RYixmoH*Hp7^ z?Wh{|0wm5IoDmn9GXmGMn#!fa7)`_9f4fVEC8-?|BI^bYX6+ByzXY(Thr~!-f1kSE zTiz<8XNg(>t&5sR7;N2Dg4eEERW#v_D2%wYjU_I?v_&w8C$%c^jDW})h`kak4)be!vdYW6n@+L?Uk&-tTNPL!PCp#tXjz- zF4ZTp7?}@7MrPM#`o9o5)UJxs#6+s~)=<>hp(s&IQ4geSkY6h1DoUVVZ<@fsZ|#UT z8qAHG-Z%;hW|E{L$!NfgiJ888Z9`F|xL0Fh|G0zNC;`uV`R&7(y3wYRYj zbpZ~MsN{b@EnA^)<3%r>KMM*pQ|$!`n#I+I;yCnM#Vx)RsBWW-L}7AtSHSi6Eujg_yTEf1bNO(}+($>b65MJ)a&53p0cK%rCxzwT zUI53610{`y=}jZY(09`7^`&*p zLRZZSf88M^rkLMra~#Xus48VkHot8S_dz_cu4k0|Uime+G_b-y4URo63bF&Yhhcu3 z)a$8lCyHheCnN;+!~kTSr7!wIdk$xrvrx99L-M6D+)f_bQ2IBu-QSD%+EI9ak6rD% z!MpcuW8+P4t>At5Zt#{(ELO8oe5Lc8%qFvJboIUBKi6mZ!neNr=-^|{u})QIB5Rhi z@DF$o$)$@&Dg*ujqN5H}YpJp}?4QH139nBa?^3p4>mgS9Cb)iaCyzF0JoWW)@cFt5 zD5MuXZQY_fU3}G!ow}?nDyd`}RmU@i3+ZFYh|&`{bDPAG^A5$(S@oo|Znk02?Q2$m zCS?cEr(v#i(1&bmp;ejb9}@f>>4%@GjB5?S_H)OpEA8&rg7%l6s?=V&mT!w+K+xPuDEIxO2seR zsPzsw%Sfof;U|Bw;1L>LOkrd3HV4L}_L2)SCJ zE^1NkNBc8^5sUbrCE{|aMP`1ZWZ6(cK^*>7lcgqQK`*3>KROD&Mnc{D_<|Y-NEUOO zD~8TPzcP`c4J^>601azsi8*Me_j`RqKl9X9rgp+PiTq1Q+NT2p6?+$E#i2Tv7;il4j zdX^HbhD@LDL8DZhxswX%eMw>vf>*td1yb6Lgu($&JV`Fq&t!2DF!yXr+-kSiEq1G2 zw)lY-X-0;zu*kbjxZt-o4`qAozL}}$vD`O;hecVw7;)`b6=J5rK9%Pl?i3AP+{-H6 zB0AmL-R>k~`)t4aDE56;o<@7Q&S=?9*rRQ zAvF0z&tuJDft1?TW}0U=YYv-%Ibj0>+&2l>z}u<-zwsP6D63V?1`)SRGbfg4#gA_H zR!kS)$zsAdBDDQ6M98b-CJC!G)Ay5T+O4Lgq;pjgE!+QzC;=t33(5LC{I8L${ZI{X zYlWrceA?!vyIdR{l;N>QO8w~oyr`n18FAg01u{A6A=0in)D)l6hKle#)&r-)dK2Z+ z*?WfSpCPRV)pyXeL0q#($8uY@!MuKB$O$5H+Aqc6^o#yz9H;9)aD?GmA0n8*rbnJ2 z5!jJ0Nr2P8<5fRW9#ab5vUG6+u4^d04Z41r>-w@xrP~QV|IZ5DLFk#Ykd3tj?&f(X z&m(xQ<9Qs<@9~szbQjP6z5O;fRBzyDvdV=)4W^qA8h@q-)R5E!~sDS}XydiU&(q27h5 z(p9z8uA!Fc`wcT&v1B#Tp3wl{?z)?$HTqhXkOIKX24KOJA*g(}TDVd|=?R&+*n2V~ zO@3;79M2R zBi8nRQm-JbLy;ufllSF%hq-!>$AF`(3ytBz|CJJA%oI|7?C%iAv8ehemQO}mIKovL zf1vaE2sAs8MfC+ldUZ*Vtv~-B`6_cuoKr6v$;bRde1TdpR;VVOWg14jz_0+piKH$d zgYo>Y!2@h$=3XT$Tg*~9S$nQ9iMHK`D*|&2pEpb1BQ$Bs&q!=&Co3pbVY{kVNiyVD z^Q==93ZQ>3{XP08HgcZE0#=EwN<77Lb-zh%u!NXY4#U$U(T8eO@5+wf5CGZ3iA=LlL7sg;7Ql~jkcOXyIYQ3-2mN+{dbL75?}DW~6d09ywa zpnc*o;g~OqMd_ZBX<3x>Ni&S>cZ3Kj=eH@2xxTqG*68#pW&&|<+D6By4=K5ql;F) zHM*c4Y;@7?4@MUbdlFDReR}c(=A(MrP`Ycw;h*7q&1n1!wa5Sle>|#OwpF9bT+R?< zjCCs1st^Fwtx%Uj3&bT>p8C#6`&hADIM}G6P+h8Ica?ze62%Mgr3y%-1%NPo2o|WQ zB`S1@#AD&7C6%bs$Vffav@}^&+tOG;^_durp`Z*tDs7rd%iG=yt72);F^lQb*h*bR zW5y|}U8XbAt#2#%aIx{TI_`pFvAq6JI zz90OtJPz_wa_nCSC7iDkP7BdC@w9?ZC0Z)PSg18T1&T)^Gn^U!)CQdy{~D?+Sie#F zL{Gnw^jupI=wQixXJ51AdMIXS+dhe2dpRsDeTZ>BY7jog24zDx+Gr$!((tVv?UhD# z4z&81BoK{BSJkN>r}yJFS*m|e#FR;5yfM~|JQl@Fp}y;2fy)5xp#U_H9;xn=tI_^z zV+HLh19aU@kpcSRV559k`Ca%m|6#b00EJI0`Hp<2L&FCbM1a&av3&hf%}i{&aAoE) z*N>uArbCAaV65rT14PTqjbi)|6kZJHQ%261_q4+PPlu8Hx3aRv}gGw%c-iJf}ig6zzVaR$!6 z%)BQH!UIcpQ~`=52r1jw;GloP9b&GL4PcdogEJo$dK_e>R(9dE)S{B@D# z4L{K+Z4=vOWdLO^R}y!kQK;O2@{Y%xwp7k;kLV1a{(}d@#hC%VlNPlmX%pW&4FQF$ zWa5U4J3r|qw+T`ss|wc0x|(NlWIa&CL?0g?f8E+#YbpXUHs`#;cL}_siedy^swyML)a2*th)b+d8@GIoT0u3=+gGY_5{v|U zV;C1(Gk_+Gdqn_^_*wdWy#U0avDO)X5m^4h*QgDDRUg?u z=r!uOswJ#Zw^`%uViC=q9Z1h^m&>8 z8g(Q-w>(o3G4yI!Ez9)z>3A0_iP>LaTvE(R-_~q-T-o`%*QhHZv+FhL_kR?+UdS5t z*aeSXqkgdp{wbnQpPaU>;>&NPkBr*Iu*YlEW7j@-Z<09HPG+)EY?Lk+& z5)a?1UH?0udAjCpj5M!g?>d@9qAB?glTzynBrQ@>A^nD5G7H33rttLH3X^oUl7`bS z=T*OOFMMUKcZn&`s!dh-&Gy-LJoD2f>sB9G2`*IC{3!p)hpjH0em}$~mPjk%y zva03NqFmKsb0oX(af?duK{h-o`D;v8Vt>;o&6KMo-c4eDqde!+^{oM&C(ra>7Jw=h zⅅ5o5MWxE>#%Xwfn5Z^5EytTB_fgIfe*pl-sOf$C#tts9fVP=-t#sLDr7l?Y7Vs zwFNm;PgrjoXN7F<0>VDqS{GrqHYC5{7w3PHMQZJ+8NFKf;}6^3LCp zR21f#I)aut);7}|)w>KAWfOZLR+H{~AtDzLg4si)egylPEo8FW9)%epnB=?3)=6ZQ z$+jR7VJ2IbMWjFfkaaPZEmH3IAUbw@5DtzHLhkq=V2%%-=J?=gjt`#Z_~2=d51!`u z;3>EI7kHiz;>&pImmOH?p49<-EzKPK=)C+ra3uJ|pPD1~q$dbB&X@k2hYUgBczr6o zitf_q8i=D@bGuP4!E1=uPi$9~;D2PMKpD%45d2b}`YGJeY{BvMN!a7CR$w(gZ?b2j z>^4GI>|bXv#(m8m%*!uw`&THaOByO}|0-Cqe=jB-l!abI3n!b0i~BRlQi5n!0fxU0 zjRdDBvS>*I=%};3o2(rrzhAk*#;L<$@px8sEdg~Y)jM3g?Lyx~dfsV{hZw++_Ymz8 zS=EXX=(nG!m^`-g(~0GHuQ!2Ursg$xB$@=0lpnX$U(I>vEEeb^%N^8`fhawkSit&6 z?))_T2Q(ZbpBno2VCU!j4`Izj*P?|zg4^9}8)tv%?rRxsRX@>BEn10z;}65}U2aX= zbE|sysEoF%FBU2n$F}Jn*zUWpWwcfOw?1n58?pz%xqmkidv#W#ErEF5;}!WbliK7f z)AxOwZB=A!HEolWvC=KOoR0l{CUup(?AoMm6;XR^Qjc5kXp{PhHm=U5dw^ znbhOfKH8*y9kuVFNj+|i#pK&S8X)E9&N!1 zu>?%#D43TD=Eb{)*&7)2lg1TkjA+pCMnb9-4q{}I( ze0pZh?ExW2Oao66p*i^{8FnzvS~In_RT~Asj&E&=oAN+!)!j7Za{BM?nsSj~cGHv{ zz~Ga$#)-z%U>~s7sOXFw@Lb-AJC!zGEo5%3VS2gc-DqIEzT zmt@r;T^M}EPhoI#cXJj;YJ*&vO!DM;cK7|GC)eqIky+)LfF2~!Bf4$jWHjiTE@JEh zl-#rYTyXE>Y_&^20+LiPxtJPaB_mzDf`Oj&2H~TV*;9>zGcebV`!Q27UEpt@>Wp^( zg$ZQin2GS>nI0O7VswPiF5oYuAO8_-3Wjy}S19>sil88^O%5wezV+l|CVD%s`hil@ zy<$&M$9c8^_!R--AK%8M_<|^Xjz2o2yaSGR^BhsEBAzFLEn?|KAd~ zumDh0w?Ad0-M&2{3#mL~F^E5p%YQyVh4jg)Fhct_Jjo*|&hV;|@==1^VUT#W(|ac% zGyRuy(9G^NF#NX)|1BKB{*fATt7JC%m_{A#^AwR!LDi2Us^l&@?^n~*B)Pvcp*K4rHbS-2rJSVBTPfwkW!goqIV zVu$3W#^FP|+oG`D+jofW?K?C#t#ntEyFOKJureo7=2w#COqQk*WA5nKN13-xth(x= z{JyB<+39Y(oyXXc-c7Ew-vB~)wW3qAC*^E;$1>0Got>(38dcV9DDUlXYdSK#cwQ3{ zYa?#bFomI_s`weTL7fsv6_4vS6em+AO}T^dsWwY$_RQ|dTq3cfu58~uwj90NdRSxC z^$Xz=G!+w?S4GozcKB$~{Y@)TIyLLPBd?n#tcPf>kB~IMTa%V%3y{_-F-q%rMhGKP zpQgD(zTx6wc7jy~v_r&|BU`N^xT$n%fM+=Z0n>R7Vyn??D(So5c7eirz6OyhzTpFC zUUJuLMg9D>Qpl+#jckS%it+h)gST?mbWTtO?R>X7swmAwa$5Al$E`Q8%pPz^<4X-m zYiy-BY;6I(^y~@UCZ&8AnLV`Sy)2Iwlr;{vXY*%RMNs0O7;InOIYn!G&8co?q(UA1 zo3n*_m<+$DE27h6hd006n80Y(ggCLz(b0g@c4gJg4Kgx5jgetnrTP3~ zG>$jeojepufRZC*gc$pvUkX}QA4cT{SA6elccr%l4om4xk0iwWe)niMHuqsv$9_H9 zqa7|~TcuK0slwIPYh7AaNBVVQ??`jzh6%K{SG9THNWZRDp4*iBHXD+7d%pBA&8#R( zT&vL9O5)wg#0^T^P)WQwnYdYrn=6UE$;2&6WNQ_}pz18YQ}0%xE7wYj>2XVeIgI<2 zl#}B;)}1vrgwpH-8kT3fV76CM>Vh7xQ4tBQ)r?Bo@e>+ozldw9X_Dbxx;_w9i7H>N zDiiN-t9gH2&HJ31_nsMIOhhat7Lkx*B4R1Ah=i0RKRuV&Ga~kkprm}%YcoUHKDSyx-2l)ib&faF z`%YuT@`g;G?&9nnnUU#xmP9_oo#|Ih*76M(xpkb~NwzOFcbOvNIwrDdiCsw+laUT( zfJ!FIBJgxBVP}6y`RLm83EgNroo?62Vs+lW2m|?7D75BXQ&(KtktfsUs~;K1L-rrW3mJ=@ES1lvYDX`twYE0iR_A{~)zklWRXxd->Rr7wR&_{2NG80=?>-TV z<%vP%G@^1^ncGFTz?%&hS?6ve&w_&D30Jy}++->T-$k^qZrK&%SjjI{j>1A2g3@ew zIF7ViK)Asu8Tl{c7hAPPI9Dd7GWNYGrn)ul7ygWPIhto%aiGCte+q*w$%F^aG@|Z>1Q}eyv z4Sc6ilR;S1Zh5G+RmjY3SwvjdbRtXgR|$hQjEjlfw0B{6!A!~4W$$^UA-mW8Bu(Jh zVqlgZek(UY+kX<7`w+ToXW&NAD&v`%^3g&bsJ}R@7NEQ*=2H>T_*R-WL;!^m`>jUtpYn0>g24AnK4X#%QkPb zv;|6A;At%TQ!(knCp8#qi|6d{(aWU9;6xB>lVD7x1G-w`ALJbDrI9mwmS`?WsihXv zX4n!&?r`xEPO|#TfKSfRAJrG;0|Zi-$uXv&JfjYURb;!i;6Is#T3b6f98- zanik0hSN{o5jqOda-3*ZJ#w_%Su=Cf`4&a@KPdwOI$Zq219hqL>4gKnPZsW*;4d7j zn$r88>U{cN4B~SJ(LL1#^ImWbg9Y`dspJI8aBn+c>~+tl-$TGEtF)xHWE;jI%XKtm za2;cPImRsB`|h7ptSzI+Zj2ubC#u>zs%k>03g*}+U5tILw4S*~B0egj-WcuL$N1VS zS4FjZOiGsFg9h3OV{ZK}N1UZKseXGkDceJwb9s91aB=yiy(9Z|+b+EA3@bMO-l3xE zyss$Irph7mSb8XzkXP}2Ce;!) zh799}MwrNq`Sv@!(eOy@uSNP$X47exg|oy8o3`c|{8W+h;02fulfMrfB%F?Lip zg2rd(gB5D5KV{<;$GeEtF4UdOT+`K-u{k$cd0YLfzDAJw^`w|Hcbwm_TpuzCJRayY z=ckZ21>^{U%!peetRxlnC5dgyu|1d}bXqM{MOVzeETpm0-1&@$V>`sKCv&21tH*j$ zeuS}aD!sUou1<)zeYIr+Z0=b%$VRWBRs31MoIk~fL}CzGnw1GVfbek?;OWwDbjjw- z9rIftuD)ftA<-P=hWK>jw^5?VmzD(U70wSAzp+R{nSS!Npz4Ryf2jn28wGoP?XqEx zT|u1KvgKZDHZMfls;$c(WyFG>V0v{GKGfISH!@r0-;vE*A?PS z>PkDqJ}}gj+P`}$_Y44#Pan!(Rho)!!Mmg52nJr8d}u{u9vfuL(ALYjEG?WqG@J7M z6AB;vXCw!a>yVb~h_&1gO`yhD(lB`1Ibh*mLeq;|Ahe;(t3vw2-_%ggXq#Wz(nD=b zd+A5cQ^^Slet%P6W|oG3_Rp$%FTtf81L@)|qN zY*qQ-JTr5{easnr=C|zt&HM`KKmKblRURXtndU+(HHdLQIDr$!#g~P=h^J{g#Yi2j*@TDrSZ|+bJOv&x%frE2h zB}G4U8L6(Yz8&I>VDHlEi5-RXm894d;9Ud?>E--|cy^$BhnziyFL*}bgEePZ9A$Vb z0qD6lGH8E{?D~7(0YNAjN;SJDe;ZcK(1~DW5`YEO`$%23{|C9fmQUcjH+8*FaAKRd z35sLSgd!*OK7o=VvfcnKuD5au?~@TxYp$RUn6#mSE>Nw(17=$@f(L8| z9NxiTHSkrG{V5x-+^c+;2@c-~@r0ZwFc-6OtP3iyyjUvHpR(1?GuqydNX5N6|pe$ZI?HKPGeWslgH?SC-Se}UjkWozSV6gv>dHX7^}BskOe0b+&TLfl{7f>518!*n*T z9X^(c<7{Cll~gu*@L^1FY=AQCq>ZjuQ1j@V%BARxV*ple;6G0CPq~p%Rbj@tq1rtx zc%ai%0|$(XCpVzl@ zI>Eq%&OV#Q7<#GFt)RsVygPOPkt)B@*<)W7rIDO*{$2PsxiP2`W@UW`lVVJ+u$R&w zxh1r2)a>PbOw1}*q*7y$tjKHe_lVniws=rdCsUO!`!-Nh{29gNw2CZ&KA2Z;B0cZJI5cDnPB`EJ+ z>8N~qzGAo^O^?co$A{EPW9qfw&G zoDUc$Vv?ZcOZ(fGM8q@vO%QRrYRsp9Ost6b1y2LsV!-zsa3JDqyaXbKob($NQ%Dc$ zQ6b_U6N)ir0?SMW({BU3aKL5!9h->yn27U$aU#wVw1}9k%;}f&H$lW7RbxKgNUVrx zihwf)yq5t7A|C%@OvJNJ`ooH0->e=LB6eIbPD}io>MEpf0laX)H~BjT5r|jQz4;N% zPPb`xx>ZKx_u+!K?$(z$0~q^!@Tr7}cy1S$W z0@H{Ltk|aJv;c#RYgbX%olF@*ulVy=?&`~L(|=ZLK3_z&!5lt7j5Wht#;AUATz)w>_0TN{l^=s=?f=V z4^#ATYBaM9eiWB}E#4aQol9ZmM4BeX>;0W}8|Mu0oS|8oF6*42RjEd|Dm{L}sQ9>m zS5kmFAa`B_QX51nL}^4$Iq%Mi6ZLsT@$OUBlFC8%FzG;a%N$_HeduNcfZQfn#U(029>Af^9$nn@TA@q@y&L9<;aNkW^hrwBOfhTF>wEw*(fFM* z;B=Vp<@|fH_`N6|Lg$~R+4Os-L}->T)CBS(8{QvqJ zPYe_DQxTvFCJjMP$5PblQUnAav)nBv0h#j2i4tSlK8Dy!b%ZpAJ<+Zj%ll##&CrMV zW~9Pb4nCmQBZcYFd*KIRFqn)WeNPXI*povK) z^3hbUzm3Q=f8%!V{&94B_a^n>vGmHds*p@nSf#ZLdoVmL!cexRgl$GOhLu~&kd5Ku zG=U2zIdrqW5?50&hn>PhcSnoQ>x?>m+u0GdEaBlk*`9D_= z9*f=qF~T<6X()@Ryx^Y{oA|=s%LP_xhZ-td1wICqJz)qiDtrFNRGttBv*K2Yvxcu4 z%BkEgHjG8(S4{^#9%SD-b+@g?H25HA{kX~3@NqqbzI!=Mi+p>-ZAvwpV3{fr46{Nl z-FE-5f<=XqRaMLle5HL{Xq!xEe*;e`es85V4X2tVP%gTPNC<7Ef;sc~)L58(XWi(~ z^@hb8O$}E36sFm(Vd9D3?HQPMFW>Q59`$n10{KA&@x%_FHi?P`{m!**AxsodED19Qd zA+N9VJTfO=@Fi|%{ zz%`7f+z1^Ql}#{8;h0f+i5aDrm{EF(8KswqQ3^+lQn&$b8gsImRA$x~a};LEX&eko zc?+CJ3&kUrE5)cLF{)7pC-$Z@Y3R15#323Wvz3b7{l5V-a6X2ff}@-ks4@NT13C%FQ0iHg-T-w z>y#Q~o$h=xFOw7Hx3?NhNk2U_01B@u>^2mvKANZu39Eeaka>x zs-bw%>_h3Q8|)Yk3Gorv>>}hVtf}JZI$?uY>Yr$t+tQ-%v#@WRkFy}bxAJG^KKyx! ztmtF6@n_a5{v0=vKgS=-pO>zXog@~K%dJ8JW+tksZ-hCG5$8T~ZOCQ&1;Y|Mkui088M}%a1HIli-j^HFAc*58SUTs1< z#vIMyD+s2oQbX_^;1nZx|6G4D(Q8jSz_*Kz-o)`LmwH6l)&ZJ^W*zJn|C%!agmv^0 zI}c`_aDX?he<=_?i8=BN=C%JHb6*1{=XCZzo9rYbHkn1jCRQ>@Rt#1$Bp8v%Bo-4E zi(pI2l89ANTV@GTHg=bcu`E(jlu)gdBCnD}s=J#HJMmFM(J0zbbheY~`l>}L|KIOE z=XuVVXJ;dQd;PEL&Bf01oZmV3xzBy>`#zt~IqbD%=fQu003564;Z;2uo6ekrB0Bo+ ztC!7(LZ-?k^Uid|t=Q|iD7vC4OR^Gn0>h9Et*@6)gu;XshK(g?bj|=njyfFAXVGt} z)edK6Tk5p!%x7NOH$kjkwB2F&3Di3`c59dA1TUpJNV)P<0UaRP(?a8Cp);(D zm8>(7KiY)TV<2JofG1I9EfpKyUgzpW3FIbK-X(_R(AbSM=o-;_lQ7gnwErR+jKebm zWfI^Ix_hiuIB_5%VECfP4NlU}V4kjiI%_wwz9_nP9hDO@4N=ELF&!nWwweGZ0%Iy| z#6yHh@GC1fR7r{?u=6TOg|OvSNL{kzrCak8SvC2*nZy^#fr;YDIu>&fE7FfhtLbm88NVDMoOHK_aP`DjkT!xro9`HT1A_pc`Sial|eb$K|X< ziJ{L123(0Gm1+V7PM6UYjdbQ=R<0u+hJwv><~ALwbQqza&wFU}_tv1nE)tUUQt~NO zc1Ovb$sGB{?7KCO70ULS9E_sWz^PNATFGl^`1zDv;)Bth$jTn(qqO2UA}laONHy#r z3m~QM1n2%I9F1dfcW#LXqUu|S4{Df_B<05OQq)qq;`ozT-e zd1sqnudgf7`t4DJ^F%-Mh)&|e1acbRIgE|M?1XN3^IyuOj=}6ideld-tr8NVK$U6@ zJ3{5Ya}7E2s(=vVaD^hXol6C_kucU(jbz9HT|}AUOB}|m z<02x(!7KZxu@cye190cKpI0YSN3`dLcNLTUHMpW4iT~Ih#fxip2o-bf(xGCmO2r#D zRGq!P6$Tr~Tz5DPQSaZ)%)kXVumrw2Tw>? z!A@m}VL+u>`Q5I_9!NMj13gZ}O~p!*>l$BBZM^=nA(D;_m3=787CpTBR}fIk0Q}B(fGX#q zS{_iwun$L%;WwmL<@?aCxuRWXqTWfCWJF|aLhC2ugszSP6dM^a6k_M3joS6h7w&vT zN^AzJ1w5a>)KNJRxCSA$kPryHi_5_9R-<)vuIT6oN=Iu+IO=vh|K|{;qmV6qEiovP z=xCg8G3cmDSfi={VNf&C(c$=Zh4m2AIvTTeG^TYFRAf-k&l=*XQv*2v1-~TH*dc~d z#Wz$D$`4*tozuS|v`S|*w^-E8aNq!Up=6|wb7=Sx>3j}$SZ6 z^3^2y6>1Ik-;6XW{;?DpV#!hQxv2KJzQjnV_*_x(tEGe@4n7rQ5-vMWJ*ioDY+@|I zYBn|jmO>3AQJy4|a>F1ul(rJn<4XQ-Oj31+jqlQJpe>2FoD20|K##e=s6Vvdnnz}) zjt0k^hd3XA)HnhEnfA+VKG6Okq*0pdQkBx<{4wyaD|>MS%r|y~McZrL;2$B_*Z?TO zIS(XSypy{B-d%Zge|}!we|o}q>pps+IjZF7{yqc#8{G%V(xj@iJa%vi_`?2&q|8#} z7{b}Oz9@$s#}IDu8$%FjF)@q`Mu?y9vWqH{TG@q4T}@?!!HTih!Z?*ZoPk>~9hd)S z5koI~K%TA+!n1H06DuT8t+1n7uxN0MkP>;oq^xX=xB+i4UzyvMec`#MEPV;*mxWyy zqHjrqFH<(OHz~6-AweiP@FekYcA}1z^zXG$HZ7GQ0H<}YrFg`kRPp|xG7d8ltjA0e z$^igaIS>ZXM_t#}diQ)^`#YFu%G{4zOzCZ~FwNeC^HK2ipe2=nEgl1})SG$h7*e9F zKcIG9BUwiwC+^7(r={1ZF|5dYhGqzq(XwbFYVtFeNGeuHi3xdn(IB)(%BV{LZvp0H z+zlU41W~zNqX_aaT_PYcCqUH`nwBsbi*eT0hbqf7F6qbFg(X;I#RuYWr@pRpU|UEU z-@wHUXb43Zm+rmO%|Rfvd|gBbM#*Xf?FzIGP>fn8S`JN-qOV0QlM?zWg*g$>N=Srd zIzm)8JjF_1qsii~XTTE37jduX6$8jhwvg`-k@U{kJE}wz#2@lureGdEPI?ysoB%N`1WaLEWi-;AkWc+`dK0)B zfSn`sbSHuFDc}u?bl2_TNhj%EL{w_KRC!XF4JdJY5f>kzWQS6*Ckh(W?FiqbW<#iL z=r$yPCQZ-0I+aPwV{M02ZA+VnK{(~qxR#n1Prj0QTt`yf;X+hOzLJRgCHpa(l>do6 zO{EcM!DgTTG++>{CH|3Awsf`u~8ZA#M zS(l`SO+_&CDnWA}#9r$Fwq@Y82;14A5`|)D--qzIe_p(*_VnrqO=v|pKM(k}?Y?o$ zdK^kBh7PK12ucs`poL*MtyJ@Y#6sE2jo4<@4!)me>O(MiK?8}&Ikr8Pz0{Ab! z=vjH*4n4jSyHEA^sB1F=u%Y}piGc;*f*0Z~Mfz=vT(t|0Q5WwuzBf%T5q>6Lq`Vd1 zWn&x;PVo^>zAp_k2xVrLW8MCBlo%hqE=2&2(&i7oS#0ld*Tf2;+p8Z(X!d}1npWmF z2tWd^L?Z!zds!SY^T4N7=ghBDxgvVfa+VIeuL}&zo zGQo%6I)eC3@E2bw%N-T3c+)z9rZqyQlzI`y42A~Iy|R*Iw{nrmqB4GFsHTyr1mYp3iji-WRSlDzMrDuE zy@9o;>(yYyPzUAJczUiFAUztMuzXfEo)73FN<-ZN1>uMZ+cUp_bl}pbsd(bfI@>qH z^b<0( z9;em#hf&MmHK&Rxx9^5{nc=iUu%}vwv~R&d(@#vt3TKutI4B(poPNx)Gt;pmgw5>4 z-IiUyfT4r*Tp=B7{vlq4e6V>AT|mnJBvpsw`_t6>gM5d%uPZ?|jUBtYPUL}o+KvMo$I%0wm;nw1v%#_h~qDRd5*ojz9jxl@Iycxxp z#BFawmB{4ay+M}p`HyHSnavZSb;bs0n(t|v&x}wsFZqvYo_-8S9y{}(=^!1T{0I56 z`>C26z?wU^6qK!+yWocholY)Jb51)9u}qgf!rq6{7fa!~el2|peJ)J39-4}*zl0P} zgUy%gUdK)e7hcS*+D?iQjMY&)RR?8f>PYX4t)m}8y<1JtFv<`l>e{wysrJ`dRCP5| zBUfP(gRKA@%q*XYRbe3L; z8oU?YXlaWfY-6<2dM}jKbsn99>+WB}s2ubDDxz+~)m$XlcAB9V;Eflu&0pv?Irp2 z-t&l>PnYxNJozVe4w8S$KVpt<5qHA_YKG3NpniDD@5ejmB5^0_`8vv{cyKDO{(Iz( z`6f>OuPW^;xR%^XL%A0E5?AKb-CxC1K^(dQ_Up3_M}N9~yY|}!*+W!E$IsOHIy%o1 z0I8^ZmP@ozH49%k1hP^gWpm&UkWihr2C zVbkXBzzih2+0sit8GQpdNVILxENSaGzL>0=dOjbfh8$CrN5vg50mNqaG(tDcFYeGX zPLp=Dv1d&1#zrU+x+}OaYH2A?ID>UWXdNm#HE$^7#{8%7H0Z;mA9EN_BPgsN;>PQG z1!OoQHwEq|zONnK?yz4IzrkexK$z}h5jPwH|W5_f<8>=ikjFYOPgR5REc;Sdm*XfC# z9wZf38Ey1DlV;`NauL+q>8_VF!J^g;L z=Y6#2U5>1?;@iiIXC&^9dAV5evV5fB1q#UuK@q-H+nO@eQ8&oBP0I?Bm8INR(hJWG za#_;{pa!^}P8RV1LxjcQO>8-YKJx_WtjI^R&YecV8=r>SD2A7fQVb7uC`bb|AH!*V z1qsN4?OmYJ6R2Yo8n+b4+!D-0wjkk$?H4*CGtldn2>sxpb86p-P@+y9#teIGcRkI8 zbn1|@P(0;4V536sOO@V2hFDXBf?z!!ee$wu=`0O7 z6|;W;ggVhG8+88!4O*_|7Vprh4fZ?>v{pM~21D+1+71cZmRg5iE5Uh62mf zB(%S301Fz{_nu)Bi0q(249hHGD&RHa$iMK-Ft>Nb)Fp_n5`}g8i!&X;G0sc z_XO~aik-KIp3(N*QogbIjX{<)zwN^q{5vuR4dyon4KCAlBzou?g9h^(gJLM3F{otu zj6tW#V+Y*)Hy_{l2lX)2bB8LlEDPhzTV2Tfk4i!B0Lrm zlku3!%MBmzgdZ*YjU)@Wc5%!BOgvF#5C|{NC4xK`j#&P%Tl>SFfxIK3G_kun;D8O? z5Y;ld4GeG2QbDd&ey2~!Lly^!vB7i6;*?P@S@$>#X}8?gO3M73Id^$m&E-mFKW@DGQyG2U-R5{9qKf5>C70M5$}YKqj_P^OYV8^UoekG zE?hzoJ&eNT2k(jq+gdbuV~E4M3gh_2jU%|$%f4|$x)?pkM7~AEWSbk+?U0A_ZT3*N zj-X2gy^zKnvCs)+erPmhwns{Z5yhThM8wEvj zFo~;33e$q=%!RnLOTF}cF$I$4UQEFNRR!8TG5}xr;tmN_M81PlOcdwN z`>|M3E-6i8ug{6ySxJs@!z%KBaX&@aF^R#6{dw#X>|)o%Zu-nh3gKJa^`Ms2@a>i` zmkpA8_wAHczJiWwYT%y3I)IZ8a_GpNDgla#%945xLkQANe8&Y4s(0gQinqx)Y`aJa zChg`6J!5OG&*|KqWf_{-i|4$lMqa$6zS}|Up&NBBy#*auzza)otgf8YNJ3L~&F#8j zPWC1aLAI@z3z%Xw1+-u8dKxB+SuG){7N>rk>0!}W1WqDKuY~a=e`E})>>lc8wxE%1 z5I6F43+f7(ox7fK!5eQwcTjajip$uTb^6~tbw8iX*+Amy%qmPo&=XC;tWfu+}%@AwkH${KLH4os}a(TW;j-C=$biEPfH8P3kqL?LXxpP85tkd z;P7xxdkmFnkD;9Q*b_r~Qp;Y<(ge`H!FY!_&+Mei#A)$(r6K+&Pr?L0Zr|90rBoE0 zJqdD}F)6TxBrVY?e}hV)mUb68-^Z6oX*0|yLzZ<*ywZEY^Df@iSCBL`jMW>KV}m#P00C*DnMQ;f-xsS16x3qq}>@?f><5 z#d9H^+TH?p?QfIC=f3?)SS*$rfU8JkC#fa&F2GFM$U?w^_R-th(wX-V0u3l_?;(ZX zfI=3ALer47`34FC3I8Od^{zPC%7aGw=QNLE!WZ|G4Hlvma>TIkCzhMp4knZSwI^VQ zr2n`0yEZe54P!Z`do12}@$epO+K8;ts}MFE{?~6u3Bms!F8`x7|9QDC%g6O&F4s>N z$XsJ72%cjr$G;Jts~ksTD>{@zw0EMnfFq@VTaIS||AfC^ZjvH8hQJS^+e^Zb?&<#q z_b89jLdvb|d!qJ2_o((bBSqXuG$TgZUTq=`Z(o2&O0X*-40-DM5HalnOzBmC>u+>OfQ#=WpOe<#v#p+gLX@y&pNXM0}8aAkbe} zhD96bt7KyVx-GMiJ1X_Sl>c}*FL5IGEi!wrZa83vn@IdStA zt8bPT_LbuvxjEJkZ;yggt^d?QDpc2RXMj)0H$?fiia#(+e{~vo?B;xU!b<#zoA_Eg z@o7k$mG6H7JF}GmLg&yu(8>HcCE^N8`lN3lllGUua3dD2v5>0p>W$W2x`wV z{0N3awwNtaOX3g1-?tx+NSPmgsUS7xS@R8|w*?NgYIN#Xh=B5=X<55wF6mM^+vA9n zc@-W(wNHrPbe7-I3Bqe0L!7qNHnDCpqWXF!!J|9K;Zo)Rrt#I=U~+*>(wPHLbeE;Q zU6#HkOGgPyn%#*mR#FaZjE!M6Qx~O**Z>>ja8(s^F|ohf`I&Sb#9p>Bldgx@lQwpQ zOEYp1usdz+AQ!76cD0Qi;9|>&onvDdMr%Gd5u0IS7-?&)cs#IiHa5z|s)!BBkJS+q zdv&Vcq-!Pi8V#s7wu0D78wvKqmc@n(6gBiJ;FB ztxs4gQEG2fPjd91d(%lYXN7~o`7dvPouu(R4rHe(0^|vuk z{r!y|$8mKSC+PfEFx`tbhS8zMiYEbk!p6|(YAj0Z4jVJFK9bm#HfHo?7O}H!%+$lh z#HQJpM`mMfY=4)R#Y{KQ#ym31(xp0O-^)$+B-6cOV;-6P#>Pw;USPVrY^>0w`5v)r zY%Jnp8Di(!*fbXl9SZDd8#~&?YKZM;V+Xp}a$>vM*x@d=nb_8jy=wQ&sJihL; zPpz_>dVhj6|7c?#efh1886TNuy8CU+(EKa0MjJDF{SC1TZOrI($>G3GurZGgPO!0{ zE0@Vkw}*{kIH~1%Jh3l7vC8g|_1iXfgqyC4>Dq0~BkP~rm`Bz(+L)2cO{96Tjd^5! zvW*#;J;-zuZEPQx&u5A4Wn&(heba4~-6ONV*qBFV>ut;R0v-B zy=Y?|op{2=OxeX}-C<)>T|TRr-<3AzsiU)P%+S1r>89D3k>`WN#@d*v+oy>Qv@uT^ zvj4EkZt{~dykcX<*S$uXzp*h-8Sb*N@4IF1X1Z%^%)`sMHs;~wXd4^p(yW>cn)}(9 zhnHP#%(NYKO!v>NR@ptg{K3XNysWY@BkPAr^Bx=X@N%7vh21i2WV$&v=HcZy8}smT zpp6;1^pIxI#yq@ymbJ=mhT$bgBHbTt%)`rXZOp^V{WfOoHcpz2Hs;~wLK`z>sAIYl zY|O*U1RL}4vWJbCI=YoKzx=yZb`LLa+ZfktmCstibnV1iFhN$(=L96sI#A3%J?YNh zVmyqs8QfOCL``ODnr#{6;?6cc@DXOz#z}r)0~>1wI(g^Dy9)7KgiACWb#EZ6m_&$X z&*dCL3>0KSlFYRYpQ0lDg((p!#z8xF(@%<{BOF^p_!%~hYK|b^eQlh_oee4YvY1+v zQ~6Z6+ZrSpHot!e(#|4R^HrE@B<(0!`&C9J1ZEf1%WAv~M2$nw4}I3EyDtA9CP!gu+`RV3PHO;TXJ zYLKG!Pqk|BFCXNs!CvuJA)b?8+un*o=6vk-V&zmZuPUE&5S2{Z7Gh3~@~NUcyWabX z>uU2QK)&9QH2^}_zOUpc@z$z%wbE5`koVJbBMLZcG7Ek!?^IU#A zF&7KQwQ70%_t}G5vj@28xMSl;tg<+C_+DPm4{2)(@}y47)=~KqXqYO5nqZBSzvsap z3RcsU zV^AK=sSLBrZH!whRVfxTU9pXMc==pcl9a*2%Vrxh-HcVF`K*n3cv)s+oYhpkyufr# zHs;}_*2X-%RN7dXOLGfpMr_Q(i})X>j?54>a1_$@(A*r%!^=B1=HaEo#>Tk3#7OfY z8}sn8*v3p9)iT|D8}sl|Ww3PSa=HUJC(2c?e%wU@NB#xjFjjZDY?!ls*8r;VA8;4agEJz`_VkMB$D78?t>5{nbN%*OV0u{vUB*qG^@ zEG0JC#*8#K5*uk_Mq7G_^~;ZiV!%Gqep0N#Xznq@Ua&DUu~bd$aT|NyEyH4Bx7(N* zXr4M9*cCQrI!d*~&a$zKT$-)Kjxty}a~}M;M-n=)cEe{k zv3G3Dq#JQ8unrqD!;~nohiok5@={G~v5lFb$W_GV=g00OR+S(74Y5i2u}#EEY-|^o zmwyo3M(5zvyRpqLiEXj5A~)TT{4PMykp75l<#U{8*R+cyn)!SZOq8}He#(dX4>|9 zh$U>y=*0cRs`F#d5}T4Ady7~oKlU$Th54~P;=nR*TV*%AM2Nj)W5ym%B(}oFjQ!OT zTVi7#8(UywrVY56>1NxQsfP!N#ca&@p2vxm+1NN&Csq>+*qBKt{pYQJvdV6B{x3|o z$;M2Zvz6FWHfBZ-ftkRT+L)PgiW6ICW1jNW*qGr{%2#1yrbpC3nqeC=>7;x`HfGB3 zDARSnWtH9ZP@W_9x{aCk?+s$BZOruCGQ{q+G1L1jJ|0+ujbZ$#eMpShTpKg#>WIZ{ z%jtpV4rWc%5HploY-a?Gxl&Hv1e`Ua5ulj#Fp8Z=|y%B zYs!zkO03q#Ouy%SVwE-)aP#{&v51YCdKY~eYGcMW1C>bE^GB=f##SQ4-m$SMZhqCo zI&943Cwlgf!8+UNBQxj!!OF$d_EJ*1qF3xmCbmvL#)Pbu<1bYYMOv}LO!~EJOpoC? z(jH-B9g3T1a_H?8P7AA z*cmov(v2WC*~UEO8);*PPtk~eHa5?#*)VB-^oAuDlTK>(1sgLxhFh8Laf9hvoBygs zDdgs|oUt2BY`aFECpOo{{BF8G5R2Q`Q7*QHShmeIE!>ywlrdw=dCY@;4e1mBXI^Y$nW<2_KRIk|EUUp;a^nW)YYuAKa zPDBI0ea(&CO9S7xF^>jz+L%WJAF(ly2Hs+09&NeI#ylE$hK+e@XtIrYXpXco(^9Tt zE%eKey+G_E+iE?U`+|*`+7r!v+{Qebd%KMpO%mUCg^hVM_beMT=|ppnvN4Zb#@LwQ zQ?zq{jhSB1yDaFp9I2$uEOAs4mV}{S`h<$9^n(49JOYAipo9vc-1+kSj=E?7F8#A*p z-As3_jhTAby$aa*Ha5%6FGB2C8}sCs<1b8abTQKnvD10-`_%RmXSw;UV7fPL%#+_5 z8#8vh>nTWgpN)Cy_IevLHde-T^K8tM-|;qPXo_Bsw=vUmJc2ZLw=t7W^!i`Fw{+gf zteWZmWMdv)+HB0w6kZ;*F{4Y@lI9IIX3_~SKd>>gnsO`Con&LC{$%uWh>aONTgr5M z+SpjPZaav5{gPF7Qx6{y`?HOidG4=>t+O#6JgNGl!%hYEOB*x!g^Ar{V`j8lN$iI< zX39`Y>{J^wzCdQ84zn>c!fa)_5jIxg^0|@Nw=Y^{ALC-hrvZE4#>{N*L}HybW=2cZ z#2&G+lU0+^2z|OF-lU%Ho*kl_!#KpD{8);)^=Cb5;VEt^Y z+)WoJ_R$NLT+HZm0kIcs%=o3{#2&XXV=MnAcDs!o;N}-N1K1TdW;TUIiJfI*W@e$4 z*iklSbm=8xV{FXmV20QL8}sPd-=DY2ZfMGE%*!@r$|vp0lQw2-T71EsHfGwYqBFtE z)i!3*i7z|&d**_g>sY;&cJd2I7; z8#8?{nK`-E#tw9KB0@gTx3QTnRzvJq8#BDDAa;O_Mcj0oi4CzaV-LmEz&=e|Wj9!i z*qb(HeDbBl*4UUwC+@Q`Q+AoDx!%SucllgEn)7VT_=0X?$J?0kb+PXO8*gJr7@EX( zw=u)#lf?ejX_ejR+3$$`$;M26n~AmA*bFzn;5 zoD=vyuorC1_|GV@$8F5$U=6X`ZES+8*Ncf=VPmJd*lJ>D*_aux?0OEcqik%5n=VXj zjExz29!_k4jhR)_Dq??MXO-RP#4W^LwlOmoaUZcKZOrr;Ruj9^#>}`_Rxz%&F;ll< zN9Py}*DtRHW4Sv%J|gj%zeBjaUL?#g-Gh&Bjb8XA7}<8#6|FNDZ*>*_avB97k-b zjaf_R#75hg=>*(H%x`06ThGslb#?Sz_TK|*L$Q4As~GhbygFaho9$ty)AS-E{nVys z9BhWzk8R8}y2a-KJI}_9p~Z+DV`C=2xy1IjF=H@S6B}$}M!D}I_DQ={Zqvv=OzaIC zGYb3!v1e>-j9cd&#C~S5bf%*X89*_yQS$V73pR)raJymt58Q9o8)5ag_l(+>0Yz-s zTTS_A?)WW;xkRuZY7M>%-{pMd`P0=llApZUXDgJ0Nas>M!b5pDC~LNh+QZCYAVRWL zCik7n;|M#CH%Qas{^@7H{fVUg_9`H-ya2Z*PDZ<UL~`p*S6%EmnM>~CXc$WqL7f1?E`ok(W};YAr% z>}foO8DRjGR9Uh%iO*O5w|)Cp;t%B8$e3 zfE+ZvZuKy?zYCQN#@F*Z6Ti2`rR|5?0vwabfb4wO##_&&QL0 z{4D-xJo$Ch1~SeB*sQoUOE9@P>~IWn(-K zQj$a6O0iM9Ja|7Ya0oVaA&~XB0$6_U4r!L-Hr2IT`g0FBPS-=cb*oRNfM{ra3-ze{ zDbM`Ql)>iTL8AY61nMYU{h|L^!cIx&lSJ4)kE&}v=>L?Epmk*jQR}*Xg7W|0sXXv? zb2<6KM+K;*yhiW|B>BHFf^&C5m5ZnRJ8AfTw|X4ho|KrBS`duS%?*z4Tb`p~HgDS(_glCS5~ zizzt}F4A@(WaDgr{}~62^ELJq)K6671UY$Y9%Su| z69%;`yw*`$r)hT@m7+FR+8P?moiB!lBkIKeiO8Ie79S>N|Yb19a}l4 zwd;MHm}%z3!#HC~`kWGS!-tSO;LNN@ejPJ%&sT@0{_~+J|H1q7ie%>+*aq|w+keX< zKK3}qS8}YN96C0HEkCr-96A<}29avE4pE&i$`Um^Jq(=g^r2(r5Rg7}Op@*Np<~~O z;_aw;QyrsVv)mUZZ0+=+V-b$q%k`mSu4?BVI(9e8tqvVC5poV4yNZG_HR!OK&J+_c zHXUq!5HgSq6IXv%by}8|%g(NS<@VrXIk};(De|r*XyW6Js~Ddn%yi~1fXcC4pkmLn zWBU;MzdTY*IRoYYU`^7ftnPs3J%jEcybF;$-!~>s+_6GCsA{CvgP!ZCvcHBHEZ_O! zqxO3~>u_Q#Vw-GY_j!n2`yUePv5B4HA$Bl{xxT<<`MX)%`vR-H-&ickAy%~2Up}IA z!Tl&H>DQWvE6N~wr^tP~8a6#jAYnVV7ArSqbO|$pcF8E%GvBovD%{09^Icz1i=A|y z5%OC$b{^D3E%eHK*Y9l1GvD=qjd|v~nr+N8-*u6VnNgd}cb#Zsp82kWZOk*@HO$65 z^Ic!jQ2QwRyTGjZuKV!nv}1kFcm2wy=b7(nu`x4CA@f~7vN6w`*6B9pnbSJL#yq3= zeQb<_3srYAr&VBMo)Pzlv<*ilX0}1*w4OIuIvhOe1Y#Sslz{ zBv0Ac(XOCn8fmGGv4f#1;YRS7S!iQsI!LCGYHZ9ijZ|S{CY?+pg>B3;9aLmvV_jaB zk(X}Ud3Y4*bsO_2(rOzsQ!p|ebgzw>sT-N{X|OSm0?xHDlTN05;x=aTlPRBa8}m%- z6dNp^nfR;k?o4i{qL|JkyScqPlgkmR&Zbp;NA!3?efV*FAdZ7Qfwyh2^>gDdkd52- zROxXM3PYvu2lK+^LVLDvMk4Zn^*$N~pVSRoavJRW&~oLfTIZoMKf|j&Zy>Q}`!WQn zq~H9~N!s_hz5`XcnZP}aTndhhAPRFPj8x&R!=#`6x#n7O<58*LzR;H_&pe2X<>cdw zq+shaw@H9H`8ax^!{6BmRc8Y~08&Dw>mD$ok#j>Dq#M>!mN{9xa}wVX z5vB$z(bUNIFP&QLO+)q+T@%i7`OBXVBu~i}WLD#dx zTX7;rInUE5I|2`Ko<^{FcMSa*lw3#ZP*oWev6aOuu8iZogO1M2jf;?zqwmT9AmM;7 z@x$y%NKk6#bHOb%Lgsblk5lG^T$%(WRsoPx&HYMok$F0E8eYI>DfuL|BMZya$sZ3W zF(68W@kKipZLI|_w8xShcU+B7%-=VaO%YZR1<$zUTmJDmZas(aJP1g@t99oNMR3Ztp>+ zYFQ%eQHw+I7DZPp@&jkUYp9ZdrW7dHd?5U->+)mwQXbYd)uZwPAK5Bl#VoqdC>K zND1y1lsvHu$We-L?c?z76)i792sU5L3!TaM8bnc-h>-5FD6&%tiRt=jT;g#36i6JT zb82Qzkcz)@DC}{GWZ2ef7jjp~UUNd>P-E?O^XB_d&_x?+5ls856&*JhP{9bR=OPbw zmty#phd3V)Fxv?bkI5(zhN#}Q4@)+gZ%G}tsSkLnFL%fLN->Tio=;i7006O6yN%9M znv!$5myj1nq7ajymZWk)~Z~DtoRe8%PE5hvsW3O zzS}9o-hGwfH2`p6)pL=r6O%rF)KzTOSdmtVBU04?N>3cDUaEZt(uYVpxv&HdBjEdXOhco{;>tZl-MW-U? zzFI2&FC4`uF>nq)4eyQT*?9EU=)*r%yo3IRT23>EG2P(N)OfN8XFORK_>>?H#|cek z9Z+um};cr%{4Uk$$I`$-7nLgDb4!0}G(7z74c}!o;cx?-8 zDoN(_J?7-$d-c(M^S#i}%;oz?Qri{O+Swn>{Q4)556q0>Xk!RPf972rizSYV8 z2T5r};07rV)iZ7DzSJu5yRf^i$1qvw<+W%BylxuemOq!*TS@I)q2>;cy6dd$hLC%3 z>ErYnD-6#8{fx(MaLIpo{9HfATb`26fa*VRCNHP|u+fbs>Y?XS8|-LZFQL=Xz71?- zE?r^?k0BJ^2vjRX88q~!GAcb=PEme!GMq>6o*mqWOs;_~cb$O7fz7SZ zL7pGo0Yx=WX@MT@MarW5ayxhY%HhNJuqK-MXG!_xNPC<97J;nlje!EowhOhwlqdxi)eJZxI z1(;schv@LW(eE~V2Y;(>Ka{eJo2gio{wCI{{ z7IkF}QXh5y@;+V@t92)Pjm<&^8L*K!6naj>JX7k=f7PzJ_S&{WWv1G*iLmjm{wPeV zS4q#CW->BL%G=a}&4svgRy=h3Mr4vX2f9w4I>;u3BENYZ^b)buJY9(sNCG8Q0!wH1 zW?@=}vSVgQLLv&6A>-y&L~(L!X_c{@qwOiQ6@xI`#?K7+e229qT9SHjr-I?f=oXT% z#gnZRiW42-RKlc;7(s$9TKq`WJO!I?&@neNw6Wt5F#DWh)@fy=QE6nk&>n-4er^K< z(ddhqo9H_7HCRVdP>m|HL!5-*NSM%rTu7YlF!_~Vv_Pr`aAzV~e-#?QFB75v;W!#q zhcC({&Fn2Gs>x!|q2926%U0j+-~O8Rxo87B4D2|tpX=>7K|zm>!k&@{>xYt|duToyrlv(=_`8}`bBkrTAtcnOSprGhM{@Q{R$f)Tp4mnZfjNl74ealzG<7?Y;U9Mk( zJehh%YC#RtayznN9^vMIQ;_L5u~zT*Fm+-_iQ zDdYxc?aayR*5x<24w@P)dVp#d!_k9{HSpHlx+DH#{WH?IrBKmx)P7uG>( zAwSrexG;f?3tM|D;C#xvfQ5(m5j%IR48BE}FfNRaf^{gr&~-7Dl;gq}N*BgN1zF5Q z>!KxwF^!}3|F{WRq3Js$SD@Dxnx>B)p{+O}Dxx$p3jVUO-lD9H_ASZ}#ns&gJ> z>0lcz@O5tId`(Ka3S(VOC~m7(G*s!nPC5%F`-wv*QzW1(wefJ|11phxz?ZI;VGjJe z6hY5l-~u?r2ZJ(OQNjlV$RHiR)%rcAe=GE_%w_-S3jl2S+>;B3(z%lxlQwpTdw zzqr^JL*H2#v(D1skxpUtU z$~;P$@wM+^ zo_(Wn5@&-qI^CBfD(R0y(6wG#)V+zI?h z%ALQ@DZxzc4ae6c=(C#InvB`{DR0VbJ&uSL_Wc+8Ao2xQS|UFfS$F!&5U&6Q7WK}K z?eq_2Kz4*o;DG50%)!srbMT+=zVQOAEpb98Ave~e9O=w)i&1%?AyP-eYEFvBkg!@O zJOv3Elyv$n;$JH>5?Y}`odtu#ROl=XZD&(--Adh93}cmGfHGnRVTz1L8H|aRsDhF#dKtz zhSSO07R+Zl;Sf}(kt$28uV;^ICAf>NJtL)7EF+t!GGQe|&Wn#&fJ&qB#FN}ooh~dp z4k6Q%pG;pJAcU2wJ@DIBA}@MrYZAO9602Ihh-;4LHf{-`r8o%r%;I!k1e>UXD>pIU zP}}Kt+8*%SFu&~Fg6x4J;k+r%wo`N>1?qhk>wQ)nQ3lb+K+FJ&ZlS>GOqMc3Nu=IDzS_|Xs05lCAf+IUlK4;f1D5eZ^`Z~~CVd@7 zmEDaj$ZO}*vJzE_ceQATG{cZamdraaBa}1!w;BNlcg#b(I)c1IcbdwI<;mykY$_YY z$9PLqnYcb=_VdvaK9b?AHKswl2*~(IrBqRA!D0h~;w?+c7?sm8q;FID#~2@$GJ{Pq z9WL=fa>v{2TdL4ubciE=ty)tkKFwxuRjg+W;tC-$cn}gp_-9-};_$@o{{P`E)H+=boV`t98LwUt4h;%&oFQg!SZTI4j`eN)0=xjV$ zDAV@EZOc?`XSQF*P`Wp`Qmkzs$(AD!Paz%}1=zD9!75yGJ)-JvFYbg#*~BNlOS*`U zds-9;Sq2kmoraitUW4vaGlQtn8h_?y(rw%jw-(=N|MSwwyb~UbVO?y<3LDMf5>`gr*Pj=<K1A~YM1zW%_oDP_2dyR#UAH5zPX7@oMS<`aZ01Z9qMansf=y4b z{)W}zE#z)tU9*?L2J+Ob`o?+Kwij}1_Gf2F z&3?#W5IjZ^+{v2V!kS$+v5%U4YoWJhA7(DPX79ms%6}XF_Fc0=Kc?xcnq{vjDs`C{ zIF$<^oHt>8j%Ty%txq9P2?7*Ii1it=>NC`P@Nald`QOFgzUxrv zFVyr^9S-lK4zri^sz6DdLTXlEm=zfIC1yAVi6OCa2d+U%{2`2wJi?UhX%HnU@Qt)o z;6O3RY#}+I!>YF1h*~PFth{5FT#h#ni#Hed3+Eh^j0pI&UnZS^A7{SM<6RZ8-pxM@yz6=XP_v)T<1A8BGnUMY;qm8 zxqebi7Te0W3p65={uqM}jVEPIqo|CM2w;OO3;-1=4R${`DM}l=&K{i-l$B z7`#8U6fr67>;yc8%?31VI)cx_7qJOUSb;#Su%)ViPsyr6^hUxQRE5#`85+D7Yf$y; zI09Gkk{#}zuGh(J5<^S2{oH|vU#Z9qZ= zvK^K+p?9pJKq)0jtl1{jgdub#f-WZZ-m2L|&Ch`x=(#F%z79Q4h0au=i*@J;Ds-X>eMpBMszUcs zp&dGOlnV9qVS9CZN;sLil)R!^s_@H&lLq`yZg_0MPgP~biG(9~X6@DSmjO=aCgB9c z_yAym6CfjL1T1s{swGBK*<$|UAIa440eRibU;JZOtvsas3)aCgbwaBeH;nUDVhSx$ z2^))YGOdp7egttt61Qbx*+Q|LIG*BsD(2GyRj+u8#gkK@u<6XpKl)aDQ5Ahr75Wvc zNuX;Cn`xY>0u@LUP{|g^--QL68au)mG?L|%`XQA+CzOB3BmvG7V(&|+yn{AO$3hww ziS<$)PokXigyB#FLe+9wHQp#TX1YK) zfL5YEi=sNy7hM4%AXe0go>0-@m?eke+~|{a^q3QUfr=i}(Mxip@2aE6o#+cy^tg^5 z%8mX`y<$dqmsuUS(sX7RD++2N>gzIVW)#1;T;Wj&UMfqt6C5g&&b*=Vn1c&DX4dFw zjmH)4|75M|5B%;&pli?T-OJ)Y4{E6~wZ8h{?OR~1qBfZZ@U9eygKg;hqngTEN7?nbM>_FHDPu6iPG>&8Op&YB zGh$HLbmlDvLUz?GoBE(((T1gXrppx53d?LMTdESy85UO}uRvuIZI&Z){LW``21K2Q znDd~d21uNbn-?Ey7zc_eH!z0P49;-nLxQGck*LyI@Hf_wB2lVH9HU8ym5^PR3!0Zj zBCbh1WJr`L68$uZYE4=1ga~K+9D;l6K?OAs$kfGur1&gK7<>5(ogdq7Wfx-h)vdpp`N= ziSG)dQFrO;SQ>39D8+wn1uT0l8Kl97ef7imuGOB#)zCFuYdmsEXJ(*aIj(0kS#mT} zqKsmcr1Xo1#F4Tgmc4&#-Ts4wq zB&x1RRTWjD9f|6<7^SNq>DrCabBUutDXG8`-VEZBMOdj7M$)>$n-p@1llTptU91E zC>*<{yFm#k#6a6@jf~UCms%kLZM7OH(#X3mlF-Pfuy;~h?;;Hv*{qRYxya2LY17E9 zE^@C%9@0p?i~L$6H)-T-7g?>5I*m+skqsI-LnHgS$R>?U(a2yIc}F8-H1e6Q-9TGL zBLR)P8)@lNnWT^$S#8M>v4L@6{w|jIij7N6LKCxj>rk2gd#a1l+dW05K3rZ zPRI@rw`N?0s%H`OKYXy6ifP# zJq6{2%+Oe;Gw)r5;f>^hkqQfG&wf3HG~C*SV70V^nvtr-uhgtmI9`T=$zIhw1Q&e% zGnY^8w3e#aLLz$sSSe-|2iA~w+gM%3FOfN_c%W2q_7v1+@xM@;^$`?#XhC9{rA@#8 zI47ILV23~G!BAeUUQA_>KpcbN1)zT)}*gHQ=1L-ykt4bVCQyse3w?grkqY82qpLHb@w1oxOM?wYYhhM}m zgkhrp2~F#SP3!X>Gq;^DYNkPSxoj|@z}bykz5pAuK_sAvc;Zze9%pQWvV7^#$b6`h z>olH>O8}~`>f1Wv&}H&%>vHA-(PfrTIdqn}XI{F&N5`VWX!@JQVBkBf4;Y)uHqb`! zk2^rbUhqsqeM!P$sITw=0X)Qv|JYZSkyD8~Jv#^USeSYuDP~^cY{eiAF8TAfaZ7>h zI;bCnT@aFK{b24tAo;FWK-WaX){Ddy4xs^bVJdeS2w|p+oZxG4*%6UAarGP|22F;} z2_CE9qzp4k+{kMw^^hKL449*80q>pd<*>@tELY~zxd`T13#p_i_~0BlQz&r+@i(}# zsy`VE;PXH?DAs>Uzk2S)U{P=aq`D9{AB@OQE}SD61fsjqUpC)xN?i6hgoCR@Yl`P3 zi&<0%3V+coS&Qq*ZXN<#h|-s`^!P2|FNa0qQhDGhPVd;4r76Tb7urf5|n)Db@eUy!5Z)ljq}l5w^zBuiWITm z|4}jeeGuz92j7f#eGh-QBB_`_2dbUl!e^d6hnb@sPV>DOHZ97O?3SgP#b^g|yxIap z5U*D2NUq9xsOAGiDN|$ko$CN`d63*8(ODed!CLCp(1Ezq6T5vMtf*l*l8WmBocRWp zf|PU7py@X7b10~!XHuA0Ix~LZH{$i`)TWJ75zgQRPB7es*2P+tF?GGoiMIL2-*8?8 z5T~e>(#f;{wn&f?uxd65Ll;-|lb6m|e;?Ywq5bMF5^~hiDk4?PsHJL~JkLv34d8=x z77~y%V$H|<{3J9UB%!8!i_h8QCWR+bs{jRSbxJu<-gHH&?6?6>vW2d~;I?-)OAH0(s{5F;SYCy=lDXh2D6$Szy37Jl zmw(+SGW;5-?-JoG<$vf{Y*W?}J((K}u>Fq(7A~cisD;`{YlBn+PE#sdKhTu&*YWet zc#FLhww?;3kH5-Et6NXihAG*Be|dGBz1x5?R2on|&>0eOq6}#=@yP4k#06W z8P!nv&~4;5_}v^QeZYOW-NC!q34W7J%XW6`!63CQIjM}Tn6m7EYRi6t`u}n>{A#gG z{vuwf=@)?@HqmyBW7XDv4~2zu20uT(au;QR>9@LFUpIMA}3@p>jSI&l5TUGPy`p?U_7jAC#IsBRT;t5cX+TY>NMPdB;K@xv19)v&h$K%f>FW}D) zxo_gq4~5TE9L^rpsI@iIb9b6mHDE8x(SMX~)ofJ2Y@SYnUcB@jRBCX?300Yp#{4v@ zoySO!)=W0U*bPh?(_d3Gm?5=ob*Vbsgcq9VBm4t zkhT!kK%qf$m1Pwu6h7#A89Xl9raqE@)0W5qQ0qDwk->ANNX~V>t+SL=P&QYW(>}2> z(8G5zv4BrcO;h;jd4M^RDB&4uiD`U{z+S~bq5DvM>r-NhR?wl85K$0;$(6smMD})} z-oaHx%K!L7*ua!1tDK(fZd-Bpd^V5gpd84L<&I;CljXjFMQOqxm9gxl(fHns=12EL zSmIip^f^kB#o5z)hq)mZdmze{4aMF_z4gp4oo(N0vs(p(up2V0plFkCg6TQv6(byvAgX#de+akf9?waI*TI0%gb87@wy$z}lgmd4@Clp#)6 zhIrT}Wr&D3C7)r{vrvmR=Hryb7aBQR9!pxEuW|3`9 zPn`q?8#{)JJ&D?jmHiCC#>zkmZPh@L#!gz-YhUECF0Plb`bfxF*Lx=_LEF}qW&@>F zD8Hqt>Y(E3O(1#9?vJ3H*X%kE1b4ly20_s5sxa8|TBK4)SSK_=+wLyn6ZEbgSO z!0BjsulRD)+RP|9kp}KQJFr!Kf#FC6jYz#NpsIT4u5<$0C}q^!O`nR!#Z)amh&Soj z$Y6^-fqdUJIWvwSXQWZ4MjGQ}q!H#wV}Fh`4&X@RK#nxZInp?YBaQJKX-xQ#%F9Y+ zg(}^}fT4s9bbw9uQ1*2~_JE;UxCP?@5^c->vSqC*anGC;%ti1SJuuE*4H{W&I$v=x&&WRRib6vm(s zHSWos2QxVB+lWz;nh@V|FYaY>;)6mSuDWJBR+Wm4z*PQXWPvFl{`i7T2M|O7YWbQ{ zDCdC11jU8TbqG+UcSH{Y~K@21{27;poJVJorsg~I;AT_C~>|~KyeC?J(qBYX#;I3OW zw{gxm%g^YX@zJ|Fun^w`{X{;!Kn+Ax4LpetMuodz^BZhN-E0QvGY-LYgr998uLbdz zo28Vp%S|^LWtFm%MNXY~$;oE>63K=<;@ivqv&kkax)7ye#chYO$CLe2{x?lTr!eRi zoglH<(53uO^^O6Lh2n}A842$LX;E%Bw3VXzqgR9}BR`fk(;P^6(5XW^ZygI$fl(z^X7JL@ALne0hCA{e>aVq;zf*h+VhQT_RL9x74sPx2FJBS(e*vY`uILY= zT~~w;7Io4(NM=v*XnDP-93QU<55ZT-jod2|#F}3b93ECkBp>*p9A9ayzmAlp)l|y0$#jqyS;XnGSCM2~tHhkp z_U&2)3$lkOH+9^xeYmM_2_UgYUzAnb`m!T4d{dnorI^q=>$yLohjl~S%Na^$5UP%e zrIGRox_(g3dJFaBYjboblDh=NVe_~pGH-{I`XOvefvRvr)w3dSFynPFNRMqkS2D7m8 z+6aiLq6A$qAWHBV6lKvsS45498Xv`272`W<7NVjAlU3FbjTRN(Xnj!8)&~Oe(-4r7 zh*iP1ijOM3+Fe&IR;y7f{J-CsbMD@|yMbu!KObf9y=P|5oS8Xu=FBni6FE`fFv9{k4wD7hm>DURoB1)f)bQcN^o9S#(MST-#Cwa@?a z<}EyXf-qJtY3$?#6KPbF1O-^D7dXm~7x?4K*9N_mYGr~VSFQ4t#8x?1tL2I+R1VM@ z^hP;#hMds$suKQ(K^7oYlVR(`o!o?j5%EjgC;dp%JgJ{)?dnJqc4hFPd1L8PLq|I} z++wg{I@}JIcSsAzPXrsz!2>d0hX?#4lZa@|Rl8h~0}!7Z;w@_=0BgkH-In;^ugYyL z!D^+J1pN~lR74x`J=>k&_B*NOd#I7d$!M=&Afs5s@dQ!!;!qu6$IG`AOhWPYcSycL zw#?9|<^uqMA3y9WOO3q69}R&;@NolpfCnf;uGQk3tH#Tll~~oqpInmf6EO&r@B%y} zVgBN)A|%AimIcP529?pJ;6wrkM)rvS1S7FQ2f2^O(K_`WWkS;M`g`6Q{$OpzBBMK8 z55aT+LexPumwUh(vE3atPtAG=uIB(fg$*Qj%n$csTNWCkEM*(Z$rNDZxxr#PSgz+? zN1yXh2hJdaQ%4$1Z6O>GCy^Zv6dJclt#1wPF8HfyI4O=DF^}fQi)lFQj(zR&tyIv6 zc*Ciln?3_`Wd}0sWycF~3GZ;g61+FMP<15=PJ9nH6=~wwjf21G7i0%mBA<`r{sRY7%6|8%#bqT5YFpNx$Qgvq)ExM-l}h9CHM6R7xQa;AD&E zrt6d7JzU?s*FN`n&?o5e;{KZ(!5q{i4z%V#v~m`oG|p4ks$L>=i0YO=tn}EM5a)KOo@Dg*4FdE})49sILH(r-2S|0Sz}m$+6#V zNt|*&vLgdFY~GTXf`4dL32=d2e*Vy6T-5jz-Dp{}S9jn}X7CuP;CZtbComB|Ot(@& zT>Hq>|lQPTxiMSPI<1l8Agp)W+#xI1P=wQRp!2-cp|2#+w z&H)ju?j0$R9?2Jx$E=!hD)yWlhVQI^_WfuZ^du`71eRq_5Afaq9+wwA5WrCd-pf)R z$O|{{blf0uple;poAFT)3yL*O2h;~1E<0O!7z(nxDp^@I&*VX1ON9k|W*7tk|M?v9 z9E|PeqVHyfIKg_KDJ?YIYzinhR!aH7*r{nL*+pHaH6U@lIxizd*@i*N*Ix_GD)&6! z?F`{2I?A*(+&6Akd*}ioaL9X#l|o-jWX5=v>Ld^ttOUkc0t2%N^tS{CS^{24?`hfw z>18wo2Q*wZO_`;-pSs?o?hIxLJjTd+bq|sCwSo|gJ%iia3<4=wf14?`!oJSjTVW$D zu{B|1MiRXKR*2PB(LI8b;K0E3b&jmZfc-D86ZZG9V41Q8of*eDg-T;aSVes#@E0q- z>?@?KGDS^%b50ow72hlA=P}CL3d}wLV=|mpT~?){-V=5GQtL7qv&KwO6Z&8y>(f9K z7y|_(7@O>>!^f(a>aph!8n$ZB z0Jir09in8g_LLw5V=3I`X3q!t)c?s8TM<8J?yZR7Vu!k&2WNU|2Pa;3R;9{wIBGpa z*~A%;;!MKWZjlXNq5`Cy_f~kv&M^bcg1^S&Ylphp)7=YAcR2HWWd^%l{lBjlndw_n z=mZ(e2>2nwOEA`k=>Sk>3Q91xjI#sNh76v>={DVN0Ib}uH}_Utl2ABT-yXBdE3q#*B`|IAb`f~AnJ%AsjS{v)WM)SO zu(h$fK@yxCBM8A*ldA@A7og8Tz1ENw%X{FX1W~TF-p15mAU}jgr2*&s#omGjK zA#r?7<4n1g*eG*vB?ia0tBZtJt8_bV>w2V41l9?g0`0P{D;2s^>nhC|F zrYis|Qo@~C7l2IwHW7mQYL@VPNGC!nU3GO4i;R3y{hLz-&8a@ksh-X0m8p8&#$JlB zbP%G_Lac*hoe&E@ljHfJvUoc)nFW~mGs@>7P=%1{=jg_`98?so1{c-f0UBf8nI-#>{`iE=se|w1F&=aXpBd|ED`>LvBP9|@>hDWY8zZwyAo?BfU(+w zU~CEW3IhMWhE)e+Oh(x1xz)ZP5Zx0of6zlPe4UHnpY{jAH5gX}JfEil!x!Ui{YL+r z3&}i}TIaYB?jpji7NJ{ogdhZ$wgcmloEYa3gTc5|0WO_kEVzVNm*&LUk63#H3(YG) z^CYshM6_9@g6K#$?&9*_`vLo(aQ@lN>Sn8}Yjh#3CIWL=g5Yh|x<`y4JQ%kSW3I(O zv+C?vqs_WAC)Vl2Ith?y*0`&;rZs7oe~P6NZgO!ukW>n6-5#y&VG(>cxez|y7YOgc zT)oX(LHU32u+_60<7r|%ZZXij`^}gY2(}RG|8inoO{^J!MDtFasamVDL_}-atg9{d zvSt^T+&U-9E z@%=7@Gk}mf-Lwgg8J-qj1V(4NI45`s!S~h%MRAla!KE?da)Rdp955s8ewSh{1_T6+ znUh}+mp5bzF+Rvn31+biz`RO{5Me+p=hwOLhHhl|%1FH3N$&5s4^vZ2Rd7^smh`9Y z&8$<7v_9c&MX8=xxGdzmu7h|CW?_N8+4%`M13lN*X|Xg|gMDr79CD{&0Pc-!j(qHZ zDJ1GBPzw_*iViXBOLF=sQ@y&1Jo7{5bg{aU;$-2S8Gs!U-6yyNrfCpxmKS!)$qb=z zyu5Z}^2`(Q-9JGkQ`qaEoBm5P_h!UWkep!3HK0lYH$u(#SLUp2af(jp}B;VzN>#W0yTaWC3$Lnw^LVs|#_9>rl+`Z#$> z5M@}`&~=N9uYzE4q6oc3VmEIQR*R;BDp!rp;4f3Rtj6giV@7n+Nj9MXqM9wDvY+#X zNnAKX&JHJ46rYt@9Joq~S((!mzK_tB*to}*Ef`K@RkPtAJzeEUe|FdOCn$zNacmyX z*+mD$d!8k@5pTqs(YVo+BW}*cjhyxsz)cl`+w%nnv*ThUMGKf`$9AZ7&sIHzb-gF> zPYb0Dv(^~*y%1V1y<8En#?v5TB+iE1IE#RjO!hXsXVp~naL$^dTdS!uH_mw0G%H<` zq{Tn_!)C5>RzSG03;rN)j-Ff)Y?y?mC9gqB5hDDdMnqWZ7NO*Stq3)zVMM68GZkSl zX19&o=~*CJ?Gh3`QXbdOJvxG&5B|M^y>1VWV8if$z{!wpHrla3OJ0p|N!ix4cz*O^ zPxYqu@m8(vS+xf;Yfo2BEKzJW)@!??a$iQ}-7?x9T(M4!YAdzh06K1l3k65pzLn}v zVD+;l&Z5<8+Y!pybOQzjNlX_6TeitUk1Q65vrQJ(4FL;3M*Cvy*=n2vIvxpRXkY9- z8|^q&-)PeRRsvhmzSN$r$DWzBd$li>XJh@P2$lEEsC;YM@1*v*pyO$KhW0zD{zO)P zlUWY1ZHM+}+DEyx-w6xbXR+YbekUxvHW)1QMt#l6?&?IARsVD+(jgH=+L8lXb&4wXRm)2inVlya>o>qkewWdI zvkZtI?{(qY+wC|cB0Kv&{ zAK5J2476mI^)AMnt;5OQy1jZA%gx3qWW^^U_tHhZOV!!@uOF1r>>Q3G8|yA$B{wjt zXiQuC*7V*TQAYo0B$j`T>Z#flL#g|ysTqQ4Dwxw z*ffLitr&4z@&=S(`-lYR*efm$Q;QJ0c5~wtaQ!+Ka6!n{&2^E+#WIl~Y@yje##;xvp)q>CuoH~+bwO-fZUviEZsjVs#pnHGxrM!K z;S;AKH}#`O#zk~uquH&WSP0Q!x!Wtc9Qa~++4$XoPw5fENKcR}IoF{xTz2qTEFRhRSQd(pDEm7Vj^O4%PLj8d zwRWHih}>X5P!)dMFDz>gNRGy_T{OVVOohDzfV?lEW{53B*dWPVRyAacs{N?`TBa%I1E z0+x%&2Eu{J9N>}&e|^z$6jL3psMv=fO6D?n&p+KqyoI)utAZuQTOzL&9%eQ?@;W5z zFi4u=RaK@0_=5h)$LJ2tY6{SeP^~-3^2@cn)|Sg=#9-_ZS&T9$)7B@L<&y1caI3;| zo@rJy?!o#3{J;}15ArB}d`XXkzYjPc1Y(b2|6WzaFwh};Or@RUq!dH z1((bVu{^$h<@?A*%o8$sYjMPnrIm$&4gK{UgQpMKI>0s4v9VBj%tZl{|6ZnTsNGkm zkln}u8)-#0j2lpHX=N(EC*F61ju#L-*suh`!su}NS@d$j*aLjH#J}Qf-bRrDgC#F- zWyktdd%WgN4uam3&Iz^18#oyn=3$%+4RZ}nhK4uH&&h6J*#i;ON%qB+3kHI(= z7%(Ze1Ba>2(+07Zn(>vp5{+5)=4+J9hx!Y&T}R+@#;>J`BDKnvk#6?Cf|pIU!umwp z-m(oWdoXv|b1a*qR{L2cQ=Leg>=c5M8pP zvDzIW>$7_TimW*Kn{c@QfU zv+NY3qQ!&p$pCAXUBy@i445Us#ViHS4jvc@(#~!qtP*XydaAUEC-r`$&65LpD_bhv zte+{2s6BcLA}o+&r7OG`qfo#BlOqhA>3IWb&N?7)(5xZiy<9j1`jVH*5RbQUKK zehahuhIx)`NQ1{POo7$5U#WTXWmMdbP|mRdg0Eo$qmogNIOh&`Gw$q|%pWK5z9%A)X$rGBTY(zxgk z2BSuYNkuy(=W_6`?EqF@Fj)`Mo}Pi2LrmG2`w(;Y3`~eAXdb!6l#RWq z53oOi>A+D;K82pF3;iJ5Jbp(qN!KvKmr1%}9@RvAA_Fl;yR#L1ATg(BV4~e;nMdw+ zXJdEt26kx%cEIHkJL&MP#KRHzKU%@p6S1wY7coaevsH97F`F_l(aiyv4g}u z7NGpPYjPqkpy^E~dPay7PS)G4`GxcdvBB-=pXdehT^u2NkGh7I8AR-KgwXdBoe{!= zc_=ZrIzk}L>>eRJ*jsu6`+qw^cm#A4>+9kO;bHV7B6d1LsDKA<_-a#{PEz*g8V&+spRL z|HTO55z{Qz+QkvV)7Xhb>~w@ki%DF72eUUZw>mSKoMq-wE!URdD4f8>BemDN1N#>l z*ttgtPebn|-uqa+?m`IQsqh>kF3dp8(a>xa?M2LsGceK6)664xL$k3z^8>pCpd2BZ zlf!U@A>!p@Ju|-&e02nwv-B({JsuRf-TDF&`x$3`9^yxk`1SIBpnGyAn)d+iOu(OU z=I0^)e7>3a4Jz++=I23}3xwo4Nfo=<7EO2n&mtgm%E<=^jf8zU=4{LsKh9rkP-Y50 z?uX5s!t;=xV8e+T!tHd7YV84lLy1?45^WMS3`MnYiNZK^MqjH9yH!8FLRmUJmlzc;s5GrqG$N zFny)}ckC-TsT~?kf3{i=$v{8ZI7z(QIk^0#C_5@|w}BuR!RPAH8Vo603KqG#&(l80 z{8Q62vw$nSz}FFYMHhijA@D5#21iFIb7$c4(W8VJjnsr$(-oya89n~f!4+0Mo`M6(i}H*WWG-r$?%H1}bQY4PYo$ZXVl9=J|CmdOpKtE? zFS@I)8~x@#Js$X#nK0oYw3mcOWkc5^t)AT}AWDcOMfqgR~LwR_n6?gvmD zo74{mt)x*>T4pd}DB>oMu%3nqn@ofj}^an+I2u^9n?v)!} zq1$Oo41ZkR3~M4*(N?jh7_2WJQ!MgC1iWd|mKbM9k-6Yfyg?aUipEWb7!?eAO#~d@ za^r7PSttw<1n^3Q{W$FU<&`ia?@s5tzgE$sC3t-tDi3={`QGT7?6o2)vyX-3!O(FX zS|pOwBH;u@2bv-gq!tNNDB6WZ*p>hy+?G%(#OylNyc{!ExTj*Ur@tKu&nl4jYNPMJRU1;hbTO|su3<-kHbe|6 zS6)&ZFHn)QS5uxm{zYC+DwOwqoV^|aeWm8u(atM1qxecq54=({vnGX~{F(_Vyn!HX zoUDBYyXEBs$@j)@-jX^A4kvkpxa42v2CJ?F7>^QKrC@vH2K(kbfc0p$r`Fcv9iIgh|u@-q^dwhC;fP> z>Z;*))RpvR{)4M9omL5!#Fl`zc3F_F`w}9?@s*%i(lX!=VjGD@x~nlSMEf~lW1z&O zd@&x~38rN}unfW?$+x~C6;>p5)SP5^ME8T_OInJQu(+K>6MGBl>nT#vU4 z!?HxuojFc8%aR<b-L1&>nc|E-^JJU$nevB~Sy}~{{p&cD%6zkMz!r8&i*Yn-KSyY(^2rsA zfX}~rNNMvPv}b}gCS?_FkdsdK;h9)Fj)p}8#X8j^@{(kp{6gC%}hR|b_w8lTgqARG~1;PFe$ zP&~nWr+xkMYIJk2^WWj0U}&tF*BBG|Z)>T0GP9ONpQ9GOpbg31E?U#q(TdP$XR{M; zxY_CFZ19|?Gg&DjD@VC3=4TLV)ias3EdLC(e5|wa(T9pD;eeY4RSnFf*NJIU!gm4t1zOT>uVEk^_8Q-_gG$|Y(K|Fg{w?g%+@lpQ{?RB;U4VKH)+#B8`&A|`LA1K7+?gmY zL3j#(fXi|V!c({rh0b7GgN&Ar?i`DT!ZaD@$T-aAI760z*&%E5CkiH`nE|5-`IH(j zN$m{-CPfCUJPpQ6f<0ltq{x8DU|3V^9!ui}Oo{;JIktywKtSa_Xz~tpUd%KYIdZ1K z0}rrw2zZBMw|D43d>#Z-xX4+rMOJ>0&##f{H;te?e~+An;Iunf!1)Ee^N8B$|HlEt zcvKZP{6-f6?^WE}^EF@KHBkPXq_9`xvw*Hs(a(;!zS~Z-VCV|NB72-nT&O?iBQK5* z-}%I9VbF3y@sjs+;&34W0g=3(BNMKRiS3z#RNE)DydeBk{i)QSU+d4=Kx4m<8sKz_ z%n8J&q9)D&iW2olD@f5~d;;UwlbeuW;>R$i(nVEsj$6zxf}L%T9Ii2lP@hf-f(`F* zV8g-Rzm|}f2afRWYz#T_6!AzqFDe>t8|p_@MC!p8RB(eQL;_WGHo7vD zmAmWS6}!wUZWK zN5-V8Rw!d^)A+hVE7EtB<$&Oc-Y1+LrsS}YFi7BB;4lPP4+ke&nqX26 zNQXtj0+pEQcMYK@_ym7+smt_I5bu_2lDOBoTHstgAXij`)(l&&FkSLQa6p|^BsLwX z%vDlA{ZS+PL?tnaSiz&h7vP3Rg|iO61jJf7F(p^*8|Wp^g;<&Gw-XKZDw3#@e)1Q@ zm7Ibu0GM>$7t90VN$=G%?Z8@>_TdJp&vfGor(Rc2e&ZAE$+aLQVtJ4ka`muWDI4IN zx1>M-a$e0wUvh=YqMBgU!tIBcl|a9LAU2;OhANlF;39G^+d&GP`^bDZdE;gt>MbW* zFe;da_$y=iq^6iytX~|3C4kWaLUw$`+bQ~r$@+2<9Af$`^O{ht=YW}4W|8TPcYuNo z@53Eg3+I$nMExi4Lw5W?up!#b1Inj+1RKtfr`v4tH%;4Yaj;>E)C*chB$tXPaf76E z^lU7EhBQ{F@anKl8!I9dZmg!BIgv zyZ_I3(;j=U(XXi)sLstz_UNBiqY&zT`hd;(^aDL)OK)3lX!!7^X{B`Dv2hlIY6FG>U7d(ib ze%%aQBfpa~=Vhdjv1{Jm&e+v{a^~1|w|glsFTO{h z9%-Ni3k=XZ2IxTn`aA9nrI%blD-6&q044r;1eMH44DIX(^GfW55Ar4EUkL{TeYc}6 z?y<6wdY`?TW28jG94G^cKkS7TFYzw}Q#elx+;Tw!^o|9o6qM$_mnB1ZI+7`whmUfi zQSU$;miKkM22$c(s>c7KtLS-C^fHU;83mh^e*n?aZo+@Se6uq^r@`&j_-o-mBze}& za+LdEp8qtsep4PiOb;1I@tH?CTeF_WhM_45=7l%L+viLPy@SKBHX!KO;H#N|TDJI7 zIR6&Ed966e-@IwKaShvTAL7-+jlm^T@DXx+_9hWr(r->d9m|4CYVZs#PjGNuhnHO7 zyH`p5^!DqJApY0yaXeb&n|1gUcwS`88l4MBPuYm2g4v%o)0cujZ?<|4o@&Tn%$70` zNQVS>@)3tIi479HN2s3ZDrExjjQKHZ9@VH#A2x()%{38k zl&8F+Gf-k&kJqbta>dqb&4@xUd6!RW*YVv%Bfgy=pTX*ALOspeZI_*&FVd}c4$aBokoKEk@7nET8x z6@($gzmxP!1nbFhghV9~406ZSZ>+cj+O01soY+LZ$A*}ze|!o3MPWX^HilUugn)mpL#_bXh2d4mK(<;T~r4a_M& z-Zmk5Ez3M{BZCjS2GLn={lq8O59oOypGwH*U{gh<^SPAI(BHXTp$H|30XMnc!wOnh zw)XW6bPKI{EwoBLc;;_-0Mbxtqr5uH3-#+<1X-vj=m4RK_+=DV3r#T zS{mM$BpS90030U105TI_lyk94=;=Zf0l^{I|J_cGbp;#d@G+EMjb9MdI9`N{AdyO_ zhX223m<)U4Z7V{OB=-NYd?;9EAZ{3mG)*dC2dYGt7$3%LDPHLs-7ldcpwMdA$^;_- z3E`JO_R0P51U2m^H3efK0q~zCHGp7C$!Zs=5J)BS(n7Q*?U7%+9GP==!lmVMxE;mM zSF>yI=CA*yp=?nwwxT;)-RS@RShj@q%wOZG=ef60&)otd>N8517BAn|ih_}Mk6=t3 z9czO%beA&d4{k+Hxu0>MFoL4KSw*5>VhzkJnm!JE?qT@c*)pMIBLOfy(P7$iDs&Gr z{fVFLQk#=pLG&`=0Wvtu^y~^3htsE^uB9Q-vb;oQ3ZtNu*EC#AOVStC?Uw#7WKS=ABJzu7NHuDUp`h_pLsxNX?-_2e9xvYK@Ca7AU z^f0*Cno_xsG)9K;Laf0`0#boVZ<6O`B^2qMzMHosU$ecE#)B!Njl%_<$6EVdAgF;Y|BtKUVs{l0Q~_iA#UA1S8tkg68Jju6HvG{_C*5OJ>RU?FQisp?uRbcL)MIZ* z73U9O6*Yy@9PMn9`#T=ro+vL!xjVc*@5|>34Z$3Ts2q_(KQOziP|C_moDCMnJ1i`C z*`@eyU?Eio)X}?3ryfJH={DBzgBxu{QpARQKgl-4L*+Th8GxTl^}$S86=cfFv`A(3 z=Yzbmn(tKMvCvbrigChAC$cKcAuD`YL&r%8nC9%`$m)y1(yGi14#Ft^jt&b|uefCO zI{IO10?W}(^xvpkSZJgO>rN$0VZCys6_$t0O(0`psyq!`G^d2Ppe^y*dUOhLmNg1bP+wsY!khO(M8V-3McLadMXV*#eDJ=NkJ}CyFWLHMU1d_vcsS z&^?X&m$WgC@^wD}2jwXl2g(5@pOdRIG?6TBOXRaPPC9`ZWHilen~b)nX#w=jb?Obm z5Ufca-@wnXqdr$Yc_)*3z7$eDO7nLszg>uf{#MX@lnjm z5QUv#i0)*WX^a$us<6`NKOc3pY;Y4Vp-db7$GIx6Sm&y|z*YJ4J39^3+43D{XwIIJ zq(oKT$?pfMj4F+cDEKPZ^(L1bJIpoF`^q)13Y@Ec&eZ_9G6F{Z2#%>uBjEX9g(){a zN(|}&E87cJ#@@syoIH~fC(ooE!98mu5pol0S}gn1n6zg-cK&>`p~{w!mi%(=6+{y` zizZQ-MQ`SL65zZVko;pS2BJ`}xF5|$0k!i9YbOkAr+jGpU!SS%kbBf9zpU|kRse(| z0P4&Hu`5vCz+U7?{5$8PpL10z78MO5Mx>GRZ`4EnJW2CAsyyPK;cO0hL_aih!AYbcyoWir`w}W zUQ)&mnEU&oo`-1D98_bzABrpM@Hfh}ma^soQ?oobSY(pe?v$}Z9XRi-Mfh21xMOQb z=mqR~wW4%4?bY^p(vr%0rv@qbH3aq8I$zUxo+(u#EJ;0Dpbanob0E z3Rr;K*cWQIL%=XzgOS6uXt1lOzbV=SMH-sN{{;M8p?Mf=82%z>Vd^kX)Wrq~W5{88 zHtoFMri#130l%AGhMl_ z9(V#rRKBA`FJY$wNh4WFN+#(us0QJvIEq@BgC>$3zr|cq4ZdjM_k$D$Sw}n=))A+A zNd09Fm;AD#$Ob)H!E$eNj13Q% z2k<%qqcic>Ik@o=+FvfSpGquSr6E0nq~m(LKACQchXwV4v}j zhE7&&%rOk%NVgvv~FXzEQ&8m)A_E6ynfSE&|xk2)9H?;|VtnPsaLU(m2^5i4vULbeYwQrl%dvA?3WzrASRuYpIi`ZvN(nEy)X9 z12)abovNO;iepwoXan?47tdc!SPz0)Y*bvpYuIV=3P3mdw|5o&fCjUu4~jHYynH2q za*dfISeLOegdxb<8u@5auw{>QQjpGVQtw<&;GzRvYN+1mQo~*#FJHU_ZUDGcLqL~s zO5I2WAGnad2D8Zz{JFZs|7F>bO@*6oVzc2+uhE3K-fB+VUTa!B`kqOP8+p4k<5!Dl zyRKY1D=G`3U-a)EM6RMk++X`VqJS%`bXDVGDYaCxq{}S>k}>c0)2lAYsJaKLhWI!1 z67e@&Z^j2!tf9K(&}F6HQ9jPJc8%AXR`(djLqpPr!NUng_Y}j}$J1T?Q}*x7F#5GZ z9wUMHukFbe&#dqdb3=QQ&L2S1E5i3>n^1ldQL`z+PX> zb77DAy{)g+>zt1ovIn`Q{anomeB?6Kqrg~lx#AWJcfr^qu~C188_AQUA4sH_A{`F7 zq4`(YKImwqrV0&yJCIANoA>REo#$F0)lopa8;Br_HE91jH?)V38wo9^5lErh$PL~;(>S=oLE~uYp36AiFX@b*`#@TZV-^sNaXjsY_AqiO zq4S!}yf`m?tb#Z!S@tlF6eAR$`D(cMA(QN^X=`lbKe70c^UKXph)q09UB*F5??F#Y zjFB0KvcpXo@1+d2vXdiZeG>nA^va~B-IeK%sA{^NVrvFzO|kLHrq~j4-4K#zVCwOu zI(W)+4A}A7%tQ!_)z+pCx7-=m0yNkwA zpuwd`rz#1cTnt+QLONI|R8cUdBZ!(vFm^lM#DGaOr^zU+NEopEwXplkiyZ#b@?HA1 zfwfA}=7eI6DyiGMiKH^81)aC@zL994|YWDxI7b>Vtx+-{qy^1fZ{1yn{kZX)@5X$qi z$~}NeobuTZTM}WhZU3Lp9ve@$@*16b!_(x||E#O%aZ~g>iV_W2ph*-L;-6o=DAP{P z5ScCE>L3;s2MjHS;A{MeSDyi)*{ivfh{F)DgBHvG`BKOg)8|$E)3*cv1hIE~Mzi0M2O)-7G_K8&9;Ew`@0F=1=dLq3aX_AF3zSd=>*)A(s+(M1z@&JaK*`(h%0AW?1 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�!aAZIt39-bB2bc;J1p7Y_!T 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 Si3xq7R#~=kHl`c Date: Sat, 8 Feb 2020 04:34:29 +0800 Subject: [PATCH 051/178] [daemon_base]fix error: syslog is not a member of DaemonBase (#4039) --- src/sonic-daemon-base/sonic_daemon_base/daemon_base.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py b/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py index a0a5bff0a297..d3807bf91524 100644 --- a/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py +++ b/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py @@ -102,15 +102,15 @@ def __init__(self): # Signal handler def signal_handler(self, sig, frame): if sig == signal.SIGHUP: - self.syslog.syslog(self.syslog.LOG_INFO, "Caught SIGHUP - ignoring...") + syslog.syslog(syslog.LOG_INFO, "Caught SIGHUP - ignoring...") elif sig == signal.SIGINT: - self.syslog.syslog(self.syslog.LOG_INFO, "Caught SIGINT - exiting...") + syslog.syslog(syslog.LOG_INFO, "Caught SIGINT - exiting...") sys.exit(128 + sig) elif sig == signal.SIGTERM: - self.syslog.syslog(self.syslog.LOG_INFO, "Caught SIGTERM - exiting...") + syslog.syslog(syslog.LOG_INFO, "Caught SIGTERM - exiting...") sys.exit(128 + sig) else: - self.syslog.syslog(self.syslog.LOG_WARNING, "Caught unhandled signal '" + sig + "'") + syslog.syslog(syslog.LOG_WARNING, "Caught unhandled signal '" + sig + "'") # Returns platform and hwsku def get_platform_and_hwsku(self): From cdab1fc49dd06ae45130e8608645a77c76a71718 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Fri, 7 Feb 2020 07:51:01 -0800 Subject: [PATCH 052/178] [frr]: Use tag for building frr (#4082) Changed logic for building frr. Previously we used latest commit in the FRR_BRANCH. Now the buildsystem will use a tag to identify a commit for building. New approach will let us to update sonic-frr without corrupting building sonic-buildimage. --- rules/frr.mk | 1 + src/sonic-frr/Makefile | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/rules/frr.mk b/rules/frr.mk index b2e347e0b12d..e5c9c230a766 100644 --- a/rules/frr.mk +++ b/rules/frr.mk @@ -3,6 +3,7 @@ FRR_VERSION = 7.2.1 FRR_SUBVERSION = 0 FRR_BRANCH = frr/7.2 +FRR_TAG = frr-7.2.1-s1 export FRR_VERSION FRR_SUBVERSION FRR_BRANCH diff --git a/src/sonic-frr/Makefile b/src/sonic-frr/Makefile index 8910798c5827..296f0226d2fe 100644 --- a/src/sonic-frr/Makefile +++ b/src/sonic-frr/Makefile @@ -11,7 +11,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : # Build the package pushd ./frr git checkout -b $(FRR_BRANCH) origin/$(FRR_BRANCH) - stg branch --create $(STG_BRANCH) $(FRR_BRANCH) + stg branch --create $(STG_BRANCH) $(FRR_TAG) stg import -s ../patch/series tools/tarsource.sh -V -e '-sonic' dpkg-buildpackage -rfakeroot -b -us -uc -Ppkg.frr.nortrlib -j$(SONIC_CONFIG_MAKE_JOBS) From 3ba436118dbecd3a9bc4e8d94167920d8bcdf397 Mon Sep 17 00:00:00 2001 From: Stepan Blyshchak <38952541+stepanblyschak@users.noreply.github.com> Date: Tue, 11 Feb 2020 09:54:38 -0800 Subject: [PATCH 053/178] [mellanox] enable ISSU on SPC2 systems (#4087) Signed-off-by: Stepan Blyschak --- .../mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/sai_3700.xml | 3 +++ .../mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/sai_3800.xml | 3 +++ 2 files changed, 6 insertions(+) diff --git a/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/sai_3700.xml b/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/sai_3700.xml index 8f6c427888b1..a7ac42950668 100644 --- a/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/sai_3700.xml +++ b/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/sai_3700.xml @@ -5,6 +5,9 @@ 00:02:03:04:05:00 + + 1 + 32 diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/sai_3800.xml b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/sai_3800.xml index 2d4c0f93d100..1b3c77ce381c 100644 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/sai_3800.xml +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/sai_3800.xml @@ -5,6 +5,9 @@ 00:02:03:04:05:00 + + 1 + 64 From a6acc1ef70146883fb1e8b80f48b941ee38bd364 Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Wed, 5 Feb 2020 01:09:16 -0800 Subject: [PATCH 054/178] teamd: fix possible race in master ifname callback (#4109) - What I did Ported a fix from libteam master to our master. Fixes #4070 Fixes #3649 - How I did it Applied patch jpirko/libteam@c723737 from upstream. - How to verify it Build image for your DUT and warm-reboot your DUT 10 times. Check that all PortChannels are up and no error messages in teamd.log --- ...sible-race-in-master-ifname-callback.patch | 101 ++++++++++++++++++ src/libteam/patch/series | 1 + 2 files changed, 102 insertions(+) create mode 100644 src/libteam/patch/0011-teamd-fix-possible-race-in-master-ifname-callback.patch diff --git a/src/libteam/patch/0011-teamd-fix-possible-race-in-master-ifname-callback.patch b/src/libteam/patch/0011-teamd-fix-possible-race-in-master-ifname-callback.patch new file mode 100644 index 000000000000..9203cd17c58b --- /dev/null +++ b/src/libteam/patch/0011-teamd-fix-possible-race-in-master-ifname-callback.patch @@ -0,0 +1,101 @@ +From c0eb9e4bfe1c6a0e77f02b1459d91498c1a3dcff Mon Sep 17 00:00:00 2001 +From: Pavel Shirshov +Date: Tue, 4 Feb 2020 09:39:08 -0800 +Subject: [PATCH 1/1] teamd: fix possible race in master ifname callback + +--- + teamd/teamd.h | 2 ++ + teamd/teamd_link_watch.c | 13 ++++++++++--- + teamd/teamd_per_port.c | 24 +++++++++++++++++++----- + 3 files changed, 31 insertions(+), 8 deletions(-) + +diff --git a/teamd/teamd.h b/teamd/teamd.h +index 418214d..1ce120e 100644 +--- a/teamd/teamd.h ++++ b/teamd/teamd.h +@@ -334,6 +334,8 @@ int teamd_port_remove_all(struct teamd_context *ctx); + void teamd_port_obj_remove_all(struct teamd_context *ctx); + int teamd_port_enabled(struct teamd_context *ctx, struct teamd_port *tdport, + bool *enabled); ++int teamd_port_enabled_check(struct teamd_context *ctx, ++ struct teamd_port *tdport, bool *enabled); + int teamd_port_prio(struct teamd_context *ctx, struct teamd_port *tdport); + int teamd_port_check_enable(struct teamd_context *ctx, + struct teamd_port *tdport, +diff --git a/teamd/teamd_link_watch.c b/teamd/teamd_link_watch.c +index 62f8267..e4b3d3f 100644 +--- a/teamd/teamd_link_watch.c ++++ b/teamd/teamd_link_watch.c +@@ -423,9 +423,16 @@ static int link_watch_refresh_forced_send(struct teamd_context *ctx) + int err; + + teamd_for_each_tdport(tdport, ctx) { +- err = teamd_port_enabled(ctx, tdport, &port_enabled); +- if (err) +- return err; ++ err = teamd_port_enabled_check(ctx, tdport, &port_enabled); ++ if (err) { ++ /* Looks like the options are not ready for this port. ++ * This can happen when called from ++ * link_watch_port_master_ifindex_changed(). Skip this ++ * for now, let it be handled by future call of ++ * link_watch_enabled_option_changed(). ++ */ ++ continue; ++ } + __set_forced_send_for_port(tdport, port_enabled); + if (port_enabled) + enabled_port_count++; +diff --git a/teamd/teamd_per_port.c b/teamd/teamd_per_port.c +index a87e809..d10cfb2 100644 +--- a/teamd/teamd_per_port.c ++++ b/teamd/teamd_per_port.c +@@ -395,19 +395,21 @@ int teamd_port_remove_ifname(struct teamd_context *ctx, const char *port_name) + return teamd_port_remove(ctx, tdport); + } + +-int teamd_port_enabled(struct teamd_context *ctx, struct teamd_port *tdport, +- bool *enabled) ++int __teamd_port_enabled(struct teamd_context *ctx, struct teamd_port *tdport, ++ bool *enabled, bool may_fail) + { + struct team_option *option; + + option = team_get_option(ctx->th, "np", "enabled", tdport->ifindex); + if (!option) { +- teamd_log_err("%s: Failed to find \"enabled\" option.", +- tdport->ifname); ++ if (!may_fail) ++ teamd_log_err("%s: Failed to find \"enabled\" option.", ++ tdport->ifname); + return -ENOENT; + } + if (team_get_option_type(option) != TEAM_OPTION_TYPE_BOOL) { +- teamd_log_err("Unexpected type of \"enabled\" option."); ++ if (!may_fail) ++ teamd_log_err("Unexpected type of \"enabled\" option."); + return -EINVAL; + } + +@@ -415,6 +417,18 @@ int teamd_port_enabled(struct teamd_context *ctx, struct teamd_port *tdport, + return 0; + } + ++int teamd_port_enabled(struct teamd_context *ctx, struct teamd_port *tdport, ++ bool *enabled) ++{ ++ return __teamd_port_enabled(ctx, tdport, enabled, false); ++} ++ ++int teamd_port_enabled_check(struct teamd_context *ctx, ++ struct teamd_port *tdport, bool *enabled) ++{ ++ return __teamd_port_enabled(ctx, tdport, enabled, true); ++} ++ + int teamd_port_prio(struct teamd_context *ctx, struct teamd_port *tdport) + { + int prio; +-- +2.17.1.windows.2 + diff --git a/src/libteam/patch/series b/src/libteam/patch/series index 7be69525d9d0..62c39e780f1a 100644 --- a/src/libteam/patch/series +++ b/src/libteam/patch/series @@ -8,3 +8,4 @@ 0008-libteam-Add-warm_reboot-mode.patch 0009-Fix-ifinfo_link_with_port-race-condition-with-newlink.patch 0010-When-read-of-timerfd-returned-0-don-t-consider-this-.patch +0011-teamd-fix-possible-race-in-master-ifname-callback.patch From e87f27050bfa86e3b81a247c97d4301f9831ed16 Mon Sep 17 00:00:00 2001 From: Prince Sunny Date: Thu, 13 Feb 2020 10:27:37 -0800 Subject: [PATCH 055/178] Update arp_update to refresh neighbor entries from APP_DB (#4125) --- files/scripts/arp_update | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/files/scripts/arp_update b/files/scripts/arp_update index 055aa98baf5d..4c7d655cfdaf 100755 --- a/files/scripts/arp_update +++ b/files/scripts/arp_update @@ -46,5 +46,26 @@ while /bin/true; do ip6cmd="ip -6 neigh show | grep -v fe80 | grep $vlan | cut -d ' ' -f 1,3 | $ndisc6cmd" eval `eval $ip6cmd` done + + # refresh neighbor entries from APP_DB in case of mismatch with kernel + DBNEIGH=$(sonic-db-cli APPL_DB keys NEIGH_TABLE*) + KERNEIGH4=$(ip -4 neigh show | grep Vlan | cut -d ' ' -f 1,3 --output-delimiter=',') + KERNEIGH6=$(ip -6 neigh show | grep -v fe80 | grep Vlan | cut -d ' ' -f 1,3 --output-delimiter=',') + for neigh in $DBNEIGH; do + intf="$( cut -d ':' -f 2 <<< "$neigh" )" + ip="$( cut -d ':' -f 3- <<< "$neigh" )" + if [[ $intf == *"Vlan"* ]]; then + if [[ $ip == *"."* ]] && [[ ! $KERNEIGH4 =~ "${ip},${intf}" ]]; then + pingcmd="timeout 0.2 ping -I $intf -n -q -i 0 -c 1 -W 1 $ip >/dev/null" + eval $pingcmd + logger "arp_update: mismatch arp entry, pinging ${ip} on ${intf}" + elif [[ $ip == *":"* ]] && [[ ! $KERNEIGH6 =~ "${ip},${intf}" ]]; then + ping6cmd="timeout 0.2 ping6 -I $intf -n -q -i 0 -c 1 -W 1 $ip >/dev/null" + eval $ping6cmd + logger "arp_update: mismatch v6 nbr entry, pinging ${ip} on ${intf}" + fi + fi + done + sleep 300 done From e1946432ff8441e20d0ae7142cbe6d0d9ae59c98 Mon Sep 17 00:00:00 2001 From: pra-moh <49077256+pra-moh@users.noreply.github.com> Date: Fri, 7 Feb 2020 07:46:29 -0800 Subject: [PATCH 056/178] [procdockerstats]: Update file permission for procdockerstatsd (#4126) --- files/image_config/procdockerstatsd/procdockerstatsd | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 files/image_config/procdockerstatsd/procdockerstatsd diff --git a/files/image_config/procdockerstatsd/procdockerstatsd b/files/image_config/procdockerstatsd/procdockerstatsd old mode 100644 new mode 100755 From 6143fdd54dd36eb476ae12b91f9a2225210471ec Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Wed, 12 Feb 2020 01:54:12 +0800 Subject: [PATCH 057/178] [process-reboot-cause]Clean up the process-reboot-cause as reqired in issue 3927 (#4128) --- .../process-reboot-cause/process-reboot-cause | 121 +++++++++++------- 1 file changed, 74 insertions(+), 47 deletions(-) diff --git a/files/image_config/process-reboot-cause/process-reboot-cause b/files/image_config/process-reboot-cause/process-reboot-cause index e5d228b4c6b6..409deb7d6859 100755 --- a/files/image_config/process-reboot-cause/process-reboot-cause +++ b/files/image_config/process-reboot-cause/process-reboot-cause @@ -62,10 +62,10 @@ def parse_warmfast_reboot_from_proc_cmdline(): if os.path.isfile(REBOOT_TYPE_KEXEC_FILE): with open(REBOOT_TYPE_KEXEC_FILE, "r") as cause_file: cause_file_kexec = cause_file.readline() - m = re.match(REBOOT_TYPE_KEXEC_PATTERN_WARM, cause_file_kexec) + m = re.search(REBOOT_TYPE_KEXEC_PATTERN_WARM, cause_file_kexec) if m and m.group(1): return 'warm-reboot' - m = re.match(REBOOT_TYPE_KEXEC_PATTERN_FAST, cause_file_kexec) + m = re.search(REBOOT_TYPE_KEXEC_PATTERN_FAST, cause_file_kexec) if m and m.group(1): return 'fast-reboot' return None @@ -77,13 +77,61 @@ def find_software_reboot_cause(): if os.path.isfile(REBOOT_CAUSE_FILE): with open(REBOOT_CAUSE_FILE, "r") as cause_file: software_reboot_cause = cause_file.readline().rstrip('\n') + log_info("{} indicates the reboot cause: {}".format(REBOOT_CAUSE_FILE, software_reboot_cause)) + else: + log_info("Reboot cause file {} not found".format(REBOOT_CAUSE_FILE)) if os.path.isfile(FIRST_BOOT_PLATFORM_FILE): os.remove(FIRST_BOOT_PLATFORM_FILE) return software_reboot_cause + + +def find_proc_cmdline_reboot_cause(): + proc_cmdline_reboot_cause = parse_warmfast_reboot_from_proc_cmdline() + if proc_cmdline_reboot_cause: + log_info("/proc/cmdline indicates reboot type: {}".format(proc_cmdline_reboot_cause)) + else: + log_info("No reboot cause found from /proc/cmdline") + return proc_cmdline_reboot_cause + + +def find_hardware_reboot_cause(): + hardware_reboot_cause = None + + # Until all platform vendors have provided sonic_platform packages, + # if there is no sonic_platform package installed, we only provide + # software-related reboot causes. + try: + import sonic_platform + + platform = sonic_platform.platform.Platform() + + chassis = platform.get_chassis() + + hardware_reboot_cause_major, hardware_reboot_cause_minor = chassis.get_reboot_cause() + + if hardware_reboot_cause_major == chassis.REBOOT_CAUSE_NON_HARDWARE: + # The reboot was not caused by hardware. If there is a REBOOT_CAUSE_FILE, it will + # contain any software-related reboot info. We will use it as the previous cause. + pass + elif hardware_reboot_cause_major == chassis.REBOOT_CAUSE_HARDWARE_OTHER: + hardware_reboot_cause = "{} ({})".format(hardware_reboot_cause_major, hardware_reboot_cause_minor) + else: + hardware_reboot_cause = hardware_reboot_cause_major + except ImportError as err: + log_warning("sonic_platform package not installed. Unable to detect hardware reboot causes.") + + if hardware_reboot_cause: + log_info("Platform api indicates reboot cause {}".format(hardware_reboot_cause)) + else: + log_info("No reboot cause found from platform api") + + return hardware_reboot_cause + + def main(): log_info("Starting up...") @@ -99,54 +147,33 @@ def main(): if os.path.exists(PREVIOUS_REBOOT_CAUSE_FILE): os.remove(PREVIOUS_REBOOT_CAUSE_FILE) - # Set a default previous reboot cause previous_reboot_cause = UNKNOWN_REBOOT_CAUSE - # Until all platform vendors have provided sonic_platform packages, - # if there is no sonic_platform package installed, we only provide - # software-related reboot causes. - try: - import sonic_platform - - # 1. Check if the previous reboot was warm/fast reboot by testing whether there is "fast|fastfast|warm" in /proc/cmdline - # If yes, the content of /hosts/reboot-cause/reboot-cause.txt will be treated as the reboot cause - proc_cmdline_reboot_cause = parse_warmfast_reboot_from_proc_cmdline() - if proc_cmdline_reboot_cause: - log_info("/proc/cmdline indicates reboot type: {}".format(proc_cmdline_reboot_cause)) - if os.path.isfile(REBOOT_CAUSE_FILE): - with open(REBOOT_CAUSE_FILE, "r") as cause_file: - proc_cmdline_reboot_cause = cause_file.readline().rstrip('\n') - else: - # /proc/cmdline says it's a warm/fast reboot but /host/reboot-cause.txt doesn't exist. - # This could happen when upgrading from a version doesn't support reboot cause. - log_info("Reboot cause file {} doesn't exist".format(REBOOT_CAUSE_DIR)) - - if proc_cmdline_reboot_cause is not None: - previous_reboot_cause = proc_cmdline_reboot_cause - else: - # 2. Check if the previous reboot was caused by hardware - # If yes, the hardware reboot cause will be treated as the reboot cause - platform = sonic_platform.platform.Platform() - - chassis = platform.get_chassis() - - hardware_reboot_cause, optional_details = chassis.get_reboot_cause() - - if hardware_reboot_cause == chassis.REBOOT_CAUSE_NON_HARDWARE: - # The reboot was not caused by hardware. If there is a REBOOT_CAUSE_FILE, it will - # contain any software-related reboot info. We will use it as the previous cause. - previous_reboot_cause = find_software_reboot_cause() - elif hardware_reboot_cause == chassis.REBOOT_CAUSE_HARDWARE_OTHER: - previous_reboot_cause = "{} ({})".format(hardware_reboot_cause, optional_details) - else: - previous_reboot_cause = hardware_reboot_cause - except ImportError as err: - log_warning("sonic_platform package not installed. Unable to detect hardware reboot causes.") - - # If there is a REBOOT_CAUSE_FILE, it will contain any software-related - # reboot info. We will use it as the previous cause. - previous_reboot_cause = find_software_reboot_cause() + # 1. Check if the previous reboot was warm/fast reboot by testing whether there is "fast|fastfast|warm" in /proc/cmdline + proc_cmdline_reboot_cause = find_proc_cmdline_reboot_cause() + + # 2. Check if the previous reboot was caused by hardware + # If yes, the hardware reboot cause will be treated as the reboot cause + hardware_reboot_cause = find_hardware_reboot_cause() + + # 3. If there is a REBOOT_CAUSE_FILE, it will contain any software-related + # reboot info. We will use it as the previous cause. + software_reboot_cause = find_software_reboot_cause() + + # The main decision logic of the reboot cause: + # If there is a reboot cause indicated by /proc/cmdline, it should be warmreboot/fastreboot + # the software_reboot_cause which is the content of /hosts/reboot-cause/reboot-cause.txt + # will be treated as the reboot cause + # Elif there is a reboot cause indicated by platform API, + # the hardware_reboot_cause will be treated as the reboot cause + # Else the software_reboot_cause will be treated as the reboot cause + if proc_cmdline_reboot_cause is not None: + previous_reboot_cause = software_reboot_cause + elif hardware_reboot_cause is not None: + previous_reboot_cause = hardware_reboot_cause + else: + previous_reboot_cause = software_reboot_cause # Write the previous reboot cause to PREVIOUS_REBOOT_CAUSE_FILE with open(PREVIOUS_REBOOT_CAUSE_FILE, "w") as prev_cause_file: From 80e388d6a08d657687b7298d7b41eb390ad4a38a Mon Sep 17 00:00:00 2001 From: zhenggen-xu Date: Sun, 9 Feb 2020 20:34:55 -0800 Subject: [PATCH 058/178] [docker-lldp] Fix lldpcli issue when description has special characters (#4133) Before the fix: lldpcli configure ports Ethernet96 lldp portidsubtype local 'Eth1/1' description 50G|sonic1|Eth1/3/2 bash: sonic1: command not found bash: Eth1/3/2: No such file or directory After fix: lldpcli configure ports Ethernet96 lldp portidsubtype local 'Eth1/1' description '50G|sonic1|Eth1/3/2' run successfully. Signed-off-by: Zhenggen Xu --- dockers/docker-lldp-sv2/lldpmgrd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockers/docker-lldp-sv2/lldpmgrd b/dockers/docker-lldp-sv2/lldpmgrd index 36b6e67a5f47..7e9ef1642a06 100755 --- a/dockers/docker-lldp-sv2/lldpmgrd +++ b/dockers/docker-lldp-sv2/lldpmgrd @@ -153,7 +153,7 @@ class LldpManager(object): # if there is a description available, also configure that if port_desc: - lldpcli_cmd += " description {}".format(port_desc) + lldpcli_cmd += " description '{}'".format(port_desc) else: log_info("Unable to retrieve description for port '{}'. Not adding port description".format(port_name)) From c70a7b877de6d0724c1fe01e90c6d415d4633832 Mon Sep 17 00:00:00 2001 From: pra-moh <49077256+pra-moh@users.noreply.github.com> Date: Mon, 10 Feb 2020 11:08:42 -0800 Subject: [PATCH 059/178] [procdockerstatsd] Fix incorrect case issue in service file (#4134) --- files/image_config/procdockerstatsd/procdockerstatsd.service | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/image_config/procdockerstatsd/procdockerstatsd.service b/files/image_config/procdockerstatsd/procdockerstatsd.service index 4e38c350a577..010dac15b2e6 100644 --- a/files/image_config/procdockerstatsd/procdockerstatsd.service +++ b/files/image_config/procdockerstatsd/procdockerstatsd.service @@ -6,7 +6,7 @@ After=database.service updategraph.service [Service] Type=simple ExecStart=/usr/bin/procdockerstatsd -Restart=Always +Restart=always [Install] WantedBy=multi-user.target From 63b00382efae09f1655aff4c9d8c0463f8a2bdc0 Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Mon, 10 Feb 2020 17:16:42 -0800 Subject: [PATCH 060/178] [sonic-buildimage] Fix build issue for docker-dhcp-relay-dbg.gz. Issue (#4136) is coming becuase some of debian package not able to fetch. Signed-off-by: Abhishek --- build_debug_docker_j2.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_debug_docker_j2.sh b/build_debug_docker_j2.sh index 3655ac037bd6..0b167cf0f39e 100755 --- a/build_debug_docker_j2.sh +++ b/build_debug_docker_j2.sh @@ -28,7 +28,7 @@ debs/{{ deb }}{{' '}} {% if $3 is defined %} {% if $3|length %} -RUN apt-get install -f -y \ +RUN apt-get update && apt-get install -f -y \ {% for dbg in $3.split(' ') -%} {{ dbg }}{{' '}} {%- endfor %} From f061353655fc7a429d35d5cda1c085bd3c5b72a5 Mon Sep 17 00:00:00 2001 From: yozhao101 <56170650+yozhao101@users.noreply.github.com> Date: Fri, 7 Feb 2020 12:35:35 -0800 Subject: [PATCH 061/178] [init_cfg.json] Maintain a separate init_cfg.json.j2 template file (#4092) --- files/build_templates/init_cfg.json.j2 | 20 +++++++++++++++++++ .../build_templates/sonic_debian_extension.j2 | 8 +++----- 2 files changed, 23 insertions(+), 5 deletions(-) create mode 100644 files/build_templates/init_cfg.json.j2 diff --git a/files/build_templates/init_cfg.json.j2 b/files/build_templates/init_cfg.json.j2 new file mode 100644 index 000000000000..33cfe990f900 --- /dev/null +++ b/files/build_templates/init_cfg.json.j2 @@ -0,0 +1,20 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "default_bgp_status": {% if shutdown_bgp_on_start == "y" %}"down"{% else %}"up"{% endif %}, + "default_pfcwd_status": {% if enable_pfcwd_on_start == "y" %}"enable"{% else %}"disable"{% endif %} + } + }, + "CRM": { + "Config": { + "polling_interval": "300", +{%- for crm_res in ["ipv4_route", "ipv6_route", "ipv4_nexthop", "ipv6_nexthop", "ipv4_neighbor", + "ipv6_neighbor", "nexthop_group_member", "nexthop_group", "acl_table", + "acl_group", "acl_entry", "acl_counter", "fdb_entry"] %} + "{{crm_res}}_threshold_type": "percentage", + "{{crm_res}}_low_threshold": "70", + "{{crm_res}}_high_threshold": "85"{% if not loop.last %},{% endif -%} +{% endfor %} + } + } +} diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 4f9c333873ee..e761c579feba 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -265,11 +265,9 @@ sudo bash -c "echo dhcp_as_static=true >> $FILESYSTEM_ROOT/etc/sonic/updategraph {% else %} sudo bash -c "echo enabled=false > $FILESYSTEM_ROOT/etc/sonic/updategraph.conf" {% endif %} -sudo bash -c "echo '{ \"DEVICE_METADATA\": { \"localhost\": { \"default_bgp_status\": {% if shutdown_bgp_on_start == "y" %}\"down\"{% else %}\"up\"{% endif %}, \"default_pfcwd_status\": {% if enable_pfcwd_on_start == "y" %}\"enable\"{% else %}\"disable\"{% endif %} } }, -{%- print ' \\"CRM\\": { \\"Config\\": { \\"polling_interval\\": \\"300\\", ' %} -{%- for crm_res in ["ipv4_route", "ipv6_route", "ipv4_nexthop", "ipv6_nexthop", "ipv4_neighbor", "ipv6_neighbor", "nexthop_group_member", "nexthop_group", "acl_table", "acl_group", "acl_entry", "acl_counter", "fdb_entry"] -%} -\"{{crm_res}}_threshold_type\": \"percentage\", \"{{crm_res}}_low_threshold\": \"70\", \"{{crm_res}}_high_threshold\": \"85\"{% if not loop.last %}, {% endif %} -{%- endfor %} } } }' >> $FILESYSTEM_ROOT/etc/sonic/init_cfg.json" + +# Generate initial SONiC configuration file +j2 files/build_templates/init_cfg.json.j2 | sudo tee $FILESYSTEM_ROOT/etc/sonic/init_cfg.json # Copy config-setup script and service file j2 files/build_templates/config-setup.service.j2 | sudo tee $FILESYSTEM_ROOT/etc/systemd/system/config-setup.service From 984c43e01da4a37651fd3bda50a3e67bf7cc5fc8 Mon Sep 17 00:00:00 2001 From: yozhao101 <56170650+yozhao101@users.noreply.github.com> Date: Tue, 11 Feb 2020 11:05:21 -0800 Subject: [PATCH 062/178] [init_cfg.json] Add new FEATURE and CONTAINER_FEATURE tables (#4137) * [init_cfg.json] Add a new table CONTAINER_FEATURE. Signed-off-by: Yong Zhao * [init_cfg.json] Update the content of table CONTAINER_FEATURE. Signed-off-by: Yong Zhao * [init_cfg.json] Use the template to generate the table CONTAINER_FEATURE. Signed-off-by: Yong Zhao * [init_cfg.json] Add a new table FEATURE. Signed-off-by: Yong Zhao * [init_cfg.json] Change the order of container names according to alphabetical order. Signed-off-by: Yong Zhao * [init_cfg.json] Change the dhcp_relay container name and add rest-api. Signed-off-by: Yong Zhao --- files/build_templates/init_cfg.json.j2 | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/files/build_templates/init_cfg.json.j2 b/files/build_templates/init_cfg.json.j2 index 33cfe990f900..bc2eff3ede56 100644 --- a/files/build_templates/init_cfg.json.j2 +++ b/files/build_templates/init_cfg.json.j2 @@ -16,5 +16,21 @@ "{{crm_res}}_high_threshold": "85"{% if not loop.last %},{% endif -%} {% endfor %} } + }, + "FEATURE": { +{%- for feature in ["sflow", "telemetry"] %} + "{{feature}}": { + "status": "disabled" + }{% if not loop.last %},{% endif -%} +{% endfor %} + }, + "CONTAINER_FEATURE": { +{%- for container in ["bgp", "database", "dhcp_relay", "lldp", "pmon", "radv", "rest-api", "sflow", + "snmp", "swss", "syncd", "teamd", "telemetry"] %} + "{{container}}": { + "auto_restart": "disabled", + "high_mem_alert": "disabled" + }{% if not loop.last %},{% endif -%} +{% endfor %} } } From 71225ea4cccd3fe793a6d3536b2e607e5e31268d Mon Sep 17 00:00:00 2001 From: yozhao101 <56170650+yozhao101@users.noreply.github.com> Date: Fri, 7 Feb 2020 12:34:07 -0800 Subject: [PATCH 063/178] [Service] Enable/disable container auto-restart based on configuration. (#4073) --- .../docker-dhcp-relay.supervisord.conf.j2 | 2 +- dockers/docker-lldp-sv2/supervisord.conf | 2 +- dockers/docker-orchagent/supervisord.conf | 2 +- .../docker-pmon.supervisord.conf.j2 | 2 +- .../docker-router-advertiser.supervisord.conf | 2 +- dockers/docker-sflow/supervisord.conf | 2 +- dockers/docker-snmp-sv2/supervisord.conf | 2 +- .../docker-sonic-telemetry/supervisord.conf | 2 +- dockers/docker-teamd/supervisord.conf | 2 +- files/scripts/supervisor-proc-exit-listener | 42 +++++++++++++++++-- .../docker-syncd-bfn/supervisord.conf | 6 +++ .../docker-syncd-brcm/supervisord.conf | 2 +- .../cavium/docker-syncd-cavm/supervisord.conf | 2 +- .../docker-syncd-centec/supervisord.conf | 2 +- .../docker-syncd-mrvl/supervisord.conf | 6 +++ .../docker-syncd-mrvl/supervisord.conf | 6 +++ .../docker-syncd-mrvl/supervisord.conf | 2 +- .../docker-syncd-mlnx/supervisord.conf | 2 +- .../docker-syncd-nephos/supervisord.conf | 2 +- .../docker-dhcp-relay.supervisord.conf | 2 +- 20 files changed, 72 insertions(+), 20 deletions(-) diff --git a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 index 94fdbfdaff2f..d52400480775 100644 --- a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 +++ b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name dhcp_relay events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected diff --git a/dockers/docker-lldp-sv2/supervisord.conf b/dockers/docker-lldp-sv2/supervisord.conf index 3f3f5beabc8d..73ff52f4420e 100644 --- a/dockers/docker-lldp-sv2/supervisord.conf +++ b/dockers/docker-lldp-sv2/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name lldp events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected diff --git a/dockers/docker-orchagent/supervisord.conf b/dockers/docker-orchagent/supervisord.conf index 9ae2776f6d26..6b21d73f3c81 100644 --- a/dockers/docker-orchagent/supervisord.conf +++ b/dockers/docker-orchagent/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name swss events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected diff --git a/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 b/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 index 9a2414c30d05..13ae0e767ab2 100644 --- a/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 +++ b/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name pmon events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected diff --git a/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf b/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf index 4ea84ab11c92..bf9320acc776 100644 --- a/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf +++ b/dockers/docker-router-advertiser/docker-router-advertiser.supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-script] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name radv events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected diff --git a/dockers/docker-sflow/supervisord.conf b/dockers/docker-sflow/supervisord.conf index 50986f197d88..8eb1bdc05e57 100644 --- a/dockers/docker-sflow/supervisord.conf +++ b/dockers/docker-sflow/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name sflow events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected diff --git a/dockers/docker-snmp-sv2/supervisord.conf b/dockers/docker-snmp-sv2/supervisord.conf index 7fd16eec5bbe..992292330552 100644 --- a/dockers/docker-snmp-sv2/supervisord.conf +++ b/dockers/docker-snmp-sv2/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name snmp events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected diff --git a/dockers/docker-sonic-telemetry/supervisord.conf b/dockers/docker-sonic-telemetry/supervisord.conf index e1346fe7db4e..54f4c5b2348d 100644 --- a/dockers/docker-sonic-telemetry/supervisord.conf +++ b/dockers/docker-sonic-telemetry/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name telemetry events=PROCESS_STATE_EXITED autostart=true autorestart=false diff --git a/dockers/docker-teamd/supervisord.conf b/dockers/docker-teamd/supervisord.conf index 43d6d2d6d116..0c3071bbfdda 100644 --- a/dockers/docker-teamd/supervisord.conf +++ b/dockers/docker-teamd/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name teamd events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected diff --git a/files/scripts/supervisor-proc-exit-listener b/files/scripts/supervisor-proc-exit-listener index 8d1735cd2b0c..cf26d5383074 100755 --- a/files/scripts/supervisor-proc-exit-listener +++ b/files/scripts/supervisor-proc-exit-listener @@ -1,17 +1,34 @@ #!/usr/bin/env python +import getopt import os import signal import sys import syslog +import swsssdk + from supervisor import childutils # Contents of file should be the names of critical processes (as defined in # supervisor.conf file), one per line CRITICAL_PROCESSES_FILE = '/etc/supervisor/critical_processes' -def main(): +# This table in databse contains the features for container and each +# feature for a row will be configured a state or number. +CONTAINER_FEATURE_TABLE_NAME = 'CONTAINER_FEATURE' + +def main(argv): + container_name = None + opts, args = getopt.getopt(argv, "c:", ["container-name="]) + for opt, arg in opts: + if opt in ("-c", "--container-name"): + container_name = arg + + if not container_name: + syslog.syslog(syslog.LOG_ERR, "Container name not specified. Exiting...") + sys.exit(1) + # Read the list of critical processes from a file with open(CRITICAL_PROCESSES_FILE, 'r') as f: critical_processes = [line.rstrip('\n') for line in f] @@ -35,12 +52,29 @@ def main(): processname = payload_headers['processname'] groupname = payload_headers['groupname'] - # If a critical process exited unexpectedly, terminate supervisor - if expected == 0 and processname in critical_processes or groupname in critical_processes: + config_db = swsssdk.ConfigDBConnector() + config_db.connect() + container_features_table = config_db.get_table(CONTAINER_FEATURE_TABLE_NAME) + if not container_features_table: + syslog.syslog(syslog.LOG_ERR, "Unable to retrieve container features table from Config DB. Exiting...") + sys.exit(2) + + if not container_features_table.has_key(container_name): + syslog.syslog(syslog.LOG_ERR, "Unable to retrieve features for container '{}'. Exiting...".format(container_name)) + sys.exit(3) + + restart_feature = container_features_table[container_name].get('auto_restart') + if not restart_feature: + syslog.syslog(syslog.LOG_ERR, "Unable to determine auto-restart feature status for container '{}'. Exiting...".format(container_name)) + sys.exit(4) + + # If auto-restart feature is enabled and a critical process exited unexpectedly, terminate supervisor + if restart_feature == 'enabled' and expected == 0 and (processname in critical_processes or groupname in critical_processes): MSG_FORMAT_STR = "Process {} exited unxepectedly. Terminating supervisor..." msg = MSG_FORMAT_STR.format(payload_headers['processname']) syslog.syslog(syslog.LOG_INFO, msg) os.kill(os.getppid(), signal.SIGTERM) + if __name__ == "__main__": - main() + main(sys.argv[1:]) diff --git a/platform/barefoot/docker-syncd-bfn/supervisord.conf b/platform/barefoot/docker-syncd-bfn/supervisord.conf index 1e015fef931f..1744d6ffefb5 100644 --- a/platform/barefoot/docker-syncd-bfn/supervisord.conf +++ b/platform/barefoot/docker-syncd-bfn/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener --container-name syncd +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 diff --git a/platform/broadcom/docker-syncd-brcm/supervisord.conf b/platform/broadcom/docker-syncd-brcm/supervisord.conf index cd6712acbf22..3fa8febb85d8 100644 --- a/platform/broadcom/docker-syncd-brcm/supervisord.conf +++ b/platform/broadcom/docker-syncd-brcm/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name syncd events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected diff --git a/platform/cavium/docker-syncd-cavm/supervisord.conf b/platform/cavium/docker-syncd-cavm/supervisord.conf index c823ab5680ef..0c6285d46ae0 100644 --- a/platform/cavium/docker-syncd-cavm/supervisord.conf +++ b/platform/cavium/docker-syncd-cavm/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name syncd events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected diff --git a/platform/centec/docker-syncd-centec/supervisord.conf b/platform/centec/docker-syncd-centec/supervisord.conf index c823ab5680ef..0c6285d46ae0 100644 --- a/platform/centec/docker-syncd-centec/supervisord.conf +++ b/platform/centec/docker-syncd-centec/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name syncd events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected diff --git a/platform/marvell-arm64/docker-syncd-mrvl/supervisord.conf b/platform/marvell-arm64/docker-syncd-mrvl/supervisord.conf index 1af5d70a1d0c..b11e045fac7e 100644 --- a/platform/marvell-arm64/docker-syncd-mrvl/supervisord.conf +++ b/platform/marvell-arm64/docker-syncd-mrvl/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener --container-name syncd +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 diff --git a/platform/marvell-armhf/docker-syncd-mrvl/supervisord.conf b/platform/marvell-armhf/docker-syncd-mrvl/supervisord.conf index 1af5d70a1d0c..b11e045fac7e 100644 --- a/platform/marvell-armhf/docker-syncd-mrvl/supervisord.conf +++ b/platform/marvell-armhf/docker-syncd-mrvl/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener --container-name syncd +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 diff --git a/platform/marvell/docker-syncd-mrvl/supervisord.conf b/platform/marvell/docker-syncd-mrvl/supervisord.conf index aea4d45b9afd..43de2426f981 100644 --- a/platform/marvell/docker-syncd-mrvl/supervisord.conf +++ b/platform/marvell/docker-syncd-mrvl/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name syncd events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected diff --git a/platform/mellanox/docker-syncd-mlnx/supervisord.conf b/platform/mellanox/docker-syncd-mlnx/supervisord.conf index c823ab5680ef..0c6285d46ae0 100644 --- a/platform/mellanox/docker-syncd-mlnx/supervisord.conf +++ b/platform/mellanox/docker-syncd-mlnx/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name syncd events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected diff --git a/platform/nephos/docker-syncd-nephos/supervisord.conf b/platform/nephos/docker-syncd-nephos/supervisord.conf index c823ab5680ef..0c6285d46ae0 100644 --- a/platform/nephos/docker-syncd-nephos/supervisord.conf +++ b/platform/nephos/docker-syncd-nephos/supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name syncd events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected diff --git a/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf b/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf index a29982a646f4..fde1d6c7714d 100644 --- a/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf +++ b/src/sonic-config-engine/tests/sample_output/docker-dhcp-relay.supervisord.conf @@ -4,7 +4,7 @@ logfile_backups=2 nodaemon=true [eventlistener:supervisor-proc-exit-listener] -command=/usr/bin/supervisor-proc-exit-listener +command=/usr/bin/supervisor-proc-exit-listener --container-name dhcp_relay events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected From 3ac345922bca76f80d11f1f18efa6529d6204259 Mon Sep 17 00:00:00 2001 From: yozhao101 <56170650+yozhao101@users.noreply.github.com> Date: Tue, 11 Feb 2020 14:03:02 -0800 Subject: [PATCH 064/178] [Services] Restart database service upon unexpected critical process exit. (#4138) * [database] Implement the auto-restart feature for database container. Signed-off-by: Yong Zhao * [database] Remove the duplicate dependency in service files. Since we already have updategraph ---> config_setup ---> database, we do not need explicitly add database.service in all other container service files. Signed-off-by: Yong Zhao * [event listener] Reorganize the line 73 in event listener script. Signed-off-by: Yong Zhao * [database] update the file sflow.service.j2 to remove the duplicate dependency. Signed-off-by: Yong Zhao * [event listener] Add comments in event listener. Signed-off-by: Yong Zhao * [event listener] Update the comments in line 56. Signed-off-by: Yong Zhao * [event listener] Add parentheses for if statement in line 76 in event listener. Signed-off-by: Yong Zhao --- dockers/docker-database/Dockerfile.j2 | 2 + dockers/docker-database/critical_processes | 1 + dockers/docker-database/supervisord.conf.j2 | 7 ++++ .../single_instance/database.service.j2 | 4 ++ files/scripts/supervisor-proc-exit-listener | 40 ++++++++++--------- rules/docker-database.mk | 1 + 6 files changed, 37 insertions(+), 18 deletions(-) create mode 100644 dockers/docker-database/critical_processes diff --git a/dockers/docker-database/Dockerfile.j2 b/dockers/docker-database/Dockerfile.j2 index acb5e013fb84..8cd181614672 100644 --- a/dockers/docker-database/Dockerfile.j2 +++ b/dockers/docker-database/Dockerfile.j2 @@ -36,5 +36,7 @@ COPY ["supervisord.conf.j2", "/usr/share/sonic/templates/"] COPY ["docker-database-init.sh", "/usr/local/bin/"] COPY ["ping_pong_db_insts", "/usr/local/bin/"] COPY ["database_config.json", "/etc/default/sonic-db/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor"] ENTRYPOINT ["/usr/local/bin/docker-database-init.sh"] diff --git a/dockers/docker-database/critical_processes b/dockers/docker-database/critical_processes new file mode 100644 index 000000000000..7800f0fad3ff --- /dev/null +++ b/dockers/docker-database/critical_processes @@ -0,0 +1 @@ +redis diff --git a/dockers/docker-database/supervisord.conf.j2 b/dockers/docker-database/supervisord.conf.j2 index 110619f762be..442bec1438c8 100644 --- a/dockers/docker-database/supervisord.conf.j2 +++ b/dockers/docker-database/supervisord.conf.j2 @@ -3,6 +3,13 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener --container-name database +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + + [program:rsyslogd] command=/bin/bash -c "rm -f /var/run/rsyslogd.pid && /usr/sbin/rsyslogd -n" priority=1 diff --git a/files/build_templates/single_instance/database.service.j2 b/files/build_templates/single_instance/database.service.j2 index 472b9d328b7d..fd0063195e31 100644 --- a/files/build_templates/single_instance/database.service.j2 +++ b/files/build_templates/single_instance/database.service.j2 @@ -3,12 +3,16 @@ Description=Database container Requires=docker.service After=docker.service After=rc-local.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 [Service] User=root ExecStartPre=/usr/bin/{{docker_container_name}}.sh start ExecStart=/usr/bin/{{docker_container_name}}.sh wait ExecStop=/usr/bin/{{docker_container_name}}.sh stop +Restart=always +RestartSec=30 [Install] WantedBy=multi-user.target diff --git a/files/scripts/supervisor-proc-exit-listener b/files/scripts/supervisor-proc-exit-listener index cf26d5383074..cf154b3a5c10 100755 --- a/files/scripts/supervisor-proc-exit-listener +++ b/files/scripts/supervisor-proc-exit-listener @@ -52,24 +52,28 @@ def main(argv): processname = payload_headers['processname'] groupname = payload_headers['groupname'] - config_db = swsssdk.ConfigDBConnector() - config_db.connect() - container_features_table = config_db.get_table(CONTAINER_FEATURE_TABLE_NAME) - if not container_features_table: - syslog.syslog(syslog.LOG_ERR, "Unable to retrieve container features table from Config DB. Exiting...") - sys.exit(2) - - if not container_features_table.has_key(container_name): - syslog.syslog(syslog.LOG_ERR, "Unable to retrieve features for container '{}'. Exiting...".format(container_name)) - sys.exit(3) - - restart_feature = container_features_table[container_name].get('auto_restart') - if not restart_feature: - syslog.syslog(syslog.LOG_ERR, "Unable to determine auto-restart feature status for container '{}'. Exiting...".format(container_name)) - sys.exit(4) - - # If auto-restart feature is enabled and a critical process exited unexpectedly, terminate supervisor - if restart_feature == 'enabled' and expected == 0 and (processname in critical_processes or groupname in critical_processes): + # Read the status of auto-restart feature from Config_DB. + if container_name != 'database': + config_db = swsssdk.ConfigDBConnector() + config_db.connect() + container_features_table = config_db.get_table(CONTAINER_FEATURE_TABLE_NAME) + if not container_features_table: + syslog.syslog(syslog.LOG_ERR, "Unable to retrieve container features table from Config DB. Exiting...") + sys.exit(2) + + if not container_features_table.has_key(container_name): + syslog.syslog(syslog.LOG_ERR, "Unable to retrieve features for container '{}'. Exiting...".format(container_name)) + sys.exit(3) + + restart_feature = container_features_table[container_name].get('auto_restart') + if not restart_feature: + syslog.syslog(syslog.LOG_ERR, "Unable to determine auto-restart feature status for container '{}'. Exiting...".format(container_name)) + sys.exit(4) + + # If container is database or auto-restart feature is enabled and at the same time + # a critical process exited unexpectedly, terminate supervisor + if ((container_name == 'database' or restart_feature == 'enabled') and expected == 0 and + (processname in critical_processes or groupname in critical_processes)): MSG_FORMAT_STR = "Process {} exited unxepectedly. Terminating supervisor..." msg = MSG_FORMAT_STR.format(payload_headers['processname']) syslog.syslog(syslog.LOG_INFO, msg) diff --git a/rules/docker-database.mk b/rules/docker-database.mk index 91fd06819a4b..7e372048afab 100644 --- a/rules/docker-database.mk +++ b/rules/docker-database.mk @@ -28,3 +28,4 @@ $(DOCKER_DATABASE)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_DATABASE)_BASE_IMAGE_FILES += redis-cli:/usr/bin/redis-cli $(DOCKER_DATABASE)_BASE_IMAGE_FILES += monit_database:/etc/monit/conf.d +$(DOCKER_DATABASE)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) From f197f0d2a99c43f129cb3ee30e11baa7359fe1eb Mon Sep 17 00:00:00 2001 From: byu343 Date: Tue, 11 Feb 2020 18:44:25 -0800 Subject: [PATCH 065/178] [arista]: Fix convertfs condition for booting from EOS (#4139) Fix the issue of incorrectly skipping the convertfs hook when fast-reboot from EOS, by adding an extra kernel cmdline param "prev_os" to differentiate fast-reboot from EOS and from SONiC. This is because we still do disk conversion for fast reboot from eos to sonic, like format the disk. --- files/Aboot/boot0.j2 | 2 +- files/initramfs-tools/arista-convertfs.j2 | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/files/Aboot/boot0.j2 b/files/Aboot/boot0.j2 index 66e86774e766..88931b3dac39 100644 --- a/files/Aboot/boot0.j2 +++ b/files/Aboot/boot0.j2 @@ -362,7 +362,7 @@ write_boot_configs() { } run_kexec() { - local cmdline="$(cat $cmdline_image | tr '\n' ' ')" + local cmdline="$(cat $cmdline_image | tr '\n' ' ') $ENV_EXTRA_CMDLINE" local kernel="${KERNEL:-$(find $image_path/boot -name 'vmlinuz-*' -type f | head -n 1)}" local initrd="${INITRD:-$(find $image_path/boot -name 'initrd.img-*' -type f | head -n 1)}" diff --git a/files/initramfs-tools/arista-convertfs.j2 b/files/initramfs-tools/arista-convertfs.j2 index 535bb441f117..56616d2ba04a 100644 --- a/files/initramfs-tools/arista-convertfs.j2 +++ b/files/initramfs-tools/arista-convertfs.j2 @@ -18,6 +18,8 @@ flash_dev='' block_flash='' aboot_flag='' backup_file='' +prev_os='' +sonic_fast_reboot='' # Wait until get the fullpath of flash device, e.g., /dev/sda wait_get_flash_dev() { @@ -133,9 +135,11 @@ for x in "$@"; do docker_inram=*) docker_inram="${x#docker_inram=}" ;; + prev_os=*) + prev_os="${x#prev_os=}" + ;; SONIC_BOOT_TYPE=warm*|SONIC_BOOT_TYPE=fast*) - # Skip this script for warm-reboot and fast-reboot - exit 0 + sonic_fast_reboot=true ;; esac done @@ -143,6 +147,9 @@ done # Check aboot [ -z "$aboot_flag" ] && exit 0 +# Skip this script for warm-reboot/fast-reboot from sonic +[ "$sonic_fast_reboot" == true ] && [ "$prev_os" != eos ] && exit 0 + # Get flash dev name if [ -z "$block_flash" ]; then echo "Error: flash device info is not provided" From 887ea003e13efb844c411c1129b3b9af77976e5d Mon Sep 17 00:00:00 2001 From: rlhui Date: Sat, 15 Feb 2020 00:20:23 -0800 Subject: [PATCH 066/178] cherry pick PR 599 for ztp --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 2f1b64489ee9..6a36a6be6a0d 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 2f1b64489ee9bc8276bc0537c6099cf8e4597e04 +Subproject commit 6a36a6be6a0df48062902528970a97460c675bcf From 48f8a8d40ec52a6a0866aa22a231ff9163ec4305 Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Wed, 29 Jan 2020 13:55:50 +0800 Subject: [PATCH 067/178] [Mellanox] platform api support firmware install (#3931) support firmware install, including CPLD and BIOS. CPLD: cpldupdate BIOS: boot to onie and update BIOS in onie and then boot to SONiC --- .../build_templates/sonic_debian_extension.j2 | 1 + .../sonic_platform/chassis.py | 16 ++ .../sonic_platform/component.py | 220 ++++++++++++++++-- platform/mellanox/one-image.mk | 2 +- platform/mellanox/onie-fw-update | 120 ++++++++++ platform/mellanox/onie-fw-update.mk | 7 + platform/mellanox/rules.mk | 1 + 7 files changed, 351 insertions(+), 16 deletions(-) create mode 100755 platform/mellanox/onie-fw-update create mode 100644 platform/mellanox/onie-fw-update.mk diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index e761c579feba..aa44ca703507 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -445,6 +445,7 @@ sudo cp $files_path/$MLNX_SPC_FW_FILE $FILESYSTEM_ROOT/etc/mlnx/fw-SPC.mfa sudo cp $files_path/$MLNX_SPC2_FW_FILE $FILESYSTEM_ROOT/etc/mlnx/fw-SPC2.mfa sudo cp $files_path/$ISSU_VERSION_FILE $FILESYSTEM_ROOT/etc/mlnx/issu-version sudo cp $files_path/$MLNX_FFB_SCRIPT $FILESYSTEM_ROOT/usr/bin/mlnx-ffb.sh +sudo cp $files_path/$ONIE_FW_UPDATE $FILESYSTEM_ROOT/usr/bin/onie-fw-update.sh j2 platform/mellanox/mlnx-fw-upgrade.j2 | sudo tee $FILESYSTEM_ROOT/usr/bin/mlnx-fw-upgrade.sh sudo chmod 755 $FILESYSTEM_ROOT/usr/bin/mlnx-fw-upgrade.sh diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index 63d432eb0b89..38320c730cc9 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -11,6 +11,7 @@ try: from sonic_platform_base.chassis_base import ChassisBase from sonic_platform_base.component_base import ComponentBase + from sonic_device_util import get_machine_info from sonic_daemon_base.daemon_base import Logger from os import listdir from os.path import isfile, join @@ -54,6 +55,11 @@ def __init__(self): # Initialize SKU name self.sku_name = self._get_sku_name() + mi = get_machine_info() + if mi is not None: + self.name = mi['onie_platform'] + else: + self.name = self.sku_name # move the initialization of each components to their dedicated initializer # which will be called from platform @@ -136,6 +142,16 @@ def initialize_components(self): self._component_list.append(ComponentCPLD()) + def get_name(self): + """ + Retrieves the name of the device + + Returns: + string: The name of the device + """ + return self.name + + ############################################## # SFP methods ############################################## diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py index fd593f7bbe45..dc09ae4011fa 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py @@ -5,13 +5,16 @@ # # implementation of new platform api ############################################################################# - +from __future__ import print_function try: from sonic_platform_base.component_base import ComponentBase + from sonic_device_util import get_machine_info from glob import glob import subprocess import io + import os import re + import sys except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -19,11 +22,12 @@ COMPONENT_BIOS = "BIOS" COMPONENT_CPLD = "CPLD" -BIOS_QUERY_VERSION_COMMAND = 'dmidecode -t 11' -CPLD_VERSION_FILE_PATTERN = '/var/run/hw-management/system/cpld[0-9]_version' -CPLD_VERSION_MAX_LENGTH = 4 - class Component(ComponentBase): + def __init__(self): + self.name = None + self.image_ext_name = None + + def get_name(self): """ Retrieves the name of the component @@ -51,8 +55,10 @@ def _get_command_result(self, cmdline): try: proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT) stdout = proc.communicate()[0] - proc.wait() + rc = proc.wait() result = stdout.rstrip('\n') + if rc != 0: + raise RuntimeError("Failed to execute command {}, return code {}, message {}".format(cmdline, rc, stdout)) except OSError as e: raise RuntimeError("Failed to execute command {} due to {}".format(cmdline, repr(e))) @@ -60,12 +66,45 @@ def _get_command_result(self, cmdline): return result + def _check_file_validity(self, image_path): + # check whether the image file exists + if not os.path.isfile(image_path): + print("ERROR: File {} doesn't exist or is not a file".format(image_path)) + return False + + if self.image_ext_name is not None: + name_list = os.path.splitext(image_path) + if name_list[1] != self.image_ext_name: + print("ERROR: Extend name of file {} is wrong. Image for {} should have extend name {}".format(image_path, self.name, self.image_ext_name)) + return False + + return True + + + class ComponentBIOS(Component): + # To update BIOS requires the ONIE with version 5.2.0016 or upper + ONIE_VERSION_PARSE_PATTERN = '[0-9]{4}\.[0-9]{2}-([0-9]+)\.([0-9]+)\.([0-9]+)' + ONIE_VERSION_MAJOR_OFFSET = 1 + ONIE_VERSION_MINOR_OFFSET = 2 + ONIE_VERSION_RELEASE_OFFSET = 3 + ONIE_REQUIRED_MAJOR = "5" + ONIE_REQUIRED_MINOR = "2" + ONIE_REQUIRED_RELEASE = "0016" + BIOS_VERSION_PARSE_PATTERN = 'OEM[\s]*Strings\n[\s]*String[\s]*1:[\s]*([0-9a-zA-Z_\.]*)' + BIOS_PENDING_UPDATE_PATTERN = '([0-9A-Za-z_]*.rom)[\s]*\|[\s]*bios_update' + ONIE_FW_UPDATE_CMD_ADD = "/usr/bin/onie-fw-update.sh add {}" + ONIE_FW_UPDATE_CMD_REMOVE = "/usr/bin/onie-fw-update.sh remove {}" + ONIE_FW_UPDATE_CMD_UPDATE = "/usr/bin/onie-fw-update.sh update" + ONIE_FW_UPDATE_CMD_SHOW = "/usr/bin/onie-fw-update.sh show-pending" + + BIOS_QUERY_VERSION_COMMAND = 'dmidecode -t 11' def __init__(self): self.name = COMPONENT_BIOS + self.image_ext_name = ".rom" def get_description(self): @@ -99,20 +138,95 @@ def get_firmware_version(self): By using regular expression 'OEM[\s]*Strings\n[\s]*String[\s]*1:[\s]*([0-9a-zA-Z_\.]*)' we can extrace the version string which is marked with * in the above context """ - bios_ver_str = self._get_command_result(BIOS_QUERY_VERSION_COMMAND) try: + bios_ver_str = self._get_command_result(self.BIOS_QUERY_VERSION_COMMAND) m = re.search(self.BIOS_VERSION_PARSE_PATTERN, bios_ver_str) result = m.group(1) - except AttributeError as e: - raise RuntimeError("Failed to parse BIOS version by {} from {} due to {}".format( - self.BIOS_VERSION_PARSE_PATTERN, bios_ver_str, repr(e))) + except (AttributeError, RuntimeError) as e: + raise RuntimeError("Failed to parse BIOS version due to {}".format(repr(e))) return result + def _check_onie_version(self): + # check ONIE version. To update ONIE requires version 5.2.0016 or later. + try: + machine_info = get_machine_info() + onie_version_string = machine_info['onie_version'] + m = re.search(self.ONIE_VERSION_PARSE_PATTERN, onie_version_string) + onie_major = m.group(self.ONIE_VERSION_MAJOR_OFFSET) + onie_minor = m.group(self.ONIE_VERSION_MINOR_OFFSET) + onie_release = m.group(self.ONIE_VERSION_RELEASE_OFFSET) + except AttributeError as e: + print("ERROR: Failed to parse ONIE version by {} from {} due to {}".format( + self.ONIE_VERSION_PARSE_PATTERN, machine_conf, repr(e))) + return False + + if onie_major < self.ONIE_REQUIRED_MAJOR or onie_minor < self.ONIE_REQUIRED_MINOR or onie_release < self.ONIE_REQUIRED_RELEASE: + print("ERROR: ONIE {}.{}.{} or later is required".format(self.ONIE_REQUIRED_MAJOR, self.ONIE_REQUIRED_MINOR, self.ONIE_REQUIRED_RELEASE)) + return False + + return True + + + def install_firmware(self, image_path): + """ + Installs firmware to the component + + Args: + image_path: A string, path to firmware image + + Returns: + A boolean, True if install was successful, False if not + """ + # check ONIE version requirement + if not self._check_onie_version(): + return False + + # check whether the file exists + if not self._check_file_validity(image_path): + return False + + # do the real work + try: + # check whether there has already been some images pending + # if yes, remove them + result = self._get_command_result(self.ONIE_FW_UPDATE_CMD_SHOW) + pending_list = result.split("\n") + for pending in pending_list: + m = re.match(self.BIOS_PENDING_UPDATE_PATTERN, pending) + if m is not None: + pending_image = m.group(1) + self._get_command_result(self.ONIE_FW_UPDATE_CMD_REMOVE.format(pending_image)) + print("WARNING: Image {} which is already pending to upgrade has been removed".format(pending_image)) + + result = subprocess.check_call(self.ONIE_FW_UPDATE_CMD_ADD.format(image_path).split()) + if result: + return False + result = subprocess.check_call(self.ONIE_FW_UPDATE_CMD_UPDATE.split()) + if result: + return False + except Exception as e: + print("ERROR: Installing BIOS failed due to {}".format(repr(e))) + return False + + print("INFO: Reboot is required to finish BIOS installation.") + return True + + + class ComponentCPLD(Component): + CPLD_VERSION_FILE_PATTERN = '/var/run/hw-management/system/cpld[0-9]_version' + CPLD_VERSION_MAX_LENGTH = 4 + + CPLD_UPDATE_COMMAND = "cpldupdate --dev {} {}" + CPLD_INSTALL_SUCCESS_FLAG = "PASS!" + + MST_DEVICE_PATTERN = "/dev/mst/mt[0-9]*_pciconf0" + def __init__(self): self.name = COMPONENT_CPLD + self.image_ext_name = ".vme" def get_description(self): @@ -132,17 +246,93 @@ def get_firmware_version(self): Returns: A string containing the firmware version of the component """ - cpld_version_file_list = glob(CPLD_VERSION_FILE_PATTERN) + cpld_version_file_list = glob(self.CPLD_VERSION_FILE_PATTERN) cpld_version = '' - if cpld_version_file_list is not None and cpld_version_file_list: + if cpld_version_file_list: cpld_version_file_list.sort() for version_file in cpld_version_file_list: - version = self._read_generic_file(version_file, CPLD_VERSION_MAX_LENGTH) - if not cpld_version == '': + version = self._read_generic_file(version_file, self.CPLD_VERSION_MAX_LENGTH) + if cpld_version: cpld_version += '.' cpld_version += version.rstrip('\n') else: - raise RuntimeError("Failed to get CPLD version files by matching {}".format(CPLD_VERSION_FILE_PATTERN)) + raise RuntimeError("Failed to get CPLD version files by matching {}".format(self.CPLD_VERSION_FILE_PATTERN)) return cpld_version + + def _get_mst_device(self): + mst_dev_list = glob(self.MST_DEVICE_PATTERN) + if mst_dev_list is None or len(mst_dev_list) != 1: + return None + return mst_dev_list + + + def install_firmware(self, image_path): + """ + Installs firmware to the component + + Args: + image_path: A string, path to firmware image + + Returns: + A boolean, True if install was successful, False if not + + Details: + The command "cpldupdate" is provided to install CPLD. There are two ways to do it: + 1. To burn CPLD via gpio, which is faster but only supported on new systems, like Anaconda, ... + 2. To install CPLD via firmware, which is slower but supported on older systems. + This also requires the mst device designated. + "cpldupdate --dev " has the logic of testing whether to update via gpio is supported, + and if so then go this way, otherwise tries updating software via fw. So we take advantage of it to update the CPLD. + By doing so we don't have to mind whether to update via gpio supported, which belongs to hardware details. + + So the procedure should be: + 1. Test whether the file exists + 2. Fetch the mst device name + 3. Update CPLD via executing "cpldupdate --dev " + 4. Check the result + """ + # check whether the image file exists + if not self._check_file_validity(image_path): + return False + + mst_dev_list = self._get_mst_device() + if mst_dev_list is None: + print("ERROR: Failed to get mst device which is required for CPLD updating or multiple device files matched") + return False + + cmdline = self.CPLD_UPDATE_COMMAND.format(mst_dev_list[0], image_path) + outputline = "" + success_flag = False + try: + proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT) + while True: + out = proc.stdout.read(1) + + if out == '' and proc.poll() != None: + break + + if out != '': + sys.stdout.write(out) + sys.stdout.flush() + outputline += out + + if (out == '\n' or out == '\r') and len(outputline): + m = re.search(self.CPLD_INSTALL_SUCCESS_FLAG, outputline) + if m and m.group(0) == self.CPLD_INSTALL_SUCCESS_FLAG: + success_flag = True + + if proc.returncode: + print("ERROR: Upgrade CPLD failed, return code {}".format(proc.returncode)) + success_flag = False + + except OSError as e: + raise RuntimeError("Failed to execute command {} due to {}".format(cmdline, repr(e))) + + if success_flag: + print("INFO: Success. Refresh or power cycle is required to finish CPLD installation.") + else: + print("ERROR: Failed to install CPLD") + + return success_flag diff --git a/platform/mellanox/one-image.mk b/platform/mellanox/one-image.mk index 2946ae53f47b..d30e44690991 100644 --- a/platform/mellanox/one-image.mk +++ b/platform/mellanox/one-image.mk @@ -11,5 +11,5 @@ $(SONIC_ONE_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.g else $(SONIC_ONE_IMAGE)_DOCKERS = $(SONIC_INSTALL_DOCKER_IMAGES) endif -$(SONIC_ONE_IMAGE)_FILES += $(MLNX_SPC_FW_FILE) $(MLNX_SPC2_FW_FILE) $(MLNX_FFB_SCRIPT) $(ISSU_VERSION_FILE) +$(SONIC_ONE_IMAGE)_FILES += $(MLNX_SPC_FW_FILE) $(MLNX_SPC2_FW_FILE) $(MLNX_FFB_SCRIPT) $(ISSU_VERSION_FILE) $(ONIE_FW_UPDATE) SONIC_INSTALLERS += $(SONIC_ONE_IMAGE) diff --git a/platform/mellanox/onie-fw-update b/platform/mellanox/onie-fw-update new file mode 100755 index 000000000000..314f4ed70268 --- /dev/null +++ b/platform/mellanox/onie-fw-update @@ -0,0 +1,120 @@ +#!/bin/sh + +# Copyright (C) 2019 Mellanox Technologies Ltd. +# Copyright (C) 2019 Michael Shych +# +# SPDX-License-Identifier: GPL-2.0 + +this_script=${ONIE_FWPKG_PROGRAM_NAME:-$(basename $(realpath $0))} + +onie_mount=/mnt/onie-boot +os_boot=/host +onie_partition= + +export ONIE_FWPKG_PROGRAM_NAME=$(basename $(realpath $0)) + +usage() +{ +cat < before update." + clean_onie_access + exit 1 + fi + ;; + purge | show | show-results | show-log | show-pending | help) + ;; + *) + echo "Unknown command: $cmd" + exit 1 + ;; +esac + +enable_onie_access +$onie_mount/onie/tools/bin/onie-fwpkg "$@" +rc=$? +if [ $cmd = "help" ]; then + usage +fi +clean_onie_access + +exit $rc diff --git a/platform/mellanox/onie-fw-update.mk b/platform/mellanox/onie-fw-update.mk new file mode 100644 index 000000000000..160f1c98f7b1 --- /dev/null +++ b/platform/mellanox/onie-fw-update.mk @@ -0,0 +1,7 @@ +# bios update tool + +ONIE_FW_UPDATE= onie-fw-update +$(ONIE_FW_UPDATE)_PATH = platform/mellanox/ +SONIC_COPY_FILES += $(ONIE_FW_UPDATE) + +export ONIE_FW_UPDATE diff --git a/platform/mellanox/rules.mk b/platform/mellanox/rules.mk index dd10cefda571..efd0af2c8f4a 100644 --- a/platform/mellanox/rules.mk +++ b/platform/mellanox/rules.mk @@ -12,6 +12,7 @@ include $(PLATFORM_PATH)/libsaithrift-dev.mk include $(PLATFORM_PATH)/docker-ptf-mlnx.mk include $(PLATFORM_PATH)/mlnx-ffb.mk include $(PLATFORM_PATH)/issu-version.mk +include $(PLATFORM_PATH)/onie-fw-update.mk SONIC_ALL += $(SONIC_ONE_IMAGE) \ $(DOCKER_FPM) From ee9295c88cbfebdd7cd5f0d682c1abe6eb477408 Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Wed, 22 Jan 2020 01:50:02 +0200 Subject: [PATCH 068/178] [grub]: Allow ONiE oneshoot boot for FW update. (#3935) Added ONiE oneshoot boot feature Signed-off-by: Nazarii Hnydyn --- installer/x86_64/install.sh | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/installer/x86_64/install.sh b/installer/x86_64/install.sh index 2cd579e28b29..78e8e2f4623b 100755 --- a/installer/x86_64/install.sh +++ b/installer/x86_64/install.sh @@ -555,15 +555,21 @@ EOF # Add the logic to support grub-reboot and grub-set-default cat <> $grub_cfg if [ -s \$prefix/grubenv ]; then - load_env + load_env fi -if [ "\${saved_entry}" ] ; then - set default="\${saved_entry}" +if [ "\${saved_entry}" ]; then + set default="\${saved_entry}" fi -if [ "\${next_entry}" ] ; then - set default="\${next_entry}" - set next_entry= - save_env next_entry +if [ "\${next_entry}" ]; then + set default="\${next_entry}" + unset next_entry + save_env next_entry +fi +if [ "\${onie_entry}" ]; then + set next_entry="\${default}" + set default="\${onie_entry}" + unset onie_entry + save_env onie_entry next_entry fi EOF From 651f4a068eefd0759b630f8e3793c24237519273 Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Fri, 24 Jan 2020 21:26:17 +0200 Subject: [PATCH 069/178] [mellanox] Add fwutil platform components. (#3999) Signed-off-by: Nazarii Hnydyn --- .../x86_64-mlnx_msn2010-r0/platform_components.json | 10 ++++++++++ .../x86_64-mlnx_msn2100-r0/platform_components.json | 10 ++++++++++ .../x86_64-mlnx_msn2410-r0/platform_components.json | 10 ++++++++++ .../x86_64-mlnx_msn2700-r0/platform_components.json | 10 ++++++++++ .../x86_64-mlnx_msn2740-r0/platform_components.json | 10 ++++++++++ .../x86_64-mlnx_msn3700-r0/platform_components.json | 10 ++++++++++ .../x86_64-mlnx_msn3700c-r0/platform_components.json | 10 ++++++++++ .../x86_64-mlnx_msn3800-r0/platform_components.json | 10 ++++++++++ 8 files changed, 80 insertions(+) create mode 100644 device/mellanox/x86_64-mlnx_msn2010-r0/platform_components.json create mode 100644 device/mellanox/x86_64-mlnx_msn2100-r0/platform_components.json create mode 100644 device/mellanox/x86_64-mlnx_msn2410-r0/platform_components.json create mode 100644 device/mellanox/x86_64-mlnx_msn2700-r0/platform_components.json create mode 100644 device/mellanox/x86_64-mlnx_msn2740-r0/platform_components.json create mode 100644 device/mellanox/x86_64-mlnx_msn3700-r0/platform_components.json create mode 100644 device/mellanox/x86_64-mlnx_msn3700c-r0/platform_components.json create mode 100644 device/mellanox/x86_64-mlnx_msn3800-r0/platform_components.json diff --git a/device/mellanox/x86_64-mlnx_msn2010-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn2010-r0/platform_components.json new file mode 100644 index 000000000000..775c6e22cf5c --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2010-r0/platform_components.json @@ -0,0 +1,10 @@ +{ + "chassis": { + "x86_64-mlnx_msn2010-r0": { + "component": { + "BIOS": { }, + "CPLD": { } + } + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn2100-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn2100-r0/platform_components.json new file mode 100644 index 000000000000..6a6a74301cbc --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2100-r0/platform_components.json @@ -0,0 +1,10 @@ +{ + "chassis": { + "x86_64-mlnx_msn2100-r0": { + "component": { + "BIOS": { }, + "CPLD": { } + } + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn2410-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn2410-r0/platform_components.json new file mode 100644 index 000000000000..77da35ce5818 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2410-r0/platform_components.json @@ -0,0 +1,10 @@ +{ + "chassis": { + "x86_64-mlnx_msn2410-r0": { + "component": { + "BIOS": { }, + "CPLD": { } + } + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn2700-r0/platform_components.json new file mode 100644 index 000000000000..2a6069414786 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/platform_components.json @@ -0,0 +1,10 @@ +{ + "chassis": { + "x86_64-mlnx_msn2700-r0": { + "component": { + "BIOS": { }, + "CPLD": { } + } + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn2740-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn2740-r0/platform_components.json new file mode 100644 index 000000000000..7964d9cb8713 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn2740-r0/platform_components.json @@ -0,0 +1,10 @@ +{ + "chassis": { + "x86_64-mlnx_msn2740-r0": { + "component": { + "BIOS": { }, + "CPLD": { } + } + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn3700-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn3700-r0/platform_components.json new file mode 100644 index 000000000000..7c0b7598aff7 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3700-r0/platform_components.json @@ -0,0 +1,10 @@ +{ + "chassis": { + "x86_64-mlnx_msn3700-r0": { + "component": { + "BIOS": { }, + "CPLD": { } + } + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn3700c-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn3700c-r0/platform_components.json new file mode 100644 index 000000000000..c55b9feab7cb --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3700c-r0/platform_components.json @@ -0,0 +1,10 @@ +{ + "chassis": { + "x86_64-mlnx_msn3700c-r0": { + "component": { + "BIOS": { }, + "CPLD": { } + } + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn3800-r0/platform_components.json new file mode 100644 index 000000000000..fa3b172b763e --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/platform_components.json @@ -0,0 +1,10 @@ +{ + "chassis": { + "x86_64-mlnx_msn3800-r0": { + "component": { + "BIOS": { }, + "CPLD": { } + } + } + } +} From af4e84298ad5c3be309794a1e79dcad29683bffd Mon Sep 17 00:00:00 2001 From: Sumukha Tumkur Vani Date: Wed, 12 Feb 2020 16:38:45 -0800 Subject: [PATCH 070/178] Start RestAPI container when sonic boots (#4140) * Start RestAPI container when sonic boots --- files/build_templates/restapi.service.j2 | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 files/build_templates/restapi.service.j2 diff --git a/files/build_templates/restapi.service.j2 b/files/build_templates/restapi.service.j2 new file mode 100644 index 000000000000..df1a50eb56c7 --- /dev/null +++ b/files/build_templates/restapi.service.j2 @@ -0,0 +1,16 @@ +[Unit] +Description=RestAPI container +Requires=updategraph.service +After=updategraph.service +Before=ntp-config.service + +[Service] +User={{ sonicadmin_user }} +ExecStartPre=/usr/bin/{{docker_container_name}}.sh start +ExecStart=/usr/bin/{{docker_container_name}}.sh wait +ExecStop=/usr/bin/{{docker_container_name}}.sh stop +Restart=always +RestartSec=30 + +[Install] +WantedBy=multi-user.target \ No newline at end of file From bc30442a38ad92dbc3a7b280ac861e001d43718a Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Fri, 14 Feb 2020 01:04:58 +0800 Subject: [PATCH 071/178] [sfputil]fix an syntax error (#4141) --- device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py index 40734349a230..07dbbe1cc21b 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py @@ -190,7 +190,7 @@ def get_transceiver_change_event(self, timeout=0): from swsscommon import swsscommon self.state_db = swsscommon.DBConnector("STATE_DB", REDIS_TIMEOUT_USECS, - True)) + True) # Subscribe to state table for SFP change notifications self.db_sel = swsscommon.Select() From f6d69aed49947648958f939801e9324e153fe747 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Fri, 14 Feb 2020 14:55:03 -0800 Subject: [PATCH 072/178] [interfaces-config.sh] Do not bring 'lo' interface down and up (#4150) --- files/image_config/interfaces/interfaces-config.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/files/image_config/interfaces/interfaces-config.sh b/files/image_config/interfaces/interfaces-config.sh index a702917419ca..9ee7de392bb6 100755 --- a/files/image_config/interfaces/interfaces-config.sh +++ b/files/image_config/interfaces/interfaces-config.sh @@ -7,5 +7,3 @@ sonic-cfggen -d -t /usr/share/sonic/templates/interfaces.j2 > /etc/network/inter [ -f /var/run/dhclient.eth0.pid ] && kill `cat /var/run/dhclient.eth0.pid` && rm -f /var/run/dhclient.eth0.pid systemctl restart networking - -ifdown lo && ifup lo From 6740b2d3df4678e7436b9169469ad3a48412532b Mon Sep 17 00:00:00 2001 From: Prince Sunny Date: Fri, 14 Feb 2020 11:08:57 -0800 Subject: [PATCH 073/178] Fix service and container name to be same (#4151) --- files/build_templates/init_cfg.json.j2 | 2 +- rules/docker-restapi.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/files/build_templates/init_cfg.json.j2 b/files/build_templates/init_cfg.json.j2 index bc2eff3ede56..17617ee1a3cb 100644 --- a/files/build_templates/init_cfg.json.j2 +++ b/files/build_templates/init_cfg.json.j2 @@ -25,7 +25,7 @@ {% endfor %} }, "CONTAINER_FEATURE": { -{%- for container in ["bgp", "database", "dhcp_relay", "lldp", "pmon", "radv", "rest-api", "sflow", +{%- for container in ["bgp", "database", "dhcp_relay", "lldp", "pmon", "radv", "restapi", "sflow", "snmp", "swss", "syncd", "teamd", "telemetry"] %} "{{container}}": { "auto_restart": "disabled", diff --git a/rules/docker-restapi.mk b/rules/docker-restapi.mk index 7c02e0d4e44b..2141dea64d17 100644 --- a/rules/docker-restapi.mk +++ b/rules/docker-restapi.mk @@ -16,7 +16,7 @@ SONIC_STRETCH_DOCKERS += $(DOCKER_RESTAPI) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_RESTAPI) endif -$(DOCKER_RESTAPI)_CONTAINER_NAME = rest-api +$(DOCKER_RESTAPI)_CONTAINER_NAME = restapi $(DOCKER_RESTAPI)_RUN_OPT += --cap-add NET_ADMIN --privileged -t $(DOCKER_RESTAPI)_RUN_OPT += -v /var/run/redis/redis.sock:/var/run/redis/redis.sock $(DOCKER_RESTAPI)_RUN_OPT += -p=8090:8090/tcp From 91e64f063e48d5dee631100f44bae013a2484237 Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Sun, 16 Feb 2020 19:47:16 +0800 Subject: [PATCH 074/178] Update SDK to 4.3.3052 (#4153) update FW to xx_2000_3298 update SAI to 1.16.0 update Spectrum-1 and Spectrum-2 buffer pool size according to the new SDK default config change. modified: ../../device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t0.j2 modified: ../../device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t1.j2 modified: ../../device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t0.j2 modified: ../../device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t1.j2 modified: fw.mk modified: mlnx-sai.mk modified: mlnx-sai/SAI-Implementation modified: sdk-src/sx-kernel/Switch-SDK-drivers modified: sdk.mk signed-off by kebol@mellanox.com --- .../ACS-MSN2700/buffers_defaults_t0.j2 | 8 ++++---- .../ACS-MSN2700/buffers_defaults_t1.j2 | 8 ++++---- .../ACS-MSN3700/buffers_defaults_t0.j2 | 8 ++++---- .../ACS-MSN3700/buffers_defaults_t1.j2 | 8 ++++---- platform/mellanox/fw.mk | 4 ++-- platform/mellanox/mlnx-sai.mk | 2 +- platform/mellanox/mlnx-sai/SAI-Implementation | 2 +- platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers | 2 +- platform/mellanox/sdk.mk | 2 +- 9 files changed, 22 insertions(+), 22 deletions(-) diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t0.j2 index 8c3cac4b80b8..5529ee3d8598 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t0.j2 +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t0.j2 @@ -1,8 +1,8 @@ {% set default_cable = '5m' %} -{% set ingress_lossless_pool_size = '4194304' %} -{% set ingress_lossy_pool_size = '7340032' %} -{% set egress_lossless_pool_size = '16777152' %} -{% set egress_lossy_pool_size = '7340032' %} +{% set ingress_lossless_pool_size = '5029836' %} +{% set ingress_lossy_pool_size = '5029836' %} +{% set egress_lossless_pool_size = '14024599' %} +{% set egress_lossy_pool_size = '5029836' %} {%- macro generate_port_lists(PORT_ALL) %} {# Generate list of ports #} diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t1.j2 index 45433b1b2641..f418e2ffa1db 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t1.j2 +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_defaults_t1.j2 @@ -1,8 +1,8 @@ {% set default_cable = '5m' %} -{% set ingress_lossless_pool_size = '2097152' %} -{% set ingress_lossy_pool_size = '5242880' %} -{% set egress_lossless_pool_size = '16777152' %} -{% set egress_lossy_pool_size = '5242880' %} +{% set ingress_lossless_pool_size = '2097100' %} +{% set ingress_lossy_pool_size = '2097100' %} +{% set egress_lossless_pool_size = '14024599' %} +{% set egress_lossy_pool_size = '2097100' %} {%- macro generate_port_lists(PORT_ALL) %} {# Generate list of ports #} diff --git a/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t0.j2 index d40bc03fbb59..e26ad28b9f0e 100644 --- a/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t0.j2 +++ b/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t0.j2 @@ -1,8 +1,8 @@ {% set default_cable = '5m' %} -{% set ingress_lossless_pool_size = '8224768' %} -{% set ingress_lossy_pool_size = '8224768' %} -{% set egress_lossless_pool_size = '35966016' %} -{% set egress_lossy_pool_size = '8224768' %} +{% set ingress_lossless_pool_size = '14983147' %} +{% set ingress_lossy_pool_size = '14983147' %} +{% set egress_lossless_pool_size = '34340822' %} +{% set egress_lossy_pool_size = '14983147' %} {%- macro generate_port_lists(PORT_ALL) %} {# Generate list of ports #} diff --git a/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t1.j2 index fe8c27b9d364..b5e4ff8d1747 100644 --- a/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t1.j2 +++ b/device/mellanox/x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t1.j2 @@ -1,8 +1,8 @@ {% set default_cable = '5m' %} -{% set ingress_lossless_pool_size = '12042240' %} -{% set ingress_lossy_pool_size = '12042240' %} -{% set egress_lossless_pool_size = '35966016' %} -{% set egress_lossy_pool_size = '12042240' %} +{% set ingress_lossless_pool_size = '9158635' %} +{% set ingress_lossy_pool_size = '9158635' %} +{% set egress_lossless_pool_size = '34340822' %} +{% set egress_lossy_pool_size = '9158635' %} {%- macro generate_port_lists(PORT_ALL) %} {# Generate list of ports #} diff --git a/platform/mellanox/fw.mk b/platform/mellanox/fw.mk index c088fe274b06..97ff9d93d486 100644 --- a/platform/mellanox/fw.mk +++ b/platform/mellanox/fw.mk @@ -11,12 +11,12 @@ else FW_FROM_URL = n endif -MLNX_SPC_FW_VERSION = 13.2000.2720 +MLNX_SPC_FW_VERSION = 13.2000.3298 MLNX_SPC_FW_FILE = fw-SPC-rel-$(subst .,_,$(MLNX_SPC_FW_VERSION))-EVB.mfa $(MLNX_SPC_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC_FW_FILE) -MLNX_SPC2_FW_VERSION = 29.2000.2720 +MLNX_SPC2_FW_VERSION = 29.2000.3298 MLNX_SPC2_FW_FILE = fw-SPC2-rel-$(subst .,_,$(MLNX_SPC2_FW_VERSION))-EVB.mfa $(MLNX_SPC2_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC2_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC2_FW_FILE) diff --git a/platform/mellanox/mlnx-sai.mk b/platform/mellanox/mlnx-sai.mk index baced2780637..419598a6a776 100644 --- a/platform/mellanox/mlnx-sai.mk +++ b/platform/mellanox/mlnx-sai.mk @@ -1,6 +1,6 @@ # Mellanox SAI -MLNX_SAI_VERSION = SAIRel1.15.5-master +MLNX_SAI_VERSION = SAIRel1.16.0-master export MLNX_SAI_VERSION diff --git a/platform/mellanox/mlnx-sai/SAI-Implementation b/platform/mellanox/mlnx-sai/SAI-Implementation index 4b40b5191b07..df052a406255 160000 --- a/platform/mellanox/mlnx-sai/SAI-Implementation +++ b/platform/mellanox/mlnx-sai/SAI-Implementation @@ -1 +1 @@ -Subproject commit 4b40b5191b07118326a29be2d491f4362fc02eee +Subproject commit df052a4062556e0f3a1e695fa73efccf81d32a9d diff --git a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers index 026b12e2bd02..fa26ae9d24b4 160000 --- a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers +++ b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers @@ -1 +1 @@ -Subproject commit 026b12e2bd02b79fdf50eb5f45a161c95ec94837 +Subproject commit fa26ae9d24b4d1ff162f56d83d944c2fc2bcea0b diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index f105f6b22f7b..649422429771 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -1,5 +1,5 @@ MLNX_SDK_BASE_PATH = $(PLATFORM_PATH)/sdk-src/sx-kernel/Switch-SDK-drivers/bin/ -MLNX_SDK_VERSION = 4.3.2908 +MLNX_SDK_VERSION = 4.3.3052 MLNX_SDK_ISSU_VERSION = 101 MLNX_SDK_DEB_VERSION = $(subst _,.,$(MLNX_SDK_VERSION)) From bb73687514beeb87ff532fba7782fadc3b872d4c Mon Sep 17 00:00:00 2001 From: michealylj1 <46735287+michealylj1@users.noreply.github.com> Date: Tue, 18 Feb 2020 06:09:15 +0800 Subject: [PATCH 075/178] [Device]: Add new CIG device CS6436-54P and CS5435-54P, also update code for CS6436-56P (#4157) * Add new CIG device CS6436-54P and CS5435-54P, also update code for CS6436-56P * security kernel update to 4.9.189 for CIG devices * security kernel update to 4.9.189 for CIG devices * Update rules Update rule file --- .../Cig-CS5435-54P/buffers.json.j2 | 111 + .../Cig-CS5435-54P/led.bin | Bin 0 -> 652 bytes .../Cig-CS5435-54P/pg_profile_lookup.ini | 17 + .../Cig-CS5435-54P/port_config.ini | 55 + .../Cig-CS5435-54P/port_config.nps} | 240 +- .../Cig-CS5435-54P/qos.json.j2 | 1 + .../Cig-CS5435-54P/sai.profile | 3 + .../cig/x86_64-cig_cs5435_54p-r0/default_sku | 1 + .../x86_64-cig_cs5435_54p-r0/installer.conf | 4 + .../plugins/eeprom.py | 21 + .../plugins/psuutil.py | 93 + .../plugins/sfputil.py | 250 ++ .../cig/x86_64-cig_cs5435_54p-r0/sensors.conf | 13 + .../Cig-CS6436-54P/buffers.json.j2 | 111 + .../Cig-CS6436-54P/led.bin | Bin 0 -> 652 bytes .../Cig-CS6436-54P/pg_profile_lookup.ini | 17 + .../Cig-CS6436-54P/port_config.ini | 55 + .../Cig-CS6436-54P/port_config.nps} | 88 +- .../Cig-CS6436-54P/qos.json.j2 | 1 + .../Cig-CS6436-54P/sai.profile | 3 + .../cig/x86_64-cig_cs6436_54p-r0/default_sku | 1 + .../x86_64-cig_cs6436_54p-r0/installer.conf | 4 + .../plugins/eeprom.py | 21 + .../plugins/psuutil.py | 93 + .../plugins/sfputil.py | 250 ++ .../cig/x86_64-cig_cs6436_54p-r0/sensors.conf | 13 + .../Cig-CS6436-56P/buffers.json.j2 | 0 .../Cig-CS6436-56P/led.bin | Bin 0 -> 652 bytes .../Cig-CS6436-56P/pg_profile_lookup.ini | 0 .../Cig-CS6436-56P/port_config.ini | 112 +- .../Cig-CS6436-56P/port_config.nps | 4 +- .../proc_init.nps} | 2 +- .../Cig-CS6436-56P/qos.json.j2 | 0 .../Cig-CS6436-56P/sai.profile | 3 +- .../cig/x86_64-cig_cs6436_56p-r0/default_sku | 0 .../x86_64-cig_cs6436_56p-r0/installer.conf | 4 +- .../plugins/psuutil.py | 3 +- .../plugins/sfputil.py | 254 +- .../cig/x86_64-cig_cs6436_56p-r0/sensors.conf | 0 platform/nephos/one-image.mk | 5 +- platform/nephos/platform-modules-cig.mk | 24 +- .../cs5435-54p/classes/__init__.py | 0 .../cs5435-54p/classes/fanutil.py | 0 .../cs5435-54p/classes/thermalutil.py | 0 .../cs5435-54p/modules/Makefile | 6 + .../cs5435-54p/modules/i2c-algo-lpc.h | 222 ++ .../modules/x86-64-cig-cs5435-54p-cpld.c | 2209 +++++++++++++++++ .../modules/x86-64-cig-cs5435-54p-fan.c | 521 ++++ .../modules/x86-64-cig-cs5435-54p-led.c | 594 +++++ .../modules/x86-64-cig-cs5435-54p-psu.c | 946 +++++++ .../modules/x86-64-cig-cs5435-54p-sfp.c | 1713 +++++++++++++ .../modules/x86-64-cig-cs5435-54p-sysfs.c | 335 +++ .../service/cs5435-platform-init.service | 13 + .../service/cs5435-platform-misc.service | 15 + .../cs5435-54p/setup.py | 15 + .../cs5435-54p/utils/cig_cs5435_misc.py | 574 +++++ .../cs5435-54p/utils/cig_cs5435_util.py | 563 +++++ .../cs6436-54p/classes/__init__.py | 0 .../cs6436-54p/classes/fanutil.py | 0 .../cs6436-54p/classes/thermalutil.py | 0 .../cs6436-54p/modules/Makefile | 6 + .../cs6436-54p/modules/i2c-algo-lpc.h | 222 ++ .../modules/x86-64-cig-cs6436-54p-cpld.c | 2202 ++++++++++++++++ .../modules/x86-64-cig-cs6436-54p-fan.c | 521 ++++ .../modules/x86-64-cig-cs6436-54p-led.c | 594 +++++ .../modules/x86-64-cig-cs6436-54p-psu.c | 943 +++++++ .../modules/x86-64-cig-cs6436-54p-sfp.c | 1713 +++++++++++++ .../modules/x86-64-cig-cs6436-54p-sysfs.c | 335 +++ .../service/cs6436-platform-init.service | 13 + .../service/cs6436-platform-misc.service | 15 + .../cs6436-54p/setup.py | 15 + .../cs6436-54p/utils/cig_cs6436_misc.py | 574 +++++ .../cs6436-54p/utils/cig_cs6436_util.py | 565 +++++ .../cs6436-56p/modules/Makefile | 3 +- .../cs6436-56p/modules/i2c-algo-lpc.h | 129 +- .../cs6436-56p/modules/i2c-algo-lpc2iic.h | 0 .../modules/x86-64-cig-cs6436-56p-cpld.c | 1200 ++++++--- .../modules/x86-64-cig-cs6436-56p-fan.c | 70 + .../modules/x86-64-cig-cs6436-56p-led.c | 0 .../modules/x86-64-cig-cs6436-56p-psu.c | 1339 ++++++---- .../modules/x86-64-cig-cs6436-56p-sfp.c | 339 ++- .../modules/x86-64-cig-cs6436-56p-sysfs.c | 335 +++ .../service/cs6436-platform-init.service | 0 .../service/cs6436-platform-misc.service | 2 +- .../cs6436-56p/utils/cig_cs6436_misc.py | 596 ++++- .../cs6436-56p/utils/cig_cs6436_util.py | 336 +-- .../debian/changelog | 0 .../sonic-platform-modules-cig/debian/compat | 0 .../sonic-platform-modules-cig/debian/control | 12 +- .../sonic-platform-modules-cig/debian/rules | 7 +- 90 files changed, 20251 insertions(+), 1438 deletions(-) create mode 100644 device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/buffers.json.j2 create mode 100644 device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/led.bin create mode 100644 device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/pg_profile_lookup.ini create mode 100644 device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/port_config.ini rename device/cig/{x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.nps.DAC.R0B => x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/port_config.nps} (82%) mode change 100755 => 100644 create mode 100644 device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/qos.json.j2 create mode 100644 device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/sai.profile create mode 100644 device/cig/x86_64-cig_cs5435_54p-r0/default_sku create mode 100644 device/cig/x86_64-cig_cs5435_54p-r0/installer.conf create mode 100755 device/cig/x86_64-cig_cs5435_54p-r0/plugins/eeprom.py create mode 100755 device/cig/x86_64-cig_cs5435_54p-r0/plugins/psuutil.py create mode 100755 device/cig/x86_64-cig_cs5435_54p-r0/plugins/sfputil.py create mode 100644 device/cig/x86_64-cig_cs5435_54p-r0/sensors.conf create mode 100644 device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/buffers.json.j2 create mode 100644 device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/led.bin create mode 100644 device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/pg_profile_lookup.ini create mode 100644 device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/port_config.ini rename device/cig/{x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.nps.AOC.R0B => x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/port_config.nps} (92%) mode change 100755 => 100644 create mode 100644 device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/qos.json.j2 create mode 100644 device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/sai.profile create mode 100644 device/cig/x86_64-cig_cs6436_54p-r0/default_sku create mode 100644 device/cig/x86_64-cig_cs6436_54p-r0/installer.conf create mode 100755 device/cig/x86_64-cig_cs6436_54p-r0/plugins/eeprom.py create mode 100755 device/cig/x86_64-cig_cs6436_54p-r0/plugins/psuutil.py create mode 100755 device/cig/x86_64-cig_cs6436_54p-r0/plugins/sfputil.py create mode 100644 device/cig/x86_64-cig_cs6436_54p-r0/sensors.conf mode change 100755 => 100644 device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/buffers.json.j2 create mode 100644 device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/led.bin mode change 100755 => 100644 device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/pg_profile_lookup.ini mode change 100755 => 100644 device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.ini mode change 100755 => 100644 device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.nps rename device/cig/x86_64-cig_cs6436_56p-r0/{led_proc_init.nps => Cig-CS6436-56P/proc_init.nps} (90%) mode change 100755 => 100644 mode change 100755 => 100644 device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/qos.json.j2 mode change 100755 => 100644 device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/sai.profile mode change 100755 => 100644 device/cig/x86_64-cig_cs6436_56p-r0/default_sku mode change 100755 => 100644 device/cig/x86_64-cig_cs6436_56p-r0/installer.conf mode change 100755 => 100644 device/cig/x86_64-cig_cs6436_56p-r0/sensors.conf create mode 100755 platform/nephos/sonic-platform-modules-cig/cs5435-54p/classes/__init__.py create mode 100755 platform/nephos/sonic-platform-modules-cig/cs5435-54p/classes/fanutil.py create mode 100755 platform/nephos/sonic-platform-modules-cig/cs5435-54p/classes/thermalutil.py create mode 100644 platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/Makefile create mode 100644 platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/i2c-algo-lpc.h create mode 100644 platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-cpld.c create mode 100644 platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-fan.c create mode 100644 platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-led.c create mode 100644 platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-psu.c create mode 100644 platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-sfp.c create mode 100644 platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-sysfs.c create mode 100644 platform/nephos/sonic-platform-modules-cig/cs5435-54p/service/cs5435-platform-init.service create mode 100644 platform/nephos/sonic-platform-modules-cig/cs5435-54p/service/cs5435-platform-misc.service create mode 100755 platform/nephos/sonic-platform-modules-cig/cs5435-54p/setup.py create mode 100755 platform/nephos/sonic-platform-modules-cig/cs5435-54p/utils/cig_cs5435_misc.py create mode 100755 platform/nephos/sonic-platform-modules-cig/cs5435-54p/utils/cig_cs5435_util.py create mode 100755 platform/nephos/sonic-platform-modules-cig/cs6436-54p/classes/__init__.py create mode 100755 platform/nephos/sonic-platform-modules-cig/cs6436-54p/classes/fanutil.py create mode 100755 platform/nephos/sonic-platform-modules-cig/cs6436-54p/classes/thermalutil.py create mode 100644 platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/Makefile create mode 100644 platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/i2c-algo-lpc.h create mode 100644 platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-cpld.c create mode 100644 platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-fan.c create mode 100644 platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-led.c create mode 100644 platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-psu.c create mode 100644 platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-sfp.c create mode 100644 platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-sysfs.c create mode 100644 platform/nephos/sonic-platform-modules-cig/cs6436-54p/service/cs6436-platform-init.service create mode 100644 platform/nephos/sonic-platform-modules-cig/cs6436-54p/service/cs6436-platform-misc.service create mode 100755 platform/nephos/sonic-platform-modules-cig/cs6436-54p/setup.py create mode 100755 platform/nephos/sonic-platform-modules-cig/cs6436-54p/utils/cig_cs6436_misc.py create mode 100755 platform/nephos/sonic-platform-modules-cig/cs6436-54p/utils/cig_cs6436_util.py mode change 100755 => 100644 platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/Makefile mode change 100755 => 100644 platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/i2c-algo-lpc.h mode change 100755 => 100644 platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/i2c-algo-lpc2iic.h mode change 100755 => 100644 platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-cpld.c mode change 100755 => 100644 platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-fan.c mode change 100755 => 100644 platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-led.c mode change 100755 => 100644 platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-psu.c mode change 100755 => 100644 platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-sfp.c create mode 100644 platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-sysfs.c mode change 100755 => 100644 platform/nephos/sonic-platform-modules-cig/cs6436-56p/service/cs6436-platform-init.service mode change 100755 => 100644 platform/nephos/sonic-platform-modules-cig/cs6436-56p/service/cs6436-platform-misc.service mode change 100755 => 100644 platform/nephos/sonic-platform-modules-cig/debian/changelog mode change 100755 => 100644 platform/nephos/sonic-platform-modules-cig/debian/compat mode change 100755 => 100644 platform/nephos/sonic-platform-modules-cig/debian/control diff --git a/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/buffers.json.j2 b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/buffers.json.j2 new file mode 100644 index 000000000000..2c391214fa65 --- /dev/null +++ b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/buffers.json.j2 @@ -0,0 +1,111 @@ +{# Default values which will be used if no actual configura available #} +{% set default_cable = '40m' %} +{% set default_speed = '10G' %} +{% set default_ports_num = 54 -%} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{% set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } +%} + +{%- macro cable_length(port_name) -%} + {%- set cable_len = [] -%} + {%- for local_port in DEVICE_NEIGHBOR -%} + {%- if local_port == port_name -%} + {%- if DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor_role = neighbor.type -%} + {%- set roles1 = switch_role + '_' + neighbor_role %} + {%- set roles2 = neighbor_role + '_' + switch_role -%} + {%- set roles1 = roles1 | lower -%} + {%- set roles2 = roles2 | lower -%} + {%- if roles1 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles1]) -%}{%- endif -%} + {%- elif roles2 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles2]) -%}{%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endfor -%} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif -%} +{% endmacro %} + +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- endif -%} + +{# Generate list of ports if not defined #} +{% if PORT is not defined %} + {% set PORT = [] %} + {% for port_idx in range(0,default_ports_num) %} + {% if PORT.append("Ethernet%d" % (port_idx)) %}{% endif %} + {% endfor %} +{% endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + +{ + "CABLE_LENGTH": { + "AZURE": { + {% for port in PORT %} + {% set cable = cable_length(port) -%} + "{{ port }}": "{{ cable }}"{%- if not loop.last -%},{% endif %} + + {% endfor %} + } + }, + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "20971328", + "type": "ingress", + "mode": "static" + }, + "ingress_lossy_pool": { + "size": "20971328", + "type": "ingress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "20971328", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "xon":"78400", + "xoff":"132160", + "size":"3584", + "static_th":"82880" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"3584", + "dynamic_th":"-1" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"3584", + "dynamic_th":"-4" + } + }, + "BUFFER_PG": { + }, + "BUFFER_QUEUE": { + } +} + \ No newline at end of file diff --git a/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/led.bin b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/led.bin new file mode 100644 index 0000000000000000000000000000000000000000..201662a1c605693991df041260615085a9b5eb7b GIT binary patch literal 652 zcmWN`$uk0Q7{}qC8Dp3cZL(b}N?9vwi@MsWq^r14mvBk`bbSZAFz)>vhg7rbDLEjHQYB`?`vgMa+vlvDolmlIC- z!ykV0n_v9mm}8DO;*djr@{=F@;5*;>#y1W);45F*XP+;8VUImN^O;?C*V!Z literal 0 HcmV?d00001 diff --git a/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/pg_profile_lookup.ini b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/pg_profile_lookup.ini new file mode 100644 index 000000000000..d98b0eca6d19 --- /dev/null +++ b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold + 10000 5m 3584 32256 59136 36736 + 25000 5m 3584 41216 68096 45696 + 40000 5m 3584 47488 74368 51968 + 50000 5m 3584 52864 79744 57344 + 100000 5m 3584 78400 132160 82880 + 10000 40m 3584 32256 59136 36736 + 25000 40m 3584 41216 68096 45696 + 40000 40m 3584 47488 74368 51968 + 50000 40m 3584 52864 79744 57344 + 100000 40m 3584 78400 132160 82880 + 10000 300m 3584 32256 65856 36736 + 25000 300m 3584 41216 84672 45696 + 40000 300m 3584 47488 101024 51968 + 50000 300m 3584 52864 113120 57344 + 100000 300m 3584 78400 198688 82880 \ No newline at end of file diff --git a/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/port_config.ini b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/port_config.ini new file mode 100644 index 000000000000..ab29b7bed9ff --- /dev/null +++ b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/port_config.ini @@ -0,0 +1,55 @@ +# name lanes alias index speed +Ethernet0 8 Ethernet1/1 1 10000 +Ethernet1 9 Ethernet2/1 2 10000 +Ethernet2 10 Ethernet3/1 3 10000 +Ethernet3 11 Ethernet4/1 4 10000 +Ethernet4 12 Ethernet5/1 5 10000 +Ethernet5 13 Ethernet6/1 6 10000 +Ethernet6 14 Ethernet7/1 7 10000 +Ethernet7 15 Ethernet8/1 8 10000 +Ethernet8 16 Ethernet9/1 9 10000 +Ethernet9 17 Ethernet10/1 10 10000 +Ethernet10 18 Ethernet11/1 11 10000 +Ethernet11 19 Ethernet12/1 12 10000 +Ethernet12 20 Ethernet13/1 13 10000 +Ethernet13 21 Ethernet14/1 14 10000 +Ethernet14 22 Ethernet15/1 15 10000 +Ethernet15 23 Ethernet16/1 16 10000 +Ethernet16 32 Ethernet17/1 17 10000 +Ethernet17 33 Ethernet18/1 18 10000 +Ethernet18 34 Ethernet19/1 19 10000 +Ethernet19 35 Ethernet20/1 20 10000 +Ethernet20 40 Ethernet21/1 21 10000 +Ethernet21 41 Ethernet22/1 22 10000 +Ethernet22 42 Ethernet23/1 23 10000 +Ethernet23 43 Ethernet24/1 24 10000 +Ethernet24 48 Ethernet25/1 25 10000 +Ethernet25 49 Ethernet26/1 26 10000 +Ethernet26 50 Ethernet27/1 27 10000 +Ethernet27 51 Ethernet28/1 28 10000 +Ethernet28 56 Ethernet29/1 29 10000 +Ethernet29 57 Ethernet30/1 30 10000 +Ethernet30 58 Ethernet31/1 31 10000 +Ethernet31 59 Ethernet32/1 32 10000 +Ethernet32 64 Ethernet33/1 33 10000 +Ethernet33 65 Ethernet34/1 34 10000 +Ethernet34 66 Ethernet35/1 35 10000 +Ethernet35 67 Ethernet36/1 36 10000 +Ethernet36 68 Ethernet37/1 37 10000 +Ethernet37 69 Ethernet38/1 38 10000 +Ethernet38 70 Ethernet39/1 39 10000 +Ethernet39 71 Ethernet40/1 40 10000 +Ethernet40 72 Ethernet41/1 41 10000 +Ethernet41 73 Ethernet42/1 42 10000 +Ethernet42 74 Ethernet43/1 43 10000 +Ethernet43 75 Ethernet44/1 44 10000 +Ethernet44 76 Ethernet45/1 45 10000 +Ethernet45 77 Ethernet46/1 46 10000 +Ethernet46 78 Ethernet47/1 47 10000 +Ethernet47 79 Ethernet48/1 48 10000 +Ethernet48 84,85,86,87 Ethernet49/1 49 100000 +Ethernet49 80,81,82,83 Ethernet50/1 50 100000 +Ethernet50 108,109,110,111 Ethernet51/1 51 100000 +Ethernet51 104,105,106,107 Ethernet52/1 52 100000 +Ethernet52 116,117,118,119 Ethernet53/1 53 100000 +Ethernet53 112,113,114,115 Ethernet54/1 54 100000 diff --git a/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.nps.DAC.R0B b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/port_config.nps old mode 100755 new mode 100644 similarity index 82% rename from device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.nps.DAC.R0B rename to device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/port_config.nps index 857e5f1ede5f..9c6a5af8e5f0 --- a/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.nps.DAC.R0B +++ b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/port_config.nps @@ -1,60 +1,58 @@ init start stage unit=0 low-level -init set port-map unit=0 port=0 eth-macro=2 lane=0 max-speed=25g active=true -init set port-map unit=0 port=1 eth-macro=2 lane=1 max-speed=25g active=true -init set port-map unit=0 port=2 eth-macro=2 lane=2 max-speed=25g active=true -init set port-map unit=0 port=3 eth-macro=2 lane=3 max-speed=25g active=true -init set port-map unit=0 port=4 eth-macro=3 lane=0 max-speed=25g active=true -init set port-map unit=0 port=5 eth-macro=3 lane=1 max-speed=25g active=true -init set port-map unit=0 port=6 eth-macro=3 lane=2 max-speed=25g active=true -init set port-map unit=0 port=7 eth-macro=3 lane=3 max-speed=25g active=true -init set port-map unit=0 port=8 eth-macro=4 lane=0 max-speed=25g active=true -init set port-map unit=0 port=9 eth-macro=4 lane=1 max-speed=25g active=true -init set port-map unit=0 port=10 eth-macro=4 lane=2 max-speed=25g active=true -init set port-map unit=0 port=11 eth-macro=4 lane=3 max-speed=25g active=true -init set port-map unit=0 port=12 eth-macro=5 lane=0 max-speed=25g active=true -init set port-map unit=0 port=13 eth-macro=5 lane=1 max-speed=25g active=true -init set port-map unit=0 port=14 eth-macro=5 lane=2 max-speed=25g active=true -init set port-map unit=0 port=15 eth-macro=5 lane=3 max-speed=25g active=true -init set port-map unit=0 port=16 eth-macro=8 lane=0 max-speed=25g active=true -init set port-map unit=0 port=17 eth-macro=8 lane=1 max-speed=25g active=true -init set port-map unit=0 port=18 eth-macro=8 lane=2 max-speed=25g active=true -init set port-map unit=0 port=19 eth-macro=8 lane=3 max-speed=25g active=true -init set port-map unit=0 port=20 eth-macro=10 lane=0 max-speed=25g active=true -init set port-map unit=0 port=21 eth-macro=10 lane=1 max-speed=25g active=true -init set port-map unit=0 port=22 eth-macro=10 lane=2 max-speed=25g active=true -init set port-map unit=0 port=23 eth-macro=10 lane=3 max-speed=25g active=true -init set port-map unit=0 port=24 eth-macro=12 lane=0 max-speed=25g active=true -init set port-map unit=0 port=25 eth-macro=12 lane=1 max-speed=25g active=true -init set port-map unit=0 port=26 eth-macro=12 lane=2 max-speed=25g active=true -init set port-map unit=0 port=27 eth-macro=12 lane=3 max-speed=25g active=true -init set port-map unit=0 port=28 eth-macro=14 lane=0 max-speed=25g active=true -init set port-map unit=0 port=29 eth-macro=14 lane=1 max-speed=25g active=true -init set port-map unit=0 port=30 eth-macro=14 lane=2 max-speed=25g active=true -init set port-map unit=0 port=31 eth-macro=14 lane=3 max-speed=25g active=true -init set port-map unit=0 port=32 eth-macro=16 lane=0 max-speed=25g active=true -init set port-map unit=0 port=33 eth-macro=16 lane=1 max-speed=25g active=true -init set port-map unit=0 port=34 eth-macro=16 lane=2 max-speed=25g active=true -init set port-map unit=0 port=35 eth-macro=16 lane=3 max-speed=25g active=true -init set port-map unit=0 port=36 eth-macro=17 lane=0 max-speed=25g active=true -init set port-map unit=0 port=37 eth-macro=17 lane=1 max-speed=25g active=true -init set port-map unit=0 port=38 eth-macro=17 lane=2 max-speed=25g active=true -init set port-map unit=0 port=39 eth-macro=17 lane=3 max-speed=25g active=true -init set port-map unit=0 port=40 eth-macro=18 lane=0 max-speed=25g active=true -init set port-map unit=0 port=41 eth-macro=18 lane=1 max-speed=25g active=true -init set port-map unit=0 port=42 eth-macro=18 lane=2 max-speed=25g active=true -init set port-map unit=0 port=43 eth-macro=18 lane=3 max-speed=25g active=true -init set port-map unit=0 port=44 eth-macro=19 lane=0 max-speed=25g active=true -init set port-map unit=0 port=45 eth-macro=19 lane=1 max-speed=25g active=true -init set port-map unit=0 port=46 eth-macro=19 lane=2 max-speed=25g active=true -init set port-map unit=0 port=47 eth-macro=19 lane=3 max-speed=25g active=true +init set port-map unit=0 port=0 eth-macro=2 lane=0 max-speed=10g active=true +init set port-map unit=0 port=1 eth-macro=2 lane=1 max-speed=10g active=true +init set port-map unit=0 port=2 eth-macro=2 lane=2 max-speed=10g active=true +init set port-map unit=0 port=3 eth-macro=2 lane=3 max-speed=10g active=true +init set port-map unit=0 port=4 eth-macro=3 lane=0 max-speed=10g active=true +init set port-map unit=0 port=5 eth-macro=3 lane=1 max-speed=10g active=true +init set port-map unit=0 port=6 eth-macro=3 lane=2 max-speed=10g active=true +init set port-map unit=0 port=7 eth-macro=3 lane=3 max-speed=10g active=true +init set port-map unit=0 port=8 eth-macro=4 lane=0 max-speed=10g active=true +init set port-map unit=0 port=9 eth-macro=4 lane=1 max-speed=10g active=true +init set port-map unit=0 port=10 eth-macro=4 lane=2 max-speed=10g active=true +init set port-map unit=0 port=11 eth-macro=4 lane=3 max-speed=10g active=true +init set port-map unit=0 port=12 eth-macro=5 lane=0 max-speed=10g active=true +init set port-map unit=0 port=13 eth-macro=5 lane=1 max-speed=10g active=true +init set port-map unit=0 port=14 eth-macro=5 lane=2 max-speed=10g active=true +init set port-map unit=0 port=15 eth-macro=5 lane=3 max-speed=10g active=true +init set port-map unit=0 port=16 eth-macro=8 lane=0 max-speed=10g active=true +init set port-map unit=0 port=17 eth-macro=8 lane=1 max-speed=10g active=true +init set port-map unit=0 port=18 eth-macro=8 lane=2 max-speed=10g active=true +init set port-map unit=0 port=19 eth-macro=8 lane=3 max-speed=10g active=true +init set port-map unit=0 port=20 eth-macro=10 lane=0 max-speed=10g active=true +init set port-map unit=0 port=21 eth-macro=10 lane=1 max-speed=10g active=true +init set port-map unit=0 port=22 eth-macro=10 lane=2 max-speed=10g active=true +init set port-map unit=0 port=23 eth-macro=10 lane=3 max-speed=10g active=true +init set port-map unit=0 port=24 eth-macro=12 lane=0 max-speed=10g active=true +init set port-map unit=0 port=25 eth-macro=12 lane=1 max-speed=10g active=true +init set port-map unit=0 port=26 eth-macro=12 lane=2 max-speed=10g active=true +init set port-map unit=0 port=27 eth-macro=12 lane=3 max-speed=10g active=true +init set port-map unit=0 port=28 eth-macro=14 lane=0 max-speed=10g active=true +init set port-map unit=0 port=29 eth-macro=14 lane=1 max-speed=10g active=true +init set port-map unit=0 port=30 eth-macro=14 lane=2 max-speed=10g active=true +init set port-map unit=0 port=31 eth-macro=14 lane=3 max-speed=10g active=true +init set port-map unit=0 port=32 eth-macro=16 lane=0 max-speed=10g active=true +init set port-map unit=0 port=33 eth-macro=16 lane=1 max-speed=10g active=true +init set port-map unit=0 port=34 eth-macro=16 lane=2 max-speed=10g active=true +init set port-map unit=0 port=35 eth-macro=16 lane=3 max-speed=10g active=true +init set port-map unit=0 port=36 eth-macro=17 lane=0 max-speed=10g active=true +init set port-map unit=0 port=37 eth-macro=17 lane=1 max-speed=10g active=true +init set port-map unit=0 port=38 eth-macro=17 lane=2 max-speed=10g active=true +init set port-map unit=0 port=39 eth-macro=17 lane=3 max-speed=10g active=true +init set port-map unit=0 port=40 eth-macro=18 lane=0 max-speed=10g active=true +init set port-map unit=0 port=41 eth-macro=18 lane=1 max-speed=10g active=true +init set port-map unit=0 port=42 eth-macro=18 lane=2 max-speed=10g active=true +init set port-map unit=0 port=43 eth-macro=18 lane=3 max-speed=10g active=true +init set port-map unit=0 port=44 eth-macro=19 lane=0 max-speed=10g active=true +init set port-map unit=0 port=45 eth-macro=19 lane=1 max-speed=10g active=true +init set port-map unit=0 port=46 eth-macro=19 lane=2 max-speed=10g active=true +init set port-map unit=0 port=47 eth-macro=19 lane=3 max-speed=10g active=true init set port-map unit=0 port=48 eth-macro=21 lane=0 max-speed=100g active=true init set port-map unit=0 port=49 eth-macro=20 lane=0 max-speed=100g active=true -init set port-map unit=0 port=50 eth-macro=23 lane=0 max-speed=100g active=true -init set port-map unit=0 port=51 eth-macro=22 lane=0 max-speed=100g active=true -init set port-map unit=0 port=52 eth-macro=27 lane=0 max-speed=100g active=true -init set port-map unit=0 port=53 eth-macro=26 lane=0 max-speed=100g active=true -init set port-map unit=0 port=54 eth-macro=29 lane=0 max-speed=100g active=true -init set port-map unit=0 port=55 eth-macro=28 lane=0 max-speed=100g active=true +init set port-map unit=0 port=50 eth-macro=27 lane=0 max-speed=100g active=true +init set port-map unit=0 port=51 eth-macro=26 lane=0 max-speed=100g active=true +init set port-map unit=0 port=52 eth-macro=29 lane=0 max-speed=100g active=true +init set port-map unit=0 port=53 eth-macro=28 lane=0 max-speed=100g active=true init set port-map unit=0 port=129 eth-macro=0 lane=1 max-speed=10g active=true guarantee=true cpi=true init set port-map unit=0 port=130 eth-macro=0 lane=0 max-speed=10g active=true guarantee=true cpi=true init-done=true init start stage unit=0 task-rsrc @@ -110,12 +108,10 @@ phy set lane-swap unit=0 portlist=46 lane-cnt=1 property=tx data=0x2 phy set lane-swap unit=0 portlist=47 lane-cnt=1 property=tx data=0x3 phy set lane-swap unit=0 portlist=48 lane-cnt=4 property=tx data=0x3.0.1.2 phy set lane-swap unit=0 portlist=49 lane-cnt=4 property=tx data=0x3.2.1.0 -phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=tx data=0x3.2.0.1 +phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=tx data=0x3.2.1.0 +phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=tx data=0x3.2.1.0 phy set lane-swap unit=0 portlist=52 lane-cnt=4 property=tx data=0x3.2.1.0 phy set lane-swap unit=0 portlist=53 lane-cnt=4 property=tx data=0x3.2.1.0 -phy set lane-swap unit=0 portlist=54 lane-cnt=4 property=tx data=0x3.2.1.0 -phy set lane-swap unit=0 portlist=55 lane-cnt=4 property=tx data=0x3.2.1.0 phy set lane-swap unit=0 portlist=129 lane-cnt=1 property=tx data=0x1 phy set lane-swap unit=0 portlist=130 lane-cnt=1 property=tx data=0x0 phy set lane-swap unit=0 portlist=0 lane-cnt=1 property=rx data=0x0 @@ -168,12 +164,10 @@ phy set lane-swap unit=0 portlist=46 lane-cnt=1 property=rx data=0x0 phy set lane-swap unit=0 portlist=47 lane-cnt=1 property=rx data=0x3 phy set lane-swap unit=0 portlist=48 lane-cnt=4 property=rx data=0x3.1.0.2 phy set lane-swap unit=0 portlist=49 lane-cnt=4 property=rx data=0x3.2.1.0 -phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=rx data=0x3.0.1.2 -phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=rx data=0x3.2.1.0 +phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=rx data=0x1.0.3.2 +phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=rx data=0x2.0.1.3 phy set lane-swap unit=0 portlist=52 lane-cnt=4 property=rx data=0x1.0.3.2 -phy set lane-swap unit=0 portlist=53 lane-cnt=4 property=rx data=0x2.0.1.3 -phy set lane-swap unit=0 portlist=54 lane-cnt=4 property=rx data=0x1.0.3.2 -phy set lane-swap unit=0 portlist=55 lane-cnt=4 property=rx data=0x1.0.3.2 +phy set lane-swap unit=0 portlist=53 lane-cnt=4 property=rx data=0x1.0.3.2 phy set lane-swap unit=0 portlist=129 lane-cnt=1 property=rx data=0x1 phy set lane-swap unit=0 portlist=130 lane-cnt=1 property=rx data=0x0 phy set polarity-rev unit=0 portlist=0 lane-cnt=1 property=tx data=0x0 @@ -230,8 +224,6 @@ phy set polarity-rev unit=0 portlist=50 lane-cnt=4 property=tx data=0x0.0.0.0 phy set polarity-rev unit=0 portlist=51 lane-cnt=4 property=tx data=0x0.0.0.0 phy set polarity-rev unit=0 portlist=52 lane-cnt=4 property=tx data=0x0.0.0.0 phy set polarity-rev unit=0 portlist=53 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=54 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=55 lane-cnt=4 property=tx data=0x0.0.0.0 phy set polarity-rev unit=0 portlist=129 lane-cnt=1 property=tx data=0x0 phy set polarity-rev unit=0 portlist=130 lane-cnt=1 property=tx data=0x0 phy set polarity-rev unit=0 portlist=0 lane-cnt=1 property=rx data=0x0 @@ -284,12 +276,10 @@ phy set polarity-rev unit=0 portlist=46 lane-cnt=1 property=rx data=0x0 phy set polarity-rev unit=0 portlist=47 lane-cnt=1 property=rx data=0x0 phy set polarity-rev unit=0 portlist=48 lane-cnt=4 property=rx data=0x0.1.1.0 phy set polarity-rev unit=0 portlist=49 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=50 lane-cnt=4 property=rx data=0x1.1.1.1 +phy set polarity-rev unit=0 portlist=50 lane-cnt=4 property=rx data=0x1.1.1.0 phy set polarity-rev unit=0 portlist=51 lane-cnt=4 property=rx data=0x0.0.0.0 phy set polarity-rev unit=0 portlist=52 lane-cnt=4 property=rx data=0x1.1.1.0 phy set polarity-rev unit=0 portlist=53 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=54 lane-cnt=4 property=rx data=0x1.1.1.0 -phy set polarity-rev unit=0 portlist=55 lane-cnt=4 property=rx data=0x0.0.0.0 phy set polarity-rev unit=0 portlist=129 lane-cnt=1 property=rx data=0x0 phy set polarity-rev unit=0 portlist=130 lane-cnt=1 property=rx data=0x0 phy set pre-emphasis unit=0 portlist=0 lane-cnt=1 property=c2 data=0x2 @@ -508,14 +498,6 @@ phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=cn1 data=0x0.0.0.0 phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c1 data=0x6.6.6.6 -phy set pre-emphasis unit=0 portlist=54 lane-cnt=4 property=c2 data=0x2.2.2.2 -phy set pre-emphasis unit=0 portlist=54 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis unit=0 portlist=54 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b -phy set pre-emphasis unit=0 portlist=54 lane-cnt=4 property=c1 data=0x6.6.6.6 -phy set pre-emphasis unit=0 portlist=55 lane-cnt=4 property=c2 data=0x2.2.2.2 -phy set pre-emphasis unit=0 portlist=55 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis unit=0 portlist=55 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b -phy set pre-emphasis unit=0 portlist=55 lane-cnt=4 property=c1 data=0x6.6.6.6 phy set pre-emphasis unit=0 portlist=129 lane-cnt=1 property=c2 data=0x1 phy set pre-emphasis unit=0 portlist=129 lane-cnt=1 property=cn1 data=0x1 phy set pre-emphasis unit=0 portlist=129 lane-cnt=1 property=c0 data=0x2 @@ -524,62 +506,60 @@ phy set pre-emphasis unit=0 portlist=130 lane-cnt=1 property=c2 data=0x1 phy set pre-emphasis unit=0 portlist=130 lane-cnt=1 property=cn1 data=0x0 phy set pre-emphasis unit=0 portlist=130 lane-cnt=1 property=c0 data=0x2 phy set pre-emphasis unit=0 portlist=130 lane-cnt=1 property=c1 data=0x3 -port set property unit=0 portlist=0 speed=25g -port set property unit=0 portlist=1 speed=25g -port set property unit=0 portlist=2 speed=25g -port set property unit=0 portlist=3 speed=25g -port set property unit=0 portlist=4 speed=25g -port set property unit=0 portlist=5 speed=25g -port set property unit=0 portlist=6 speed=25g -port set property unit=0 portlist=7 speed=25g -port set property unit=0 portlist=8 speed=25g -port set property unit=0 portlist=9 speed=25g -port set property unit=0 portlist=10 speed=25g -port set property unit=0 portlist=11 speed=25g -port set property unit=0 portlist=12 speed=25g -port set property unit=0 portlist=13 speed=25g -port set property unit=0 portlist=14 speed=25g -port set property unit=0 portlist=15 speed=25g -port set property unit=0 portlist=16 speed=25g -port set property unit=0 portlist=17 speed=25g -port set property unit=0 portlist=18 speed=25g -port set property unit=0 portlist=19 speed=25g -port set property unit=0 portlist=20 speed=25g -port set property unit=0 portlist=21 speed=25g -port set property unit=0 portlist=22 speed=25g -port set property unit=0 portlist=23 speed=25g -port set property unit=0 portlist=24 speed=25g -port set property unit=0 portlist=25 speed=25g -port set property unit=0 portlist=26 speed=25g -port set property unit=0 portlist=27 speed=25g -port set property unit=0 portlist=28 speed=25g -port set property unit=0 portlist=29 speed=25g -port set property unit=0 portlist=30 speed=25g -port set property unit=0 portlist=31 speed=25g -port set property unit=0 portlist=32 speed=25g -port set property unit=0 portlist=33 speed=25g -port set property unit=0 portlist=34 speed=25g -port set property unit=0 portlist=35 speed=25g -port set property unit=0 portlist=36 speed=25g -port set property unit=0 portlist=37 speed=25g -port set property unit=0 portlist=38 speed=25g -port set property unit=0 portlist=39 speed=25g -port set property unit=0 portlist=40 speed=25g -port set property unit=0 portlist=41 speed=25g -port set property unit=0 portlist=42 speed=25g -port set property unit=0 portlist=43 speed=25g -port set property unit=0 portlist=44 speed=25g -port set property unit=0 portlist=45 speed=25g -port set property unit=0 portlist=46 speed=25g -port set property unit=0 portlist=47 speed=25g +port set property unit=0 portlist=0 speed=10g +port set property unit=0 portlist=1 speed=10g +port set property unit=0 portlist=2 speed=10g +port set property unit=0 portlist=3 speed=10g +port set property unit=0 portlist=4 speed=10g +port set property unit=0 portlist=5 speed=10g +port set property unit=0 portlist=6 speed=10g +port set property unit=0 portlist=7 speed=10g +port set property unit=0 portlist=8 speed=10g +port set property unit=0 portlist=9 speed=10g +port set property unit=0 portlist=10 speed=10g +port set property unit=0 portlist=11 speed=10g +port set property unit=0 portlist=12 speed=10g +port set property unit=0 portlist=13 speed=10g +port set property unit=0 portlist=14 speed=10g +port set property unit=0 portlist=15 speed=10g +port set property unit=0 portlist=16 speed=10g +port set property unit=0 portlist=17 speed=10g +port set property unit=0 portlist=18 speed=10g +port set property unit=0 portlist=19 speed=10g +port set property unit=0 portlist=20 speed=10g +port set property unit=0 portlist=21 speed=10g +port set property unit=0 portlist=22 speed=10g +port set property unit=0 portlist=23 speed=10g +port set property unit=0 portlist=24 speed=10g +port set property unit=0 portlist=25 speed=10g +port set property unit=0 portlist=26 speed=10g +port set property unit=0 portlist=27 speed=10g +port set property unit=0 portlist=28 speed=10g +port set property unit=0 portlist=29 speed=10g +port set property unit=0 portlist=30 speed=10g +port set property unit=0 portlist=31 speed=10g +port set property unit=0 portlist=32 speed=10g +port set property unit=0 portlist=33 speed=10g +port set property unit=0 portlist=34 speed=10g +port set property unit=0 portlist=35 speed=10g +port set property unit=0 portlist=36 speed=10g +port set property unit=0 portlist=37 speed=10g +port set property unit=0 portlist=38 speed=10g +port set property unit=0 portlist=39 speed=10g +port set property unit=0 portlist=40 speed=10g +port set property unit=0 portlist=41 speed=10g +port set property unit=0 portlist=42 speed=10g +port set property unit=0 portlist=43 speed=10g +port set property unit=0 portlist=44 speed=10g +port set property unit=0 portlist=45 speed=10g +port set property unit=0 portlist=46 speed=10g +port set property unit=0 portlist=47 speed=10g port set property unit=0 portlist=48 speed=100g port set property unit=0 portlist=49 speed=100g port set property unit=0 portlist=50 speed=100g port set property unit=0 portlist=51 speed=100g port set property unit=0 portlist=52 speed=100g port set property unit=0 portlist=53 speed=100g -port set property unit=0 portlist=54 speed=100g -port set property unit=0 portlist=55 speed=100g port set property unit=0 portlist=129 speed=10g port set property unit=0 portlist=130 speed=1g port set property unit=0 portlist=0 medium-type=sr @@ -636,8 +616,6 @@ port set property unit=0 portlist=50 medium-type=sr4 port set property unit=0 portlist=51 medium-type=sr4 port set property unit=0 portlist=52 medium-type=sr4 port set property unit=0 portlist=53 medium-type=sr4 -port set property unit=0 portlist=54 medium-type=sr4 -port set property unit=0 portlist=55 medium-type=sr4 port set property unit=0 portlist=129 medium-type=kr port set property unit=0 portlist=130 medium-type=x port advertise unit=0 portlist=129 speed-10g-kr @@ -696,7 +674,5 @@ port set property unit=0 portlist=50 admin=enable port set property unit=0 portlist=51 admin=enable port set property unit=0 portlist=52 admin=enable port set property unit=0 portlist=53 admin=enable -port set property unit=0 portlist=54 admin=enable -port set property unit=0 portlist=55 admin=enable -port set property unit=0 portlist=129 admin=enable -port set property unit=0 portlist=130 admin=enable +port set property unit=0 portlist=129 admin=disable +port set property unit=0 portlist=130 admin=disable diff --git a/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/qos.json.j2 b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/sai.profile b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/sai.profile new file mode 100644 index 000000000000..e7b5f90ac88a --- /dev/null +++ b/device/cig/x86_64-cig_cs5435_54p-r0/Cig-CS5435-54P/sai.profile @@ -0,0 +1,3 @@ +SAI_INIT_LED_CONFIG_FILE=/usr/share/sonic/hwsku/led.bin +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/proc_init.nps +SAI_DSH_CONFIG_FILE=/usr/share/sonic/hwsku/port_config.nps diff --git a/device/cig/x86_64-cig_cs5435_54p-r0/default_sku b/device/cig/x86_64-cig_cs5435_54p-r0/default_sku new file mode 100644 index 000000000000..66b35b61e09b --- /dev/null +++ b/device/cig/x86_64-cig_cs5435_54p-r0/default_sku @@ -0,0 +1 @@ +Cig-CS5435-54P t1 diff --git a/device/cig/x86_64-cig_cs5435_54p-r0/installer.conf b/device/cig/x86_64-cig_cs5435_54p-r0/installer.conf new file mode 100644 index 000000000000..ea6b4f6ebe31 --- /dev/null +++ b/device/cig/x86_64-cig_cs5435_54p-r0/installer.conf @@ -0,0 +1,4 @@ +CONSOLE_PORT=0x3f8 +CONSOLE_DEV=0 +CONSOLE_SPEED=115200 +ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="pci=noaer" diff --git a/device/cig/x86_64-cig_cs5435_54p-r0/plugins/eeprom.py b/device/cig/x86_64-cig_cs5435_54p-r0/plugins/eeprom.py new file mode 100755 index 000000000000..5019b9c40a9a --- /dev/null +++ b/device/cig/x86_64-cig_cs5435_54p-r0/plugins/eeprom.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python + +try: + import exceptions + import binascii + import time + import optparse + import warnings + import os + import sys + from sonic_eeprom import eeprom_base + from sonic_eeprom import eeprom_tlvinfo + import subprocess +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + +class board(eeprom_tlvinfo.TlvInfoDecoder): + _TLV_INFO_MAX_LEN = 256 + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/sys/bus/i2c/devices/7-0057/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/cig/x86_64-cig_cs5435_54p-r0/plugins/psuutil.py b/device/cig/x86_64-cig_cs5435_54p-r0/plugins/psuutil.py new file mode 100755 index 000000000000..70d50e6c3458 --- /dev/null +++ b/device/cig/x86_64-cig_cs5435_54p-r0/plugins/psuutil.py @@ -0,0 +1,93 @@ +# +# psuutil.py +# Platform-specific PSU status interface for SONiC +# + + +import os.path +import logging + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + SYSFS_PSU_DIR = ["/sys/bus/i2c/devices/5-005a", + "/sys/bus/i2c/devices/5-005b"] + + def __init__(self): + PsuBase.__init__(self) + + + # Get sysfs attribute + def get_attr_value(self, attr_path): + + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open %s file !", attr_path) + + retval = retval.rstrip('\r\n') + return retval + + def get_num_psus(self): + """ + Retrieves the number of PSUs available on the device + :return: An integer, the number of PSUs available on the device + """ + MAX_PSUS = 2 + return MAX_PSUS + + def get_psu_status(self, index): + """ + Retrieves the oprational status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is operating properly, False if PSU is\ + faulty + """ + status = 0 + attr_file = 'psu_power_good' + attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file + + attr_value = self.get_attr_value(attr_path) + + if (attr_value != 'ERR'): + attr_value = int(attr_value, 16) + # Check for PSU status + if (attr_value == 1): + status = 1 + + return status + + def get_psu_presence(self, index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + status = 0 + psu_absent = 0 + attr_file ='psu_present' + attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file + + attr_value = self.get_attr_value(attr_path) + + if (attr_value != 'ERR'): + attr_value = int(attr_value, 16) + # Check for PSU presence + if (attr_value == 1): + status = 1 + + return status + diff --git a/device/cig/x86_64-cig_cs5435_54p-r0/plugins/sfputil.py b/device/cig/x86_64-cig_cs5435_54p-r0/plugins/sfputil.py new file mode 100755 index 000000000000..2863b80c9950 --- /dev/null +++ b/device/cig/x86_64-cig_cs5435_54p-r0/plugins/sfputil.py @@ -0,0 +1,250 @@ +#!/usr/bin/env python + +try: + import time + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + + +class SfpUtil(SfpUtilBase): + """Platform specific SfpUtill class""" + + _port_start = 1 + _port_end = 54 + _qsfp_port_start = 49 + _ports_in_block = 54 + + _port_to_eeprom_mapping = {} + _global_port_pres_dict = {} + + _port_to_i2c_mapping = { + 1 : 8, + 2 : 9, + 3 : 10, + 4 : 11, + 5 : 12, + 6 : 13, + 7 : 14, + 8 : 15, + 9 : 16, + 10: 17, + 11 : 18, + 12 : 19, + 13 : 20, + 14 : 21, + 15 : 22, + 16 : 23, + 17 : 24, + 18 : 25, + 19 : 26, + 20 : 27, + 21 : 28, + 22 : 29, + 23 : 30, + 24 : 31, + 25 : 32, + 26 : 33, + 27 : 34, + 28 : 35, + 29 : 36, + 30 : 37, + 31 : 38, + 32 : 39, + 33 : 40, + 34 : 41, + 35 : 42, + 36 : 43, + 37 : 44, + 38 : 45, + 39 : 46, + 40 : 47, + 41 : 48, + 42 : 49, + 43 : 50, + 44 : 51, + 45 : 52, + 46 : 53, + 47 : 54, + 48 : 55, + 49 : 56, + 50 : 57, + 51 : 60, + 52 : 61, + 53 : 62, + 54 : 63, + } + + _qsfp_ports = range(_qsfp_port_start, _ports_in_block + 1) + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + + path = "/sys/bus/i2c/devices/{0}-0050/sfp_is_present" + port_ps = path.format(self._port_to_i2c_mapping[port_num]) + + + try: + reg_file = open(port_ps) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + try: + reg_value = reg_file.readline().rstrip() + except IOError as e: + time.sleep(1) + + try: + reg_value = reg_file.readline().rstrip() + except IOError as e: + print "Error:try again to read file failed: %s %s" % (str(e), port_ps) + reg_file.close() + return False + + reg_file.close() + if reg_value == '1': + return True + + reg_file.close() + if reg_value == '1': + return True + + return False + + def init_global_port_presence(self): + for port_num in range(self.port_start, (self.port_end + 1)): + self._global_port_pres_dict[port_num] = '0' + + + def __init__(self): + eeprom_path = '/sys/bus/i2c/devices/{0}-0050/sfp_eeprom' + for x in range(self._port_start, self._port_end + 1): + port_eeprom_path = eeprom_path.format(self._port_to_i2c_mapping[x]) + self._port_to_eeprom_mapping[x] = port_eeprom_path + + self.init_global_port_presence() + SfpUtilBase.__init__(self) + + def reset(self, port_num): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + + path = "/sys/bus/i2c/devices/{0}-0050/sfp_port_reset" + port_ps = path.format(self._port_to_i2c_mapping[port_num]) + + try: + reg_file = open(port_ps, 'w') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + #toggle reset + reg_file.seek(0) + reg_file.write('1') + time.sleep(1) + reg_file.seek(0) + reg_file.write('0') + reg_file.close() + return True + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + if port_num < self._qsfp_port_start or port_num > self._port_end: + return False + + pre_value = self.get_presence(port_num) + if pre_value == False: + return False + + path = "/sys/bus/i2c/devices/{0}-0050/sfp_lpmode" + port_ps = path.format(self._port_to_i2c_mapping[port_num]) + + try: + reg_file = open(port_ps,'w') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_file.seek(0) + + if lpmode == 1: + reg_file.write('1') + elif lpmode == 0: + reg_file.write('0') + reg_file.close() + + return True + + + def get_low_power_mode(self, port_num): + # Check for invalid port_num + + if port_num < self._qsfp_port_start or port_num > self._port_end: + return False + + pre_value = self.get_presence(port_num) + if pre_value == False: + return False + + path = "/sys/bus/i2c/devices/{0}-0050/sfp_lpmode" + port_ps = path.format(self._port_to_i2c_mapping[port_num]) + + try: + reg_file = open(port_ps) + except IOError as e: + print "Error: unable to open file:%s %s" % (str(e), port_ps) + return False + + try: + reg_value = reg_file.readline().rstrip() + except IOError as e: + print "Error: unable to open file:%s %s" % (str(e), port_ps) + reg_file.close() + return False + + reg_file.close() + + if reg_value == '1': + return True + + return False + + def get_transceiver_change_event(self): + port_dict = {} + while True: + for port_num in range(self.port_start, (self.port_end + 1)): + presence = self.get_presence(port_num) + + if(presence and self._global_port_pres_dict[port_num] == '0'): + self._global_port_pres_dict[port_num] = '1' + port_dict[port_num] = '1' + elif(not presence and + self._global_port_pres_dict[port_num] == '1'): + self._global_port_pres_dict[port_num] = '0' + port_dict[port_num] = '0' + + if(len(port_dict) > 0): + return True, port_dict + + time.sleep(0.5) + + + @property + def port_start(self): + return self._port_start + + @property + def port_end(self): + return self._port_end + + @property + def qsfp_ports(self): + return self._qsfp_ports + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping diff --git a/device/cig/x86_64-cig_cs5435_54p-r0/sensors.conf b/device/cig/x86_64-cig_cs5435_54p-r0/sensors.conf new file mode 100644 index 000000000000..f0964c87dae7 --- /dev/null +++ b/device/cig/x86_64-cig_cs5435_54p-r0/sensors.conf @@ -0,0 +1,13 @@ +# libsensors configuration file + +chip "cs5435_54p_fan-*" + label fan1 "front fan 1" + label fan2 "front fan 2" + label fan3 "front fan 3" + label fan4 "front fan 4" + label fan5 "front fan 5" + label fan6 "rear fan 1" + label fan7 "rear fan 2" + label fan8 "rear fan 3" + label fan9 "rear fan 4" + label fan10 "rear fan 5" diff --git a/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/buffers.json.j2 b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/buffers.json.j2 new file mode 100644 index 000000000000..2c391214fa65 --- /dev/null +++ b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/buffers.json.j2 @@ -0,0 +1,111 @@ +{# Default values which will be used if no actual configura available #} +{% set default_cable = '40m' %} +{% set default_speed = '10G' %} +{% set default_ports_num = 54 -%} + +{# Port configuration to cable length look-up table #} +{# Each record describes mapping of DUT (DUT port) role and neighbor role to cable length #} +{# Roles described in the minigraph #} +{% set ports2cable = { + 'torrouter_server' : '5m', + 'leafrouter_torrouter' : '40m', + 'spinerouter_leafrouter' : '300m' + } +%} + +{%- macro cable_length(port_name) -%} + {%- set cable_len = [] -%} + {%- for local_port in DEVICE_NEIGHBOR -%} + {%- if local_port == port_name -%} + {%- if DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor = DEVICE_NEIGHBOR_METADATA[DEVICE_NEIGHBOR[local_port].name] -%} + {%- set neighbor_role = neighbor.type -%} + {%- set roles1 = switch_role + '_' + neighbor_role %} + {%- set roles2 = neighbor_role + '_' + switch_role -%} + {%- set roles1 = roles1 | lower -%} + {%- set roles2 = roles2 | lower -%} + {%- if roles1 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles1]) -%}{%- endif -%} + {%- elif roles2 in ports2cable -%} + {%- if cable_len.append(ports2cable[roles2]) -%}{%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endif -%} + {%- endfor -%} + {%- if cable_len -%} + {{ cable_len.0 }} + {%- else -%} + {{ default_cable }} + {%- endif -%} +{% endmacro %} + +{%- if DEVICE_METADATA is defined %} +{%- set switch_role = DEVICE_METADATA['localhost']['type'] %} +{%- endif -%} + +{# Generate list of ports if not defined #} +{% if PORT is not defined %} + {% set PORT = [] %} + {% for port_idx in range(0,default_ports_num) %} + {% if PORT.append("Ethernet%d" % (port_idx)) %}{% endif %} + {% endfor %} +{% endif -%} + +{% set port_names_list = [] %} +{% for port in PORT %} + {%- if port_names_list.append(port) %}{% endif %} +{% endfor %} +{% set port_names = port_names_list | join(',') -%} + +{ + "CABLE_LENGTH": { + "AZURE": { + {% for port in PORT %} + {% set cable = cable_length(port) -%} + "{{ port }}": "{{ cable }}"{%- if not loop.last -%},{% endif %} + + {% endfor %} + } + }, + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "20971328", + "type": "ingress", + "mode": "static" + }, + "ingress_lossy_pool": { + "size": "20971328", + "type": "ingress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "20971328", + "type": "egress", + "mode": "static" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "xon":"78400", + "xoff":"132160", + "size":"3584", + "static_th":"82880" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"3584", + "dynamic_th":"-1" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"3584", + "dynamic_th":"-4" + } + }, + "BUFFER_PG": { + }, + "BUFFER_QUEUE": { + } +} + \ No newline at end of file diff --git a/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/led.bin b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/led.bin new file mode 100644 index 0000000000000000000000000000000000000000..201662a1c605693991df041260615085a9b5eb7b GIT binary patch literal 652 zcmWN`$uk0Q7{}qC8Dp3cZL(b}N?9vwi@MsWq^r14mvBk`bbSZAFz)>vhg7rbDLEjHQYB`?`vgMa+vlvDolmlIC- z!ykV0n_v9mm}8DO;*djr@{=F@;5*;>#y1W);45F*XP+;8VUImN^O;?C*V!Z literal 0 HcmV?d00001 diff --git a/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/pg_profile_lookup.ini b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/pg_profile_lookup.ini new file mode 100644 index 000000000000..d98b0eca6d19 --- /dev/null +++ b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold + 10000 5m 3584 32256 59136 36736 + 25000 5m 3584 41216 68096 45696 + 40000 5m 3584 47488 74368 51968 + 50000 5m 3584 52864 79744 57344 + 100000 5m 3584 78400 132160 82880 + 10000 40m 3584 32256 59136 36736 + 25000 40m 3584 41216 68096 45696 + 40000 40m 3584 47488 74368 51968 + 50000 40m 3584 52864 79744 57344 + 100000 40m 3584 78400 132160 82880 + 10000 300m 3584 32256 65856 36736 + 25000 300m 3584 41216 84672 45696 + 40000 300m 3584 47488 101024 51968 + 50000 300m 3584 52864 113120 57344 + 100000 300m 3584 78400 198688 82880 \ No newline at end of file diff --git a/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/port_config.ini b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/port_config.ini new file mode 100644 index 000000000000..165b5204c2f8 --- /dev/null +++ b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/port_config.ini @@ -0,0 +1,55 @@ +# name lanes alias index speed +Ethernet0 8 Ethernet1/1 1 25000 +Ethernet1 9 Ethernet2/1 2 25000 +Ethernet2 10 Ethernet3/1 3 25000 +Ethernet3 11 Ethernet4/1 4 25000 +Ethernet4 12 Ethernet5/1 5 25000 +Ethernet5 13 Ethernet6/1 6 25000 +Ethernet6 14 Ethernet7/1 7 25000 +Ethernet7 15 Ethernet8/1 8 25000 +Ethernet8 16 Ethernet9/1 9 25000 +Ethernet9 17 Ethernet10/1 10 25000 +Ethernet10 18 Ethernet11/1 11 25000 +Ethernet11 19 Ethernet12/1 12 25000 +Ethernet12 20 Ethernet13/1 13 25000 +Ethernet13 21 Ethernet14/1 14 25000 +Ethernet14 22 Ethernet15/1 15 25000 +Ethernet15 23 Ethernet16/1 16 25000 +Ethernet16 32 Ethernet17/1 17 25000 +Ethernet17 33 Ethernet18/1 18 25000 +Ethernet18 34 Ethernet19/1 19 25000 +Ethernet19 35 Ethernet20/1 20 25000 +Ethernet20 40 Ethernet21/1 21 25000 +Ethernet21 41 Ethernet22/1 22 25000 +Ethernet22 42 Ethernet23/1 23 25000 +Ethernet23 43 Ethernet24/1 24 25000 +Ethernet24 48 Ethernet25/1 25 25000 +Ethernet25 49 Ethernet26/1 26 25000 +Ethernet26 50 Ethernet27/1 27 25000 +Ethernet27 51 Ethernet28/1 28 25000 +Ethernet28 56 Ethernet29/1 29 25000 +Ethernet29 57 Ethernet30/1 30 25000 +Ethernet30 58 Ethernet31/1 31 25000 +Ethernet31 59 Ethernet32/1 32 25000 +Ethernet32 64 Ethernet33/1 33 25000 +Ethernet33 65 Ethernet34/1 34 25000 +Ethernet34 66 Ethernet35/1 35 25000 +Ethernet35 67 Ethernet36/1 36 25000 +Ethernet36 68 Ethernet37/1 37 25000 +Ethernet37 69 Ethernet38/1 38 25000 +Ethernet38 70 Ethernet39/1 39 25000 +Ethernet39 71 Ethernet40/1 40 25000 +Ethernet40 72 Ethernet41/1 41 25000 +Ethernet41 73 Ethernet42/1 42 25000 +Ethernet42 74 Ethernet43/1 43 25000 +Ethernet43 75 Ethernet44/1 44 25000 +Ethernet44 76 Ethernet45/1 45 25000 +Ethernet45 77 Ethernet46/1 46 25000 +Ethernet46 78 Ethernet47/1 47 25000 +Ethernet47 79 Ethernet48/1 48 25000 +Ethernet48 84,85,86,87 Ethernet49/1 49 100000 +Ethernet49 80,81,82,83 Ethernet50/1 50 100000 +Ethernet50 108,109,110,111 Ethernet51/1 51 100000 +Ethernet51 104,105,106,107 Ethernet52/1 52 100000 +Ethernet52 116,117,118,119 Ethernet53/1 53 100000 +Ethernet53 112,113,114,115 Ethernet54/1 54 100000 diff --git a/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.nps.AOC.R0B b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/port_config.nps old mode 100755 new mode 100644 similarity index 92% rename from device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.nps.AOC.R0B rename to device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/port_config.nps index 857e5f1ede5f..aca222f5962d --- a/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/port_config.nps.AOC.R0B +++ b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/port_config.nps @@ -1,24 +1,24 @@ init start stage unit=0 low-level -init set port-map unit=0 port=0 eth-macro=2 lane=0 max-speed=25g active=true -init set port-map unit=0 port=1 eth-macro=2 lane=1 max-speed=25g active=true -init set port-map unit=0 port=2 eth-macro=2 lane=2 max-speed=25g active=true -init set port-map unit=0 port=3 eth-macro=2 lane=3 max-speed=25g active=true -init set port-map unit=0 port=4 eth-macro=3 lane=0 max-speed=25g active=true -init set port-map unit=0 port=5 eth-macro=3 lane=1 max-speed=25g active=true -init set port-map unit=0 port=6 eth-macro=3 lane=2 max-speed=25g active=true -init set port-map unit=0 port=7 eth-macro=3 lane=3 max-speed=25g active=true -init set port-map unit=0 port=8 eth-macro=4 lane=0 max-speed=25g active=true -init set port-map unit=0 port=9 eth-macro=4 lane=1 max-speed=25g active=true -init set port-map unit=0 port=10 eth-macro=4 lane=2 max-speed=25g active=true -init set port-map unit=0 port=11 eth-macro=4 lane=3 max-speed=25g active=true -init set port-map unit=0 port=12 eth-macro=5 lane=0 max-speed=25g active=true -init set port-map unit=0 port=13 eth-macro=5 lane=1 max-speed=25g active=true -init set port-map unit=0 port=14 eth-macro=5 lane=2 max-speed=25g active=true -init set port-map unit=0 port=15 eth-macro=5 lane=3 max-speed=25g active=true -init set port-map unit=0 port=16 eth-macro=8 lane=0 max-speed=25g active=true -init set port-map unit=0 port=17 eth-macro=8 lane=1 max-speed=25g active=true -init set port-map unit=0 port=18 eth-macro=8 lane=2 max-speed=25g active=true -init set port-map unit=0 port=19 eth-macro=8 lane=3 max-speed=25g active=true +init set port-map unit=0 port=0 eth-macro=2 lane=0 max-speed=25g active=true +init set port-map unit=0 port=1 eth-macro=2 lane=1 max-speed=25g active=true +init set port-map unit=0 port=2 eth-macro=2 lane=2 max-speed=25g active=true +init set port-map unit=0 port=3 eth-macro=2 lane=3 max-speed=25g active=true +init set port-map unit=0 port=4 eth-macro=3 lane=0 max-speed=25g active=true +init set port-map unit=0 port=5 eth-macro=3 lane=1 max-speed=25g active=true +init set port-map unit=0 port=6 eth-macro=3 lane=2 max-speed=25g active=true +init set port-map unit=0 port=7 eth-macro=3 lane=3 max-speed=25g active=true +init set port-map unit=0 port=8 eth-macro=4 lane=0 max-speed=25g active=true +init set port-map unit=0 port=9 eth-macro=4 lane=1 max-speed=25g active=true +init set port-map unit=0 port=10 eth-macro=4 lane=2 max-speed=25g active=true +init set port-map unit=0 port=11 eth-macro=4 lane=3 max-speed=25g active=true +init set port-map unit=0 port=12 eth-macro=5 lane=0 max-speed=25g active=true +init set port-map unit=0 port=13 eth-macro=5 lane=1 max-speed=25g active=true +init set port-map unit=0 port=14 eth-macro=5 lane=2 max-speed=25g active=true +init set port-map unit=0 port=15 eth-macro=5 lane=3 max-speed=25g active=true +init set port-map unit=0 port=16 eth-macro=8 lane=0 max-speed=25g active=true +init set port-map unit=0 port=17 eth-macro=8 lane=1 max-speed=25g active=true +init set port-map unit=0 port=18 eth-macro=8 lane=2 max-speed=25g active=true +init set port-map unit=0 port=19 eth-macro=8 lane=3 max-speed=25g active=true init set port-map unit=0 port=20 eth-macro=10 lane=0 max-speed=25g active=true init set port-map unit=0 port=21 eth-macro=10 lane=1 max-speed=25g active=true init set port-map unit=0 port=22 eth-macro=10 lane=2 max-speed=25g active=true @@ -49,12 +49,10 @@ init set port-map unit=0 port=46 eth-macro=19 lane=2 max-speed=25g active=true init set port-map unit=0 port=47 eth-macro=19 lane=3 max-speed=25g active=true init set port-map unit=0 port=48 eth-macro=21 lane=0 max-speed=100g active=true init set port-map unit=0 port=49 eth-macro=20 lane=0 max-speed=100g active=true -init set port-map unit=0 port=50 eth-macro=23 lane=0 max-speed=100g active=true -init set port-map unit=0 port=51 eth-macro=22 lane=0 max-speed=100g active=true -init set port-map unit=0 port=52 eth-macro=27 lane=0 max-speed=100g active=true -init set port-map unit=0 port=53 eth-macro=26 lane=0 max-speed=100g active=true -init set port-map unit=0 port=54 eth-macro=29 lane=0 max-speed=100g active=true -init set port-map unit=0 port=55 eth-macro=28 lane=0 max-speed=100g active=true +init set port-map unit=0 port=50 eth-macro=27 lane=0 max-speed=100g active=true +init set port-map unit=0 port=51 eth-macro=26 lane=0 max-speed=100g active=true +init set port-map unit=0 port=52 eth-macro=29 lane=0 max-speed=100g active=true +init set port-map unit=0 port=53 eth-macro=28 lane=0 max-speed=100g active=true init set port-map unit=0 port=129 eth-macro=0 lane=1 max-speed=10g active=true guarantee=true cpi=true init set port-map unit=0 port=130 eth-macro=0 lane=0 max-speed=10g active=true guarantee=true cpi=true init-done=true init start stage unit=0 task-rsrc @@ -110,12 +108,10 @@ phy set lane-swap unit=0 portlist=46 lane-cnt=1 property=tx data=0x2 phy set lane-swap unit=0 portlist=47 lane-cnt=1 property=tx data=0x3 phy set lane-swap unit=0 portlist=48 lane-cnt=4 property=tx data=0x3.0.1.2 phy set lane-swap unit=0 portlist=49 lane-cnt=4 property=tx data=0x3.2.1.0 -phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=tx data=0x0.1.2.3 -phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=tx data=0x3.2.0.1 +phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=tx data=0x3.2.1.0 +phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=tx data=0x3.2.1.0 phy set lane-swap unit=0 portlist=52 lane-cnt=4 property=tx data=0x3.2.1.0 phy set lane-swap unit=0 portlist=53 lane-cnt=4 property=tx data=0x3.2.1.0 -phy set lane-swap unit=0 portlist=54 lane-cnt=4 property=tx data=0x3.2.1.0 -phy set lane-swap unit=0 portlist=55 lane-cnt=4 property=tx data=0x3.2.1.0 phy set lane-swap unit=0 portlist=129 lane-cnt=1 property=tx data=0x1 phy set lane-swap unit=0 portlist=130 lane-cnt=1 property=tx data=0x0 phy set lane-swap unit=0 portlist=0 lane-cnt=1 property=rx data=0x0 @@ -168,12 +164,10 @@ phy set lane-swap unit=0 portlist=46 lane-cnt=1 property=rx data=0x0 phy set lane-swap unit=0 portlist=47 lane-cnt=1 property=rx data=0x3 phy set lane-swap unit=0 portlist=48 lane-cnt=4 property=rx data=0x3.1.0.2 phy set lane-swap unit=0 portlist=49 lane-cnt=4 property=rx data=0x3.2.1.0 -phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=rx data=0x3.0.1.2 -phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=rx data=0x3.2.1.0 +phy set lane-swap unit=0 portlist=50 lane-cnt=4 property=rx data=0x1.0.3.2 +phy set lane-swap unit=0 portlist=51 lane-cnt=4 property=rx data=0x2.0.1.3 phy set lane-swap unit=0 portlist=52 lane-cnt=4 property=rx data=0x1.0.3.2 -phy set lane-swap unit=0 portlist=53 lane-cnt=4 property=rx data=0x2.0.1.3 -phy set lane-swap unit=0 portlist=54 lane-cnt=4 property=rx data=0x1.0.3.2 -phy set lane-swap unit=0 portlist=55 lane-cnt=4 property=rx data=0x1.0.3.2 +phy set lane-swap unit=0 portlist=53 lane-cnt=4 property=rx data=0x1.0.3.2 phy set lane-swap unit=0 portlist=129 lane-cnt=1 property=rx data=0x1 phy set lane-swap unit=0 portlist=130 lane-cnt=1 property=rx data=0x0 phy set polarity-rev unit=0 portlist=0 lane-cnt=1 property=tx data=0x0 @@ -230,8 +224,6 @@ phy set polarity-rev unit=0 portlist=50 lane-cnt=4 property=tx data=0x0.0.0.0 phy set polarity-rev unit=0 portlist=51 lane-cnt=4 property=tx data=0x0.0.0.0 phy set polarity-rev unit=0 portlist=52 lane-cnt=4 property=tx data=0x0.0.0.0 phy set polarity-rev unit=0 portlist=53 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=54 lane-cnt=4 property=tx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=55 lane-cnt=4 property=tx data=0x0.0.0.0 phy set polarity-rev unit=0 portlist=129 lane-cnt=1 property=tx data=0x0 phy set polarity-rev unit=0 portlist=130 lane-cnt=1 property=tx data=0x0 phy set polarity-rev unit=0 portlist=0 lane-cnt=1 property=rx data=0x0 @@ -284,12 +276,10 @@ phy set polarity-rev unit=0 portlist=46 lane-cnt=1 property=rx data=0x0 phy set polarity-rev unit=0 portlist=47 lane-cnt=1 property=rx data=0x0 phy set polarity-rev unit=0 portlist=48 lane-cnt=4 property=rx data=0x0.1.1.0 phy set polarity-rev unit=0 portlist=49 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=50 lane-cnt=4 property=rx data=0x1.1.1.1 +phy set polarity-rev unit=0 portlist=50 lane-cnt=4 property=rx data=0x1.1.1.0 phy set polarity-rev unit=0 portlist=51 lane-cnt=4 property=rx data=0x0.0.0.0 phy set polarity-rev unit=0 portlist=52 lane-cnt=4 property=rx data=0x1.1.1.0 phy set polarity-rev unit=0 portlist=53 lane-cnt=4 property=rx data=0x0.0.0.0 -phy set polarity-rev unit=0 portlist=54 lane-cnt=4 property=rx data=0x1.1.1.0 -phy set polarity-rev unit=0 portlist=55 lane-cnt=4 property=rx data=0x0.0.0.0 phy set polarity-rev unit=0 portlist=129 lane-cnt=1 property=rx data=0x0 phy set polarity-rev unit=0 portlist=130 lane-cnt=1 property=rx data=0x0 phy set pre-emphasis unit=0 portlist=0 lane-cnt=1 property=c2 data=0x2 @@ -508,14 +498,6 @@ phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c2 data=0x2.2.2.2 phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=cn1 data=0x0.0.0.0 phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b phy set pre-emphasis unit=0 portlist=53 lane-cnt=4 property=c1 data=0x6.6.6.6 -phy set pre-emphasis unit=0 portlist=54 lane-cnt=4 property=c2 data=0x2.2.2.2 -phy set pre-emphasis unit=0 portlist=54 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis unit=0 portlist=54 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b -phy set pre-emphasis unit=0 portlist=54 lane-cnt=4 property=c1 data=0x6.6.6.6 -phy set pre-emphasis unit=0 portlist=55 lane-cnt=4 property=c2 data=0x2.2.2.2 -phy set pre-emphasis unit=0 portlist=55 lane-cnt=4 property=cn1 data=0x0.0.0.0 -phy set pre-emphasis unit=0 portlist=55 lane-cnt=4 property=c0 data=0x1b.1b.1b.1b -phy set pre-emphasis unit=0 portlist=55 lane-cnt=4 property=c1 data=0x6.6.6.6 phy set pre-emphasis unit=0 portlist=129 lane-cnt=1 property=c2 data=0x1 phy set pre-emphasis unit=0 portlist=129 lane-cnt=1 property=cn1 data=0x1 phy set pre-emphasis unit=0 portlist=129 lane-cnt=1 property=c0 data=0x2 @@ -578,8 +560,6 @@ port set property unit=0 portlist=50 speed=100g port set property unit=0 portlist=51 speed=100g port set property unit=0 portlist=52 speed=100g port set property unit=0 portlist=53 speed=100g -port set property unit=0 portlist=54 speed=100g -port set property unit=0 portlist=55 speed=100g port set property unit=0 portlist=129 speed=10g port set property unit=0 portlist=130 speed=1g port set property unit=0 portlist=0 medium-type=sr @@ -636,8 +616,6 @@ port set property unit=0 portlist=50 medium-type=sr4 port set property unit=0 portlist=51 medium-type=sr4 port set property unit=0 portlist=52 medium-type=sr4 port set property unit=0 portlist=53 medium-type=sr4 -port set property unit=0 portlist=54 medium-type=sr4 -port set property unit=0 portlist=55 medium-type=sr4 port set property unit=0 portlist=129 medium-type=kr port set property unit=0 portlist=130 medium-type=x port advertise unit=0 portlist=129 speed-10g-kr @@ -696,7 +674,5 @@ port set property unit=0 portlist=50 admin=enable port set property unit=0 portlist=51 admin=enable port set property unit=0 portlist=52 admin=enable port set property unit=0 portlist=53 admin=enable -port set property unit=0 portlist=54 admin=enable -port set property unit=0 portlist=55 admin=enable -port set property unit=0 portlist=129 admin=enable -port set property unit=0 portlist=130 admin=enable +port set property unit=0 portlist=129 admin=disable +port set property unit=0 portlist=130 admin=disable diff --git a/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/qos.json.j2 b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/qos.json.j2 new file mode 100644 index 000000000000..3e548325ea30 --- /dev/null +++ b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/sai.profile b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/sai.profile new file mode 100644 index 000000000000..e7b5f90ac88a --- /dev/null +++ b/device/cig/x86_64-cig_cs6436_54p-r0/Cig-CS6436-54P/sai.profile @@ -0,0 +1,3 @@ +SAI_INIT_LED_CONFIG_FILE=/usr/share/sonic/hwsku/led.bin +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/proc_init.nps +SAI_DSH_CONFIG_FILE=/usr/share/sonic/hwsku/port_config.nps diff --git a/device/cig/x86_64-cig_cs6436_54p-r0/default_sku b/device/cig/x86_64-cig_cs6436_54p-r0/default_sku new file mode 100644 index 000000000000..24afbb73b770 --- /dev/null +++ b/device/cig/x86_64-cig_cs6436_54p-r0/default_sku @@ -0,0 +1 @@ +Cig-CS6436-54P t1 diff --git a/device/cig/x86_64-cig_cs6436_54p-r0/installer.conf b/device/cig/x86_64-cig_cs6436_54p-r0/installer.conf new file mode 100644 index 000000000000..ea6b4f6ebe31 --- /dev/null +++ b/device/cig/x86_64-cig_cs6436_54p-r0/installer.conf @@ -0,0 +1,4 @@ +CONSOLE_PORT=0x3f8 +CONSOLE_DEV=0 +CONSOLE_SPEED=115200 +ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="pci=noaer" diff --git a/device/cig/x86_64-cig_cs6436_54p-r0/plugins/eeprom.py b/device/cig/x86_64-cig_cs6436_54p-r0/plugins/eeprom.py new file mode 100755 index 000000000000..5019b9c40a9a --- /dev/null +++ b/device/cig/x86_64-cig_cs6436_54p-r0/plugins/eeprom.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python + +try: + import exceptions + import binascii + import time + import optparse + import warnings + import os + import sys + from sonic_eeprom import eeprom_base + from sonic_eeprom import eeprom_tlvinfo + import subprocess +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + +class board(eeprom_tlvinfo.TlvInfoDecoder): + _TLV_INFO_MAX_LEN = 256 + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/sys/bus/i2c/devices/7-0057/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) diff --git a/device/cig/x86_64-cig_cs6436_54p-r0/plugins/psuutil.py b/device/cig/x86_64-cig_cs6436_54p-r0/plugins/psuutil.py new file mode 100755 index 000000000000..70d50e6c3458 --- /dev/null +++ b/device/cig/x86_64-cig_cs6436_54p-r0/plugins/psuutil.py @@ -0,0 +1,93 @@ +# +# psuutil.py +# Platform-specific PSU status interface for SONiC +# + + +import os.path +import logging + +try: + from sonic_psu.psu_base import PsuBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class PsuUtil(PsuBase): + """Platform-specific PSUutil class""" + + SYSFS_PSU_DIR = ["/sys/bus/i2c/devices/5-005a", + "/sys/bus/i2c/devices/5-005b"] + + def __init__(self): + PsuBase.__init__(self) + + + # Get sysfs attribute + def get_attr_value(self, attr_path): + + retval = 'ERR' + if (not os.path.isfile(attr_path)): + return retval + + try: + with open(attr_path, 'r') as fd: + retval = fd.read() + except Exception as error: + logging.error("Unable to open %s file !", attr_path) + + retval = retval.rstrip('\r\n') + return retval + + def get_num_psus(self): + """ + Retrieves the number of PSUs available on the device + :return: An integer, the number of PSUs available on the device + """ + MAX_PSUS = 2 + return MAX_PSUS + + def get_psu_status(self, index): + """ + Retrieves the oprational status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is operating properly, False if PSU is\ + faulty + """ + status = 0 + attr_file = 'psu_power_good' + attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file + + attr_value = self.get_attr_value(attr_path) + + if (attr_value != 'ERR'): + attr_value = int(attr_value, 16) + # Check for PSU status + if (attr_value == 1): + status = 1 + + return status + + def get_psu_presence(self, index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + status = 0 + psu_absent = 0 + attr_file ='psu_present' + attr_path = self.SYSFS_PSU_DIR[index-1] +'/' + attr_file + + attr_value = self.get_attr_value(attr_path) + + if (attr_value != 'ERR'): + attr_value = int(attr_value, 16) + # Check for PSU presence + if (attr_value == 1): + status = 1 + + return status + diff --git a/device/cig/x86_64-cig_cs6436_54p-r0/plugins/sfputil.py b/device/cig/x86_64-cig_cs6436_54p-r0/plugins/sfputil.py new file mode 100755 index 000000000000..2863b80c9950 --- /dev/null +++ b/device/cig/x86_64-cig_cs6436_54p-r0/plugins/sfputil.py @@ -0,0 +1,250 @@ +#!/usr/bin/env python + +try: + import time + from sonic_sfp.sfputilbase import SfpUtilBase +except ImportError, e: + raise ImportError (str(e) + "- required module not found") + + +class SfpUtil(SfpUtilBase): + """Platform specific SfpUtill class""" + + _port_start = 1 + _port_end = 54 + _qsfp_port_start = 49 + _ports_in_block = 54 + + _port_to_eeprom_mapping = {} + _global_port_pres_dict = {} + + _port_to_i2c_mapping = { + 1 : 8, + 2 : 9, + 3 : 10, + 4 : 11, + 5 : 12, + 6 : 13, + 7 : 14, + 8 : 15, + 9 : 16, + 10: 17, + 11 : 18, + 12 : 19, + 13 : 20, + 14 : 21, + 15 : 22, + 16 : 23, + 17 : 24, + 18 : 25, + 19 : 26, + 20 : 27, + 21 : 28, + 22 : 29, + 23 : 30, + 24 : 31, + 25 : 32, + 26 : 33, + 27 : 34, + 28 : 35, + 29 : 36, + 30 : 37, + 31 : 38, + 32 : 39, + 33 : 40, + 34 : 41, + 35 : 42, + 36 : 43, + 37 : 44, + 38 : 45, + 39 : 46, + 40 : 47, + 41 : 48, + 42 : 49, + 43 : 50, + 44 : 51, + 45 : 52, + 46 : 53, + 47 : 54, + 48 : 55, + 49 : 56, + 50 : 57, + 51 : 60, + 52 : 61, + 53 : 62, + 54 : 63, + } + + _qsfp_ports = range(_qsfp_port_start, _ports_in_block + 1) + + def get_presence(self, port_num): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + + path = "/sys/bus/i2c/devices/{0}-0050/sfp_is_present" + port_ps = path.format(self._port_to_i2c_mapping[port_num]) + + + try: + reg_file = open(port_ps) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + try: + reg_value = reg_file.readline().rstrip() + except IOError as e: + time.sleep(1) + + try: + reg_value = reg_file.readline().rstrip() + except IOError as e: + print "Error:try again to read file failed: %s %s" % (str(e), port_ps) + reg_file.close() + return False + + reg_file.close() + if reg_value == '1': + return True + + reg_file.close() + if reg_value == '1': + return True + + return False + + def init_global_port_presence(self): + for port_num in range(self.port_start, (self.port_end + 1)): + self._global_port_pres_dict[port_num] = '0' + + + def __init__(self): + eeprom_path = '/sys/bus/i2c/devices/{0}-0050/sfp_eeprom' + for x in range(self._port_start, self._port_end + 1): + port_eeprom_path = eeprom_path.format(self._port_to_i2c_mapping[x]) + self._port_to_eeprom_mapping[x] = port_eeprom_path + + self.init_global_port_presence() + SfpUtilBase.__init__(self) + + def reset(self, port_num): + # Check for invalid port_num + if port_num < self._port_start or port_num > self._port_end: + return False + + path = "/sys/bus/i2c/devices/{0}-0050/sfp_port_reset" + port_ps = path.format(self._port_to_i2c_mapping[port_num]) + + try: + reg_file = open(port_ps, 'w') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + #toggle reset + reg_file.seek(0) + reg_file.write('1') + time.sleep(1) + reg_file.seek(0) + reg_file.write('0') + reg_file.close() + return True + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + if port_num < self._qsfp_port_start or port_num > self._port_end: + return False + + pre_value = self.get_presence(port_num) + if pre_value == False: + return False + + path = "/sys/bus/i2c/devices/{0}-0050/sfp_lpmode" + port_ps = path.format(self._port_to_i2c_mapping[port_num]) + + try: + reg_file = open(port_ps,'w') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_file.seek(0) + + if lpmode == 1: + reg_file.write('1') + elif lpmode == 0: + reg_file.write('0') + reg_file.close() + + return True + + + def get_low_power_mode(self, port_num): + # Check for invalid port_num + + if port_num < self._qsfp_port_start or port_num > self._port_end: + return False + + pre_value = self.get_presence(port_num) + if pre_value == False: + return False + + path = "/sys/bus/i2c/devices/{0}-0050/sfp_lpmode" + port_ps = path.format(self._port_to_i2c_mapping[port_num]) + + try: + reg_file = open(port_ps) + except IOError as e: + print "Error: unable to open file:%s %s" % (str(e), port_ps) + return False + + try: + reg_value = reg_file.readline().rstrip() + except IOError as e: + print "Error: unable to open file:%s %s" % (str(e), port_ps) + reg_file.close() + return False + + reg_file.close() + + if reg_value == '1': + return True + + return False + + def get_transceiver_change_event(self): + port_dict = {} + while True: + for port_num in range(self.port_start, (self.port_end + 1)): + presence = self.get_presence(port_num) + + if(presence and self._global_port_pres_dict[port_num] == '0'): + self._global_port_pres_dict[port_num] = '1' + port_dict[port_num] = '1' + elif(not presence and + self._global_port_pres_dict[port_num] == '1'): + self._global_port_pres_dict[port_num] = '0' + port_dict[port_num] = '0' + + if(len(port_dict) > 0): + return True, port_dict + + time.sleep(0.5) + + + @property + def port_start(self): + return self._port_start + + @property + def port_end(self): + return self._port_end + + @property + def qsfp_ports(self): + return self._qsfp_ports + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping diff --git a/device/cig/x86_64-cig_cs6436_54p-r0/sensors.conf b/device/cig/x86_64-cig_cs6436_54p-r0/sensors.conf new file mode 100644 index 000000000000..22cd3ccda958 --- /dev/null +++ b/device/cig/x86_64-cig_cs6436_54p-r0/sensors.conf @@ -0,0 +1,13 @@ +# libsensors configuration file + +chip "cs6436_54p_fan-*" + label fan1 "front fan 1" + label fan2 "front fan 2" + label fan3 "front fan 3" + label fan4 "front fan 4" + label fan5 "front fan 5" + label fan6 "rear fan 1" + label fan7 "rear fan 2" + label fan8 "rear fan 3" + label fan9 "rear fan 4" + label fan10 "rear fan 5" diff --git a/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/buffers.json.j2 b/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/buffers.json.j2 old mode 100755 new mode 100644 diff --git a/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/led.bin b/device/cig/x86_64-cig_cs6436_56p-r0/Cig-CS6436-56P/led.bin new file mode 100644 index 0000000000000000000000000000000000000000..8b3490ca3b7c9f2a0b934b770a56d512277844c0 GIT binary patch literal 652 zcmWN`$uk0Q7{}qC8Dp4HN(*sK%2r9)3gv2vwBQ;p(j~cA{&mmco#*||Clo>mb0Hkg zyI2S{)>vhg2Rz^@PkF)<9`l$-JmNXedB!s~*kGM?Uh4R3hOYhLk+GqWKi{0aXuml self._port_end: + return False + path = "/sys/bus/i2c/devices/{0}-0050/sfp_is_present" + port_ps = path.format(self._port_to_i2c_mapping[port_num]) + + + try: + reg_file = open(port_ps) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + try: + reg_value = reg_file.readline().rstrip() + except IOError as e: + time.sleep(1) + + try: + reg_value = reg_file.readline().rstrip() + except IOError as e: + print "Error:try again to read file failed: %s %s" % (str(e), port_ps) + reg_file.close() + return False + + reg_file.close() + if reg_value == '1': + return True + + reg_file.close() + if reg_value == '1': + return True + + return False + + def init_global_port_presence(self): + for port_num in range(self.port_start, (self.port_end + 1)): + self._global_port_pres_dict[port_num] = '0' + + def __init__(self): eeprom_path = '/sys/bus/i2c/devices/{0}-0050/sfp_eeprom' for x in range(self._port_start, self._port_end + 1): port_eeprom_path = eeprom_path.format(self._port_to_i2c_mapping[x]) self._port_to_eeprom_mapping[x] = port_eeprom_path - - SfpUtilBase.__init__(self) + + self.init_global_port_presence() + SfpUtilBase.__init__(self) def reset(self, port_num): # Check for invalid port_num @@ -107,41 +152,88 @@ def reset(self, port_num): reg_file.write('0') reg_file.close() return True + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid port_num + if port_num < self._qsfp_port_start or port_num > self._port_end: + return False + + pre_value = self.get_presence(port_num) + if pre_value == False: + return False + + path = "/sys/bus/i2c/devices/{0}-0050/sfp_lpmode" + port_ps = path.format(self._port_to_i2c_mapping[port_num]) + + try: + reg_file = open(port_ps,'w') + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_file.seek(0) + + if lpmode == 1: + reg_file.write('1') + elif lpmode == 0: + reg_file.write('0') + reg_file.close() + + return True - def set_low_power_mode(self, port_nuM, lpmode): - raise NotImplementedError def get_low_power_mode(self, port_num): - raise NotImplementedError - - def get_presence(self, port_num): # Check for invalid port_num - if port_num < self._port_start or port_num > self._port_end: - return False - path = "/sys/bus/i2c/devices/{0}-0050/sfp_is_present" + if port_num < self._qsfp_port_start or port_num > self._port_end: + return False + + pre_value = self.get_presence(port_num) + if pre_value == False: + return False + + path = "/sys/bus/i2c/devices/{0}-0050/sfp_lpmode" port_ps = path.format(self._port_to_i2c_mapping[port_num]) - try: reg_file = open(port_ps) except IOError as e: - print "Error: unable to open file: %s" % str(e) + print "Error: unable to open file:%s %s" % (str(e), port_ps) + return False + + try: + reg_value = reg_file.readline().rstrip() + except IOError as e: + print "Error: unable to open file:%s %s" % (str(e), port_ps) + reg_file.close() return False + + reg_file.close() - reg_value = reg_file.readline().rstrip() if reg_value == '1': return True return False - + def get_transceiver_change_event(self): - """ - TODO: This function need to be implemented - when decide to support monitoring SFP(Xcvrd) - on this platform. - """ - raise NotImplementedError + port_dict = {} + while True: + for port_num in range(self.port_start, (self.port_end + 1)): + presence = self.get_presence(port_num) + + if(presence and self._global_port_pres_dict[port_num] == '0'): + self._global_port_pres_dict[port_num] = '1' + port_dict[port_num] = '1' + elif(not presence and + self._global_port_pres_dict[port_num] == '1'): + self._global_port_pres_dict[port_num] = '0' + port_dict[port_num] = '0' + + if(len(port_dict) > 0): + return True, port_dict + + time.sleep(0.5) + @property def port_start(self): diff --git a/device/cig/x86_64-cig_cs6436_56p-r0/sensors.conf b/device/cig/x86_64-cig_cs6436_56p-r0/sensors.conf old mode 100755 new mode 100644 diff --git a/platform/nephos/one-image.mk b/platform/nephos/one-image.mk index 3651325456c7..60254051c5b5 100644 --- a/platform/nephos/one-image.mk +++ b/platform/nephos/one-image.mk @@ -8,7 +8,10 @@ $(SONIC_ONE_IMAGE)_INSTALLS += $(SYSTEMD_SONIC_GENERATOR) $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(INGRASYS_S9130_32X_PLATFORM_MODULE) \ $(INGRASYS_S9230_64X_PLATFORM_MODULE) \ $(ACCTON_AS7116_54X_PLATFORM_MODULE) \ - $(CIG_CS6436_56P_PLATFORM_MODULE) + $(CIG_CS6436_56P_PLATFORM_MODULE) \ + $(CIG_CS6436_54P_PLATFORM_MODULE) \ + $(CIG_CS5435_54P_PLATFORM_MODULE) + ifeq ($(INSTALL_DEBUG_TOOLS),y) $(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_DBG_IMAGES) $(SONIC_ONE_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.gz, $(SONIC_INSTALL_DOCKER_DBG_IMAGES)), $(SONIC_INSTALL_DOCKER_IMAGES)) diff --git a/platform/nephos/platform-modules-cig.mk b/platform/nephos/platform-modules-cig.mk index 98bbadf9ce3c..5cccf1692550 100644 --- a/platform/nephos/platform-modules-cig.mk +++ b/platform/nephos/platform-modules-cig.mk @@ -1,12 +1,26 @@ -# Cig CS6436 56P Platform modules +# Cig Nephos Switch Platform modules -CIG_CS6436_56P_PLATFORM_MODULE_VERSION = 1.0.0 +CIG_MTK_PLATFORM_MODULE_VERSION = 1.0.0 -export CIG_CS6436_56P_PLATFORM_MODULE_VERSION +export CIG_MTK_PLATFORM_MODULE_VERSION -CIG_CS6436_56P_PLATFORM_MODULE = sonic-platform-cig-cs6436-56p_$(CIG_CS6436_56P_PLATFORM_MODULE_VERSION)_amd64.deb +CIG_CS6436_56P_PLATFORM_MODULE = sonic-platform-cig-cs6436-56p_$(CIG_MTK_PLATFORM_MODULE_VERSION)_amd64.deb $(CIG_CS6436_56P_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-cig $(CIG_CS6436_56P_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) $(CIG_CS6436_56P_PLATFORM_MODULE)_PLATFORM = x86_64-cig_cs6436_56p-r0 SONIC_DPKG_DEBS += $(CIG_CS6436_56P_PLATFORM_MODULE) -SONIC_STRETCH_DEBS += $(CIG_CS6436_56P_PLATFORM_MODULE) \ No newline at end of file +SONIC_STRETCH_DEBS += $(CIG_CS6436_56P_PLATFORM_MODULE) + +CIG_CS6436_54P_PLATFORM_MODULE = sonic-platform-cig-cs6436-54p_$(CIG_MTK_PLATFORM_MODULE_VERSION)_amd64.deb +$(CIG_CS6436_54P_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-cig +$(CIG_CS6436_54P_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) +$(CIG_CS6436_54P_PLATFORM_MODULE)_PLATFORM = x86_64-cig_cs6436_54p-r0 +SONIC_DPKG_DEBS += $(CIG_CS6436_54P_PLATFORM_MODULE) +SONIC_STRETCH_DEBS += $(CIG_CS6436_54P_PLATFORM_MODULE) + +CIG_CS5435_54P_PLATFORM_MODULE = sonic-platform-cig-cs5435-54p_$(CIG_MTK_PLATFORM_MODULE_VERSION)_amd64.deb +$(CIG_CS5435_54P_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-cig +$(CIG_CS5435_54P_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) +$(CIG_CS5435_54P_PLATFORM_MODULE)_PLATFORM = x86_64-cig_cs5435_54p-r0 +SONIC_DPKG_DEBS += $(CIG_CS5435_54P_PLATFORM_MODULE) +SONIC_STRETCH_DEBS += $(CIG_CS5435_54P_PLATFORM_MODULE) diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/classes/__init__.py b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/classes/__init__.py new file mode 100755 index 000000000000..e69de29bb2d1 diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/classes/fanutil.py b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/classes/fanutil.py new file mode 100755 index 000000000000..e69de29bb2d1 diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/classes/thermalutil.py b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/classes/thermalutil.py new file mode 100755 index 000000000000..e69de29bb2d1 diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/Makefile b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/Makefile new file mode 100644 index 000000000000..446fde4b0a70 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/Makefile @@ -0,0 +1,6 @@ +obj-m :=x86-64-cig-cs5435-54p-sysfs.o \ + x86-64-cig-cs5435-54p-cpld.o \ + x86-64-cig-cs5435-54p-fan.o \ + x86-64-cig-cs5435-54p-led.o \ + x86-64-cig-cs5435-54p-psu.o \ + x86-64-cig-cs5435-54p-sfp.o diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/i2c-algo-lpc.h b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/i2c-algo-lpc.h new file mode 100644 index 000000000000..dc9e30d16ddd --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/i2c-algo-lpc.h @@ -0,0 +1,222 @@ +/* -------------------------------------------------------------------- + + * A hwmon driver for the CIG cs5435-54P + * + * Copyright (C) 2018 Cambridge, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 I2C_LPC_H +#define I2C_LPC_H 1 + +/* ----- Control register bits ---------------------------------------- */ +#define I2C_LPC_PIN 0x80 +#define I2C_LPC_ESO 0x40 +#define I2C_LPC_ES1 0x20 +#define I2C_LPC_ES2 0x10 +#define I2C_LPC_ENI 0x08 + +#define I2C_LPC_STO 0x40 +#define I2C_LPC_ACK 0x01 + +/*command register*/ +#define I2C_LPC_STA 0x80 +#define I2C_LPC_ABT 0x40 + +/*status register*/ +#define I2C_LPC_TBE 0x02 +#define I2C_LPC_IBB 0x80 +#define I2C_LPC_RBF 0x01 +#define I2C_LPC_TD 0x08 + +#define I2C_LPC_START I2C_LPC_STA +#define I2C_LPC_STOP I2C_LPC_STO +#define I2C_LPC_REPSTART I2C_LPC_STA +#define I2C_LPC_IDLE + +/* ----- Status register bits ----------------------------------------- */ +/*#define I2C_LPC_PIN 0x80 as above*/ + +#define I2C_LPC_INI 0x40 /* 1 if not initialized */ +#define I2C_LPC_STS 0x20 +#define I2C_LPC_BER 0x10 +#define I2C_LPC_AD0 0x08 +#define I2C_LPC_LRB 0x08 +#define I2C_LPC_AAS 0x04 +#define I2C_LPC_LAB 0x02 +#define I2C_LPC_BB 0x80 + +/* ----- Chip clock frequencies --------------------------------------- */ +#define I2C_LPC_CLK3 0x00 +#define I2C_LPC_CLK443 0x10 +#define I2C_LPC_CLK6 0x14 +#define I2C_LPC_CLK 0x18 +#define I2C_LPC_CLK12 0x1c + +/* ----- transmission frequencies ------------------------------------- */ +#define I2C_LPC_TRNS90 0x00 /* 90 kHz */ +#define I2C_LPC_TRNS45 0x01 /* 45 kHz */ +#define I2C_LPC_TRNS11 0x02 /* 11 kHz */ +#define I2C_LPC_TRNS15 0x03 /* 1.5 kHz */ + + +#define I2C_LPC_OWNADR 0 +#define I2C_LPC_INTREG I2C_LPC_ES2 +#define I2C_LPC_CLKREG I2C_LPC_ES1 + +#define I2C_LPC_REG_TEST 0x01 +#define I2C_LPC_REG_BUS_SEL 0x80 +#define I2C_LPC_REG_DEVICE_ADDR 0x81 +#define I2C_LPC_REG_BYTE_COUNT 0x83 +#define I2C_LPC_REG_COMMAND 0x84 +#define I2C_LPC_REG_STATUS 0x85 +#define I2C_LPC_REG_DATA_RX1 0x86 +#define I2C_LPC_REG_DATA_RX2 0x87 +#define I2C_LPC_REG_DATA_RX3 0x88 +#define I2C_LPC_REG_DATA_RX4 0x89 +#define I2C_LPC_REG_DATA_TX1 0x8a +#define I2C_LPC_REG_DATA_TX2 0x8b +#define I2C_LPC_REG_DATA_TX3 0x8c +#define I2C_LPC_REG_DATA_TX4 0x8d + + +#define ADDR_REG_SFP_STATUS_ADDR 0X62 //reg addr +R/W# //1031 +#define ADDR_REG_SFP_STATUS_TX 0X63 // write data +#define ADDR_REG_SFP_STATUS_RX 0X64 //read data +#define ADDR_REG_SFP_STATUS_COMMAND 0X65 //cmd bit7=1,go +#define ADDR_REG_SFP_STATUS_STATUS 0X66 //status + +#define CPLD_MASTER_INTERRUPT_STATUS_REG 0x20 +#define CPLD_MASTER_INTERRUPT_MASK_REG 0x21 +#define CPLD_MASTER_INTERRUPT_ALL 0x3f +#define CPLD_MASTER_INTERRUPT_CPLD2 0x20 +#define CPLD_MASTER_INTERRUPT_CPLD1 0x10 +#define CPLD_MASTER_INTERRUPT_PSU2 0x08 +#define CPLD_MASTER_INTERRUPT_PSU1 0x04 +#define CPLD_MASTER_INTERRUPT_6320 0x02 +#define CPLD_MASTER_INTERRUPT_LSW 0x01 + + + +#define CPLD_SLAVE1_INTERRUPT_STATUS_L_REG 0x20 +#define CPLD_SLAVE1_INTERRUPT_STATUS_H_REG 0x21 +#define CPLD_SLAVE2_INTERRUPT_STATUS_L_REG 0x22 +#define CPLD_SLAVE2_INTERRUPT_STATUS_H_REG 0x23 +#define CPLD_SLAVE1_INTERRUPT_MASK_REG 0x24 +#define CPLD_SLAVE2_INTERRUPT_MASK_REG 0x25 + + +#define CPLD_SLAVE1_PRESENT08_REG 0x01 +#define CPLD_SLAVE1_PRESENT16_REG 0x02 +#define CPLD_SLAVE1_PRESENT24_REG 0x03 +#define CPLD_SLAVE2_PRESENT32_REG 0x04 +#define CPLD_SLAVE2_PRESENT40_REG 0x05 +#define CPLD_SLAVE2_PRESENT48_REG 0x06 + +#define CPLD_SLAVE1_RX_LOST08_REG 0x07 +#define CPLD_SLAVE1_RX_LOST16_REG 0x08 +#define CPLD_SLAVE1_RX_LOST24_REG 0x09 +#define CPLD_SLAVE2_RX_LOST32_REG 0x0a +#define CPLD_SLAVE2_RX_LOST40_REG 0x0b +#define CPLD_SLAVE2_RX_LOST48_REG 0x0c + +#define CPLD_SLAVE1_TX_FAULT08_REG 0x0d +#define CPLD_SLAVE1_TX_FAULT16_REG 0x0e +#define CPLD_SLAVE1_TX_FAULT24_REG 0x0f +#define CPLD_SLAVE2_TX_FAULT32_REG 0x10 +#define CPLD_SLAVE2_TX_FAULT40_REG 0x11 +#define CPLD_SLAVE2_TX_FAULT48_REG 0x12 + +#define CPLD_SLAVE2_PRESENT56_REG 0x19 +#define CPLD_SLAVE2_QSFP_CR56_REG 0x1a + + +#define CPLD_SLAVE1_INTERRUPT_PRESENT08 0x0001 +#define CPLD_SLAVE1_INTERRUPT_PRESENT16 0x0002 +#define CPLD_SLAVE1_INTERRUPT_PRESENT24 0x0004 +#define CPLD_SLAVE2_INTERRUPT_PRESENT32 0x0001 +#define CPLD_SLAVE2_INTERRUPT_PRESENT40 0x0002 +#define CPLD_SLAVE2_INTERRUPT_PRESENT48 0x0004 + +#define CPLD_SLAVE2_INTERRUPT_QSFP_CR56 0x0200 +#define CPLD_SLAVE2_INTERRUPT_PRESENT56 0x0400 + +#define CPLD_SLAVE1_INTERRUPT_RX_LOST08 0x0008 +#define CPLD_SLAVE1_INTERRUPT_RX_LOST16 0x0010 +#define CPLD_SLAVE1_INTERRUPT_RX_LOST24 0x0020 +#define CPLD_SLAVE2_INTERRUPT_RX_LOST32 0x0008 +#define CPLD_SLAVE2_INTERRUPT_RX_LOST40 0x0010 +#define CPLD_SLAVE2_INTERRUPT_RX_LOST48 0x0020 + +#define CPLD_SLAVE1_INTERRUPT_TX_FAULT08 0x0040 +#define CPLD_SLAVE1_INTERRUPT_TX_FAULT16 0x0080 +#define CPLD_SLAVE1_INTERRUPT_TX_FAULT24 0x0100 +#define CPLD_SLAVE2_INTERRUPT_TX_FAULT32 0x0040 +#define CPLD_SLAVE2_INTERRUPT_TX_FAULT40 0x0080 +#define CPLD_SLAVE2_INTERRUPT_TX_FAULT48 0x0100 + + + + + + + +#define WAIT_TIME_OUT_COUNT 100 + + +struct i2c_algo_lpc_data { + void *data; /* private data for lolevel routines */ + void (*setlpc) (void *data, int ctl, int val); + int (*getlpc) (void *data, int ctl); + int (*getown) (void *data); + int (*getclock) (void *data); + void (*waitforpin) (void *data); + + int (*xfer_begin) (void *data); + int (*xfer_end) (void *data); + + /* Multi-master lost arbitration back-off delay (msecs) + * This should be set by the bus adapter or knowledgable client + * if bus is multi-mastered, else zero + */ + unsigned long lab_mdelay; +}; + + +struct subsys_private { + struct kset subsys; + struct kset *devices_kset; + struct list_head interfaces; + struct mutex mutex; + + struct kset *drivers_kset; + struct klist klist_devices; + struct klist klist_drivers; + struct blocking_notifier_head bus_notifier; + unsigned int drivers_autoprobe:1; + struct bus_type *bus; + + struct kset glue_dirs; + struct class *class; +}; + +void cs5435_54p_sysfs_add_client(struct i2c_client *client); +void cs5435_54p_sysfs_remove_client(struct i2c_client *client); + + +#endif /* I2C_LPC8584_H */ diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-cpld.c b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-cpld.c new file mode 100644 index 000000000000..68f1192e58b1 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-cpld.c @@ -0,0 +1,2209 @@ +/* + * A hwmon driver for the CIG cs5435-54P CPLD + * + * Copyright (C) 2018 Cambridge, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 "i2c-algo-lpc.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef CPLD_USER +# include +#else +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + + + + + +/********************************************** Start ********************************************************/ + +/* + * ISA bus. + */ + +static void platform_isa_bus_release(struct device * dev) +{ + return ; +} + + +static struct device isa_bus = { + .init_name = "lpc-isa", + .release = platform_isa_bus_release, +}; + +struct isa_dev { + struct device dev; + struct device *next; + unsigned int id; +}; + +#define to_isa_dev(x) container_of((x), struct isa_dev, dev) + +static int isa_bus_match(struct device *dev, struct device_driver *driver) +{ + struct isa_driver *isa_driver = to_isa_driver(driver); + + if (dev->platform_data == isa_driver) { + if (!isa_driver->match || + isa_driver->match(dev, to_isa_dev(dev)->id)) + return 1; + dev->platform_data = NULL; + } + return 0; +} + +static int isa_bus_probe(struct device *dev) +{ + struct isa_driver *isa_driver = dev->platform_data; + + if (isa_driver->probe) + return isa_driver->probe(dev, to_isa_dev(dev)->id); + + return 0; +} + +static int isa_bus_remove(struct device *dev) +{ + struct isa_driver *isa_driver = dev->platform_data; + + if (isa_driver->remove) + return isa_driver->remove(dev, to_isa_dev(dev)->id); + + return 0; +} + +static void isa_bus_shutdown(struct device *dev) +{ + struct isa_driver *isa_driver = dev->platform_data; + + if (isa_driver->shutdown) + isa_driver->shutdown(dev, to_isa_dev(dev)->id); +} + +static int isa_bus_suspend(struct device *dev, pm_message_t state) +{ + struct isa_driver *isa_driver = dev->platform_data; + + if (isa_driver->suspend) + return isa_driver->suspend(dev, to_isa_dev(dev)->id, state); + + return 0; +} + +static int isa_bus_resume(struct device *dev) +{ + struct isa_driver *isa_driver = dev->platform_data; + + if (isa_driver->resume) + return isa_driver->resume(dev, to_isa_dev(dev)->id); + + return 0; +} + +static struct bus_type isa_bus_type = { + .name = "lpc-isa", + .match = isa_bus_match, + .probe = isa_bus_probe, + .remove = isa_bus_remove, + .shutdown = isa_bus_shutdown, + .suspend = isa_bus_suspend, + .resume = isa_bus_resume +}; + +static void isa_dev_release(struct device *dev) +{ + kfree(to_isa_dev(dev)); +} + +void lpc_unregister_driver(struct isa_driver *isa_driver) +{ + struct device *dev = isa_driver->devices; + + while (dev) { + struct device *tmp = to_isa_dev(dev)->next; + device_unregister(dev); + dev = tmp; + } + driver_unregister(&isa_driver->driver); +} + + +int lpc_register_driver(struct isa_driver *isa_driver, unsigned int ndev) +{ + int error; + unsigned int id; + + isa_driver->driver.bus = &isa_bus_type; + isa_driver->devices = NULL; + + error = driver_register(&isa_driver->driver); + if (error) + return error; + + for (id = 0; id < ndev; id++) { + struct isa_dev *isa_dev; + + isa_dev = kzalloc(sizeof *isa_dev, GFP_KERNEL); + if (!isa_dev) { + error = -ENOMEM; + break; + } + + isa_dev->dev.parent = &isa_bus; + isa_dev->dev.bus = &isa_bus_type; + + dev_set_name(&isa_dev->dev, "%s.%u", + isa_driver->driver.name, id); + isa_dev->dev.platform_data = isa_driver; + isa_dev->dev.release = isa_dev_release; + isa_dev->id = id; + + isa_dev->dev.coherent_dma_mask = DMA_BIT_MASK(24); + isa_dev->dev.dma_mask = &isa_dev->dev.coherent_dma_mask; + + error = device_register(&isa_dev->dev); + if (error) { + put_device(&isa_dev->dev); + break; + } + + if (isa_dev->dev.platform_data) { + isa_dev->next = isa_driver->devices; + isa_driver->devices = &isa_dev->dev; + } else + device_unregister(&isa_dev->dev); + } + + if (!error && !isa_driver->devices) + error = -ENODEV; + + if (error) + isa_unregister_driver(isa_driver); + + return error; +} + + +int lpc_bus_init(void) +{ + int error; + + error = bus_register(&isa_bus_type); + if (!error) { + error = device_register(&isa_bus); + if (error) + bus_unregister(&isa_bus_type); + } + return error; +} + +void lpc_bus_exit(void) +{ + + device_unregister(&isa_bus); + + bus_unregister(&isa_bus_type); +} + + +/********************************************** End ********************************************************/ + + + + + + +/********************************************** Start ********************************************************/ +/* + * module parameters: + */ +static int i2c_debug = 0; +static struct mutex lpc_lock; + + +#define DEB2(x) if (i2c_debug == 2) x +#define DEB3(x) if (i2c_debug == 3) x + /* print several statistical values */ +#define DEBPROTO(x) if (i2c_debug == 9) x; + /* debug the protocol by showing transferred bits */ +#define DEF_TIMEOUT 160 + + + +/* setting states on the bus with the right timing: */ + +#define set_lpc(adap, ctl, val) adap->setlpc(adap->data, ctl, val) +#define get_lpc(adap, ctl) adap->getlpc(adap->data, ctl) +#define get_own(adap) adap->getown(adap->data) +#define get_clock(adap) adap->getclock(adap->data) +#define i2c_outaddr(adap, val) adap->setlpc(adap->data, I2C_LPC_REG_DEVICE_ADDR, val) + +#define i2c_outbyte1(adap, val) adap->setlpc(adap->data, I2C_LPC_REG_DATA_TX1, val) +#define i2c_outbyte2(adap, val) adap->setlpc(adap->data, I2C_LPC_REG_DATA_TX2, val) +#define i2c_outbyte3(adap, val) adap->setlpc(adap->data, I2C_LPC_REG_DATA_TX3, val) +#define i2c_outbyte4(adap, val) adap->setlpc(adap->data, I2C_LPC_REG_DATA_TX4, val) +#define i2c_inbyte1(adap) adap->getlpc(adap->data, I2C_LPC_REG_DATA_RX1) +#define i2c_inbyte2(adap) adap->getlpc(adap->data, I2C_LPC_REG_DATA_RX2) +#define i2c_inbyte3(adap) adap->getlpc(adap->data, I2C_LPC_REG_DATA_RX3) +#define i2c_inbyte4(adap) adap->getlpc(adap->data, I2C_LPC_REG_DATA_RX4) + + + +#define LPC_FPRINTF_LOG_PATH "/tmp/file.log" +struct file *lpc_fprintf_file = NULL; + +static int lpc_fprintf_debug(const char *fmt, ...) +{ + char lpc_fprintf_buf[256]={0}; + struct va_format vaf; + va_list args; + int r; + mm_segment_t old_fs; + struct timeval tv; + struct rtc_time tm; + + do_gettimeofday(&tv); + + rtc_time_to_tm(tv.tv_sec,&tm); + + va_start(args, fmt); + vaf.fmt = fmt; + vaf.va = &args; + r=snprintf(lpc_fprintf_buf,sizeof(lpc_fprintf_buf),"[%04d.%08d] %pV\n",tm.tm_sec, (int)tv.tv_usec, &vaf); + va_end(args); + old_fs = get_fs(); + set_fs(KERNEL_DS); + vfs_write(lpc_fprintf_file, (char *)&lpc_fprintf_buf, strlen(lpc_fprintf_buf), &lpc_fprintf_file->f_pos); + set_fs(old_fs); + memset(lpc_fprintf_buf,0x0,sizeof(lpc_fprintf_buf)); + return r; + +} + + + +static int lpc_fprintf_init(void) +{ + printk("lpc_fprintf_init.\n"); + + if(lpc_fprintf_file == NULL) + lpc_fprintf_file = filp_open(LPC_FPRINTF_LOG_PATH, O_RDWR | O_APPEND | O_CREAT, 0644); + + if (IS_ERR(lpc_fprintf_file)) { + printk("Error occured while opening file %s, exiting...\n", LPC_FPRINTF_LOG_PATH); + return -1; + } + + return 0; +} + +static int lpc_fprintf_exit(void) +{ + printk("lpc_fprintf_exit.\n"); + + if(lpc_fprintf_file != NULL) + filp_close(lpc_fprintf_file, NULL); + + return 0; +} + + +/* other auxiliary functions */ + + +void print_reg(struct i2c_algo_lpc_data *adap) +{ + unsigned char status; + DEBPROTO(lpc_fprintf_debug("================================================\n");) + status = get_lpc(adap, I2C_LPC_REG_BUS_SEL); + DEBPROTO(lpc_fprintf_debug("%s select reg %x : %x\n",__func__,I2C_LPC_REG_BUS_SEL, status);) + status = get_lpc(adap, I2C_LPC_REG_BYTE_COUNT); + DEBPROTO(lpc_fprintf_debug("%s count reg %x : %x\n",__func__,I2C_LPC_REG_BYTE_COUNT, status);) + + status = get_lpc(adap, I2C_LPC_REG_COMMAND); + DEBPROTO(lpc_fprintf_debug("%s command reg %x : %x\n",__func__,I2C_LPC_REG_COMMAND, status);) + status = get_lpc(adap, I2C_LPC_REG_DEVICE_ADDR); + DEBPROTO(lpc_fprintf_debug("%s address reg %x : %x\n",__func__,I2C_LPC_REG_DEVICE_ADDR, status);) + + status = get_lpc(adap, I2C_LPC_REG_STATUS); + DEBPROTO(lpc_fprintf_debug("%s status reg %x : %x\n",__func__,I2C_LPC_REG_STATUS, status);) +} + + + +static void i2c_repstart(struct i2c_algo_lpc_data *adap) +{ + DEBPROTO(lpc_fprintf_debug("%s :\n",__func__);) + set_lpc(adap, I2C_LPC_REG_COMMAND, I2C_LPC_REPSTART); +} + +static void i2c_stop(struct i2c_algo_lpc_data *adap) +{ + DEBPROTO(lpc_fprintf_debug("%s :\n",__func__);) + set_lpc(adap, I2C_LPC_REG_COMMAND, I2C_LPC_STOP); + udelay(60); + set_lpc(adap, I2C_LPC_REG_COMMAND, 0x00); +} + + + + +static void i2c_start(struct i2c_algo_lpc_data *adap) +{ + print_reg(adap); + + set_lpc(adap, I2C_LPC_REG_COMMAND, I2C_LPC_START); + + print_reg(adap); +} + + + + +static int wait_for_bb(struct i2c_algo_lpc_data *adap) +{ + + int timeout = DEF_TIMEOUT; + int status; + + while (--timeout) { + status = get_lpc(adap, I2C_LPC_REG_STATUS); + + DEBPROTO(lpc_fprintf_debug("%s : Waiting for bus free status : %x\n",__func__,status);) + + if(status == I2C_LPC_TD) + { + DEBPROTO(lpc_fprintf_debug("%s : Bus is free status : %x\n",__func__,status);) + break; + } + } + + if (timeout == 0) { + DEBPROTO(lpc_fprintf_debug("%s : Timeout for free busy status : %x\n",__func__,status);) + return -ETIMEDOUT; + } + + + + return 0; +} + + +static int wait_for_be(int mode,struct i2c_algo_lpc_data *adap) +{ + + int timeout = DEF_TIMEOUT; + unsigned char status; + + + while (--timeout) { + + status = get_lpc(adap, I2C_LPC_REG_STATUS); + + DEBPROTO(lpc_fprintf_debug("%s : Waiting for bus empty status : %x\n",__func__,status);) + + if(mode == 1) + { + if((status & I2C_LPC_IBB) && (status & I2C_LPC_TBE)) + { + DEBPROTO(lpc_fprintf_debug("%s : Bus is empty status : %x\n",__func__,status);) + break; + } + } + else + { + if(status & I2C_LPC_TD) + { + DEBPROTO(lpc_fprintf_debug("%s : Bus is empty status : %x\n",__func__,status);) + break; + } + } + + status = get_lpc(adap, I2C_LPC_REG_TEST); + + DEBPROTO(lpc_fprintf_debug("%s : The test register data : %x\n",__func__,status);) + udelay(1); /* wait for 100 us */ + } + + if (timeout == 0) { + DEBPROTO(lpc_fprintf_debug("%s : Timeout waiting for Bus Empty\n",__func__);) + return -ETIMEDOUT; + } + + return 0; +} + + +static int wait_for_bf(struct i2c_algo_lpc_data *adap) +{ + + int timeout = DEF_TIMEOUT; + int status; + + + while (--timeout) { + status = get_lpc(adap, I2C_LPC_REG_STATUS); + + DEBPROTO(lpc_fprintf_debug("%s : Waiting for bus full status : %x\n",__func__,status);) + + if(status & I2C_LPC_RBF) + { + DEBPROTO(lpc_fprintf_debug("%s : Bus is full status : %x\n",__func__,status);) + break; + } + + status = get_lpc(adap, I2C_LPC_REG_TEST); + + DEBPROTO(lpc_fprintf_debug("%s : The test register data : %x\n",__func__,status);) + udelay(1); /* wait for 100 us */ + } + + if (timeout == 0) { + DEBPROTO(lpc_fprintf_debug("%s : Timeout waiting for Bus Full\n",__func__);) + return -ETIMEDOUT; + } + + return 0; +} + +static int wait_for_td(struct i2c_algo_lpc_data *adap) +{ + + int timeout = DEF_TIMEOUT; + int status=0; + + while (--timeout) { + udelay(4); + status = get_lpc(adap, I2C_LPC_REG_STATUS); + + DEBPROTO(lpc_fprintf_debug("%s : Waiting for bus done status : %x\n",__func__,status);) + + if(status == I2C_LPC_TD) + { + DEBPROTO(lpc_fprintf_debug("%s : Bus is done status : %x\n",__func__,status);) + break; + } + } + + if (timeout == 0) { + DEBPROTO(lpc_fprintf_debug("%s : Timeout waiting for Bus Done\n",__func__);) + return -ETIMEDOUT; + } + + return 0; +} + + + +static int wait_for_pin(struct i2c_algo_lpc_data *adap, int *status) +{ + int timeout = DEF_TIMEOUT; + *status = get_lpc(adap, I2C_LPC_REG_STATUS); + + while ((*status & I2C_LPC_TBE) && --timeout) { + *status = get_lpc(adap, I2C_LPC_REG_STATUS); + } + + if (timeout == 0) + return -ETIMEDOUT; + + + return 0; +} + + +static int lpc_doAddress(struct i2c_algo_lpc_data *adap,struct i2c_msg *msg) +{ + unsigned short flags = msg->flags; + unsigned char addr; + + addr = msg->addr << 1; + if (flags & I2C_M_RD) + { + addr |= 1; + DEBPROTO(lpc_fprintf_debug("step 7 : read mode then write device address 0x%x\n",addr);) + } + else + { + DEBPROTO(lpc_fprintf_debug("step 2 : write mode then write device address 0x%x\n",addr);) + } + + if (flags & I2C_M_REV_DIR_ADDR) + { + addr ^= 1; + + } + i2c_outaddr(adap, addr); + return 0; + +} + + +static int lpc_sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) +{ + struct i2c_algo_lpc_data *adap = i2c_adap->algo_data; + int i = 0,timeout=0; + + unsigned int count = msg->len; + unsigned char *buf = msg->buf; + + do{ + lpc_doAddress(adap,msg); + set_lpc(adap, I2C_LPC_REG_BYTE_COUNT, (count-i) >= 4 ? 4:(count - i)); + DEBPROTO(lpc_fprintf_debug("step 3 : write register count %x\n",count);) + + if((count -i) >= 4) + { + i2c_outbyte1(adap, buf[i+0] & 0xff); + i2c_outbyte2(adap, buf[i+1] & 0xff); + i2c_outbyte3(adap, buf[i+2] & 0xff); + i2c_outbyte4(adap, buf[i+3] & 0xff); + + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+0,buf[i+0]);) + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+1,buf[i+1]);) + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+2,buf[i+2]);) + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+3,buf[i+3]);) + i += 4; + } + else if((count -i) == 3) + { + i2c_outbyte1(adap, buf[i+0] & 0xff); + i2c_outbyte2(adap, buf[i+1] & 0xff); + i2c_outbyte3(adap, buf[i+2] & 0xff); + + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+0,buf[i+0]);) + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+1,buf[i+1]);) + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+2,buf[i+2]);) + + i += 3; + } + else if((count -i) == 2) + { + i2c_outbyte1(adap, buf[i+0] & 0xff); + i2c_outbyte2(adap, buf[i+1] & 0xff); + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+0,buf[i+0]);) + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+1,buf[i+1]);) + i += 2; + } + else if((count -i) == 1) + { + i2c_outbyte1(adap, buf[i+0] & 0xff); + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+0,buf[i+0]);) + i += 1; + } + + /* Send START */ + DEBPROTO(lpc_fprintf_debug("step 5-1 : Delay 6mS \n");) + udelay(6000); + DEBPROTO(lpc_fprintf_debug("step 5-2 : Start to transfrom \n");) + i2c_stop(adap); + i2c_start(adap); + DEBPROTO(lpc_fprintf_debug("step 5-3 : Start done\n");) + + udelay(400); + DEBPROTO(lpc_fprintf_debug("step 6 : Waiting for BE\n");) + timeout = wait_for_td(adap); + if (timeout) { + DEBPROTO(lpc_fprintf_debug("step 6 : Timeout waiting for BE \n");) + return -EREMOTEIO; + } + }while (i < count); + + if(i == count) + { + DEBPROTO(lpc_fprintf_debug("Writen %d bytes successd !\n",count);) + return i; + } + else + { + DEBPROTO(lpc_fprintf_debug("Writen %d bytes failed \n",count);) + return -EIO; + } +} + +static int lpc_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) +{ + int i=0,timeout=0; + struct i2c_algo_lpc_data *adap = i2c_adap->algo_data; + + unsigned int count = msg->len; + unsigned char *buf = msg->buf; + + do{ + lpc_doAddress(adap,msg); + set_lpc(adap, I2C_LPC_REG_BYTE_COUNT, (count-i) >= 4 ? 4:(count - i)); + DEBPROTO(lpc_fprintf_debug("step 8 : write register count %d\n",count);) + + /* Send START */ + DEBPROTO(lpc_fprintf_debug("step 9-1 : Delay 6mS\n");) + udelay(6000); + DEBPROTO(lpc_fprintf_debug("step 9-2 : Start to receive data\n");) + i2c_stop(adap); + i2c_start(adap); + DEBPROTO(lpc_fprintf_debug("step 9-3 : Start done\n");) + + udelay(400); + DEBPROTO(lpc_fprintf_debug("step 10 : Waiting for TD\n");) + timeout = wait_for_td(adap); + if (timeout) { + DEBPROTO(lpc_fprintf_debug("step 10 : Timeout waiting for TD \n");) + return -EREMOTEIO; + } + + if((count -i) >= 4) + { + buf[i+0] = 0xff & i2c_inbyte1(adap); + buf[i+1] = 0xff & i2c_inbyte2(adap); + buf[i+2] = 0xff & i2c_inbyte3(adap); + buf[i+3] = 0xff & i2c_inbyte4(adap); + + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+0,buf[i+0]);) + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+1,buf[i+1]);) + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+2,buf[i+2]);) + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+3,buf[i+3]);) + + i += 4; + } + else if((count -i) == 3) + { + buf[i+0] = 0xff & i2c_inbyte1(adap); + buf[i+1] = 0xff & i2c_inbyte2(adap); + buf[i+2] = 0xff & i2c_inbyte3(adap); + + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+0,buf[i+0]);) + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+1,buf[i+1]);) + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+2,buf[i+2]);) + + i += 3; + } + else if((count -i) == 2) + { + buf[i+0] = 0xff & i2c_inbyte1(adap); + buf[i+1] = 0xff & i2c_inbyte2(adap); + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+0,buf[i+0]);) + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+1,buf[i+1]);) + i += 2; + } + else if((count -i) == 1) + { + buf[i+0] = 0xff & i2c_inbyte1(adap); + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+0,buf[i+0]);) + i += 1; + } + + + }while(i < count); + + if(i == count) + { + DEBPROTO(lpc_fprintf_debug("Read %d bytes successd !\n",count);) + return i; + } + else + { + DEBPROTO(lpc_fprintf_debug("Read %d bytes failed \n",count);) + return -EIO; + } +} + + +struct cpld_client_node { + struct i2c_client *client; + struct list_head list; +}; +#define LPC_I2C_MAX_NCHANS 6 + + +struct lpc_iic { + struct i2c_adapter *virt_adaps[LPC_I2C_MAX_NCHANS]; + u8 last_chan; /* last register value */ +}; + + +static int lpc_master_xfer(struct i2c_adapter *i2c_adap, + struct i2c_msg *msgs, + int num) +{ + struct i2c_algo_lpc_data *adap = i2c_adap->algo_data; + struct i2c_msg *pmsg; + int i; + int ret=0; + + mutex_lock(&lpc_lock); + + if (adap->xfer_begin) + adap->xfer_begin(&i2c_adap->nr); + + + for (i = 0;ret >= 0 && i < num; i++) { + pmsg = &msgs[i]; + + DEBPROTO(lpc_fprintf_debug("lpc_xfer.o: Doing %s %d bytes to 0x%02x - %d of %d messages\n", + pmsg->flags & I2C_M_RD ? "read" : "write", + pmsg->len, pmsg->addr, i + 1, num);) + + DEBPROTO(lpc_fprintf_debug("lpc_xfer.o: Msg %d, addr=0x%x, flags=0x%x, len=%d\n", + i, msgs[i].addr, msgs[i].flags, msgs[i].len);) + + if (pmsg->flags & I2C_M_RD) { + ret = lpc_readbytes(i2c_adap, pmsg); + + if (ret != pmsg->len) { + DEBPROTO(lpc_fprintf_debug("lpc_xfer.o: fail: " + "only read %d bytes.\n",ret)); + } else { + DEBPROTO(lpc_fprintf_debug("lpc_xfer.o: read %d bytes.\n",ret)); + } + } else { + + ret = lpc_sendbytes(i2c_adap, pmsg); + + if (ret != pmsg->len) { + DEBPROTO(lpc_fprintf_debug("lpc_xfer.o: fail: " + "only wrote %d bytes.\n",ret)); + } else { + DEBPROTO(lpc_fprintf_debug("lpc_xfer.o: wrote %d bytes.\n",ret)); + } + } + } + + if (adap->xfer_end) + adap->xfer_end(&i2c_adap->nr); + + mutex_unlock(&lpc_lock); + + DEBPROTO(lpc_fprintf_debug("ret = 0x%x num = 0x%x i = 0x%x.\n",ret,num,i)); + + return ret = (ret < 0) ? ret : num; +} + + +static u32 lpc_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SMBUS_QUICK; +} + +/* exported algorithm data: */ +static const struct i2c_algorithm lpc_algo = { + .master_xfer = lpc_master_xfer, + //.smbus_xfer = lpc_smbus_xfer, + .functionality = lpc_func, +}; + + +/********************************************** End ********************************************************/ + + + + + + +/********************************************** Start ********************************************************/ +#define DEFAULT_BASE 0x0a00 + +static int lpc_base= 0x0a00; +static u8 __iomem *lpc_base_iomem; + +static int lpc_irq; +static int lpc_clock = 0x1c; +static int lpc_own = 0x55; +static int lpc_mmapped; + +static unsigned long lpc_base_addr = 0x0a00; +static unsigned int lpc_io_space_size = 2; + +static unsigned long LPC_INDEX_REG; +static unsigned long LPC_DATA_REG; + + +/* notice : removed static struct i2c_lpc_iic gpi; code - + this module in real supports only one device, due to missing arguments + in some functions, called from the algo-lpc module. Sometimes it's + need to be rewriten - but for now just remove this for simpler reading */ + +static wait_queue_head_t lpc_wait; +static int lpc_pending; +static spinlock_t lock; +static spinlock_t lpc_slock; + +static struct i2c_adapter lpc_iic_ops; + +struct cpld_dev_type { + struct resource *io_resource; + struct semaphore sem; + struct cdev cdev; +}; + +struct cpld_dev_type *cpld_device; + + +/* ----- local functions ---------------------------------------------- */ + +static void lpc_cpld_setbyte(void *data, int ctl, int val) +{ + outb(ctl, LPC_INDEX_REG); + mb(); + + outb(val, LPC_DATA_REG); + mb(); +} + +static int lpc_cpld_getbyte(void *data, int ctl) +{ + u8 val = 0; + + outb(ctl, LPC_INDEX_REG); + mb(); + + val = inb(LPC_DATA_REG); + mb(); + + return val; +} + +static void lpc_iic_setbyte(void *data, int ctl, int val) +{ + if (!cpld_device) + { + return ; + } + + if (down_interruptible(&cpld_device->sem)) + { + return ; + } + + + lpc_cpld_setbyte(data,ctl,val); + + up(&cpld_device->sem); + DEBPROTO(lpc_fprintf_debug("%s REG[%x] = %x\n",__func__,ctl,val);) +} + + +static int lpc_iic_getbyte(void *data, int ctl) +{ + u8 val = 0; + if (!cpld_device) + return -ENOTTY; + + if (down_interruptible(&cpld_device->sem)) + return -ERESTARTSYS; + + val = lpc_cpld_getbyte(data,ctl); + + up(&cpld_device->sem); + DEBPROTO(lpc_fprintf_debug("%s REG[%x] = %x\n",__func__,ctl,val);) + return val; +} + +int cig_cpld_read_register(u8 reg_off, u8 *val) +{ + if (!cpld_device) + return -ENOTTY; + + if (down_interruptible(&cpld_device->sem)) + return -ERESTARTSYS; + + *val = lpc_cpld_getbyte(cpld_device, reg_off); + + up(&cpld_device->sem); + + return 0; +} +EXPORT_SYMBOL(cig_cpld_read_register); + +int cig_cpld_write_register(u8 reg_off, u8 val) +{ + if (!cpld_device) + return -ENOTTY; + + if (down_interruptible(&cpld_device->sem)) + return -ERESTARTSYS; + + lpc_cpld_setbyte(cpld_device, reg_off, val); + up(&cpld_device->sem); + return 0; +} +EXPORT_SYMBOL(cig_cpld_write_register); + + + +static int lpc_iic_getown(void *data) +{ + return (lpc_own); +} + + +static int lpc_iic_getclock(void *data) +{ + return (lpc_clock); +} + +static void lpc_iic_waitforpin(void *data) +{ + DEFINE_WAIT(wait); + int timeout = 2; + unsigned long flags; + + if (lpc_irq > 0) { + spin_lock_irqsave(&lock, flags); + if (lpc_pending == 0) { + spin_unlock_irqrestore(&lock, flags); + prepare_to_wait(&lpc_wait, &wait, TASK_INTERRUPTIBLE); + if (schedule_timeout(timeout*HZ)) { + spin_lock_irqsave(&lock, flags); + if (lpc_pending == 1) { + lpc_pending = 0; + } + spin_unlock_irqrestore(&lock, flags); + } + finish_wait(&lpc_wait, &wait); + } else { + lpc_pending = 0; + spin_unlock_irqrestore(&lock, flags); + } + } else { + udelay(100); + } +} + + +static irqreturn_t lpc_iic_handler(int this_irq, void *dev_id) { + spin_lock(&lock); + lpc_pending = 1; + spin_unlock(&lock); + wake_up_interruptible(&lpc_wait); + return IRQ_HANDLED; +} + +static int board_id = 0; + + +static int lpc_iic_select(void *data) +{ + unsigned int chan_id=0; + chan_id = *(unsigned int *)data; + chan_id -= 2; + DEBPROTO(lpc_fprintf_debug("step 1 : selest channel id = %d\n",chan_id);) + lpc_iic_setbyte(data,I2C_LPC_REG_BUS_SEL,chan_id); + + return 0; +} + +static int lpc_iic_deselect(void *data) +{ + + unsigned int chan_id=0; + chan_id = *(unsigned int *)data; + chan_id -= 2; + DEBPROTO(lpc_fprintf_debug("step last :deselect channel id = %d\n",chan_id);) + + return 0; +} + + +/* ------------------------------------------------------------------------ + * Encapsulate the above functions in the correct operations structure. + * This is only done when more than one hardware adapter is supported. + */ +static struct i2c_algo_lpc_data lpc_iic_data = { + .setlpc = lpc_iic_setbyte, + .getlpc = lpc_iic_getbyte, + .getown = lpc_iic_getown, + .getclock = lpc_iic_getclock, + .waitforpin = lpc_iic_waitforpin, + .xfer_begin = lpc_iic_select, + .xfer_end = lpc_iic_deselect, +}; + +#include + +static struct i2c_adapter lpc_iic_arr_ops[LPC_I2C_MAX_NCHANS] = {0}; + +static void dummy_setscl(void *data, int state) +{ + return; +} + +static void dummy_setsda(void *data, int state) +{ + return; + +} + +static int dummy_getscl(void *data) +{ + return 1; + +} + +static int dummy_getsda(void *data) +{ + return 1; +} + + +static struct i2c_algo_bit_data dummy_algo_data = { + .setsda = dummy_setsda, + .setscl = dummy_setscl, + .getsda = dummy_getsda, + .getscl = dummy_getscl, + .udelay = 50, + .timeout = HZ, +}; + + +static int dummy_xfer(struct i2c_adapter *i2c_adap, + struct i2c_msg *msgs, + int num) +{ + return 1; +} + +static u32 dummy_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SMBUS_QUICK; +} + + +static const struct i2c_algorithm dummy_algo = { + .master_xfer = dummy_xfer, + .functionality = dummy_func, +}; + + + +static struct i2c_adapter i2c_dummy = { + .owner = THIS_MODULE, + .class = I2C_CLASS_HWMON, + .algo_data = &dummy_algo_data, + .algo = &dummy_algo, + .name = "i2c_dummy", +}; + + +static int lpc_iic_match(struct device *dev, unsigned int id) +{ + /* sanity checks for lpc_mmapped I/O */ + + DEB2(printk("lpc_iic_match\n");) + + + if (lpc_base < DEFAULT_BASE) { + dev_err(dev, "incorrect lpc_base address (%#x) specified " + "for lpc_mmapped I/O\n", lpc_base); + return 0; + } + + if (lpc_base == 0) { + lpc_base = DEFAULT_BASE; + } + return 1; +} + +static int lpc_iic_probe(struct device *dev, unsigned int id) +{ + int rval,num; + + lpc_fprintf_init(); + + DEB2(printk("lpc_iic_probe\n");) + + mutex_init(&lpc_lock); + + for(num = 0; num < LPC_I2C_MAX_NCHANS;num++) + { + lpc_iic_arr_ops[num].dev.parent = dev; + lpc_iic_arr_ops[num].owner = THIS_MODULE; + lpc_iic_arr_ops[num].class = I2C_CLASS_HWMON | I2C_CLASS_SPD; + lpc_iic_arr_ops[num].algo = &lpc_algo; + lpc_iic_arr_ops[num].algo_data = &lpc_iic_data, + lpc_iic_arr_ops[num].nr=num; + snprintf(lpc_iic_arr_ops[num].name, sizeof(lpc_iic_arr_ops[num].name), "i2c-%d-lpc", i2c_adapter_id(&lpc_iic_arr_ops[num])); + rval |= i2c_add_adapter(&lpc_iic_arr_ops[num]); + DEB2(printk("%s\n",lpc_iic_arr_ops[num].name);) + } + + return 0; +} + +static int lpc_iic_remove(struct device *dev, unsigned int id) +{ + int num; + DEB2(printk("lpc_iic_remove\n")); + + lpc_fprintf_exit(); + for(num = LPC_I2C_MAX_NCHANS - 1; num >= 0 ;num--) + i2c_del_adapter(&lpc_iic_arr_ops[num]); + + + return 0; +} + +static struct isa_driver i2c_lpc_driver = { + .match = lpc_iic_match, + .probe = lpc_iic_probe, + .remove = lpc_iic_remove, + .driver = { + .owner = THIS_MODULE, + .name = "lpc-iic", + }, +}; + +/********************************************** End ********************************************************/ + + + + + + +/********************************************** Start ********************************************************/ + +static int cpld_major = 0; +static int cpld_minor = 0; + +struct cpld_rw_msg { + unsigned char addr; + unsigned char data; +}; + + +static struct cpld_rw_msg param_read = {-1}; +static struct cpld_rw_msg param_write = {-1}; +static struct cpld_rw_msg param_reads = {-1}; +static struct cpld_rw_msg param_writes = {-1}; + +void cpld_sysfs_kobj_release(struct kobject *kobj) +{ + return; +} + +int cpld_sysfs_add_attr(struct kobject* kobj, char* attr_name) +{ + + struct attribute *attr; + + attr = kmalloc(sizeof(struct attribute), GFP_KERNEL); + attr->name = attr_name; + attr->mode = 0644; + + return sysfs_create_file(kobj, attr); +} + +static int cig_cpld_write_slave_cpld_register(u8 reg_addr, u8 reg_data); +static int cig_cpld_read_slave_cpld_register(u8 reg_addr, u8 *reg_data); + + +static ssize_t cpld_sysfs_show(struct kobject *kobj, struct attribute *attr, char *buffer) +{ + u8 val=0,ret=0,year=0,month=0,day=0,cpld_m=0,cpld_1=0,cpld_2=0; + + if (0 == strcmp(attr->name, "read")) + { + val = lpc_iic_getbyte(NULL,param_read.addr); + ret = sprintf(buffer,"read : addr = 0x%x val = 0x%x\n",param_read.addr, val); + + } + else if (0 == strcmp(attr->name, "write")) + { + lpc_iic_setbyte(NULL, param_write.addr,param_write.data); + ret = sprintf(buffer,"write : addr = 0x%x val = 0x%x\n",param_write.addr, param_write.data); + } + else if (0 == strcmp(attr->name, "version")) + { + cpld_m = lpc_iic_getbyte(NULL, 0x02); + year = lpc_iic_getbyte(NULL, 0x03); + month = lpc_iic_getbyte(NULL, 0x04); + day = lpc_iic_getbyte(NULL, 0x05); + + cig_cpld_read_slave_cpld_register(0x1d,&cpld_1); + cig_cpld_read_slave_cpld_register(0x1e,&cpld_2); + + ret = sprintf(buffer,"Main CPLD version : V%02x\n"\ + "Main CPLD date : 20%02x-%02x-%02x\n"\ + "Slave 1 CPLD version : V%02x\n"\ + "Slave 2 CPLD version : V%02x\n",cpld_m,year,month,day,cpld_1,cpld_2); + } + if (0 == strcmp(attr->name, "reads")) + { + ret = cig_cpld_read_slave_cpld_register(param_reads.addr,&val); + if (ret < 0) + printk("ERROR:Failed to read slave cpld.\n"); + ret = sprintf(buffer,"reads : addr = 0x%x val = 0x%x\n",param_reads.addr, val); + + } + else if (0 == strcmp(attr->name, "writes")) + { + ret = cig_cpld_write_slave_cpld_register(param_writes.addr,param_writes.data); + if (ret < 0) + printk("ERROR:Failed to read slave cpld.\n"); + ret = sprintf(buffer,"writes : addr = 0x%x val = 0x%x\n",param_writes.addr, param_writes.data); + } + + + return ret; + +} + +static ssize_t cpld_sysfs_store(struct kobject *kobj, struct attribute *attr, const char *buffer, size_t count) +{ + int param[3]; + + if (0 == strcmp(attr->name, "read")) + { + sscanf(buffer, "0x%02x", ¶m[0]); + param_read.addr = param[0]; + } + else if (0 == strcmp(attr->name, "write")) + { + sscanf(buffer, "0x%2x 0x%02x", ¶m[0], ¶m[1]); + param_write.addr = param[0]; + param_write.data = param[1]; + } + if (0 == strcmp(attr->name, "reads")) + { + sscanf(buffer, "0x%02x", ¶m[0]); + param_reads.addr = param[0]; + } + else if (0 == strcmp(attr->name, "writes")) + { + sscanf(buffer, "0x%2x 0x%02x", ¶m[0], ¶m[1]); + param_writes.addr = param[0]; + param_writes.data = param[1]; + } + return count; +} + + + +static struct sysfs_ops cpld_sysfs_ops = +{ + .show = cpld_sysfs_show, + .store = cpld_sysfs_store, +}; + +static struct kobj_type cpld_kobj_type = +{ + .release = cpld_sysfs_kobj_release, + .sysfs_ops = &cpld_sysfs_ops, + .default_attrs = NULL, +}; + + +static const char driver_name[] = "cpld_drv"; +static atomic_t cpld_available = ATOMIC_INIT(1); +static struct class *cpld_class; +static struct device *cpld_dev; + + + +#define CPLD_IOC_MAGIC '[' + +#define CPLD_IOC_RDREG _IOR(CPLD_IOC_MAGIC, 0, struct cpld_rw_msg) +#define CPLD_IOC_WRREG _IOW(CPLD_IOC_MAGIC, 1, struct cpld_rw_msg) + +#define CPLD_IOC_MAXNR 2 + + +int cpld_open(struct inode *inode, struct file *filp) +{ + struct cpld_dev_type *dev; + + if (! atomic_dec_and_test(&cpld_available)) { + atomic_inc(&cpld_available); + return -EBUSY; + } + + dev = container_of(inode->i_cdev, struct cpld_dev_type, cdev); + filp->private_data = dev; + + return 0; +} + +int cpld_release(struct inode *inode, struct file *flip) +{ + atomic_inc(&cpld_available); + return 0; +} + + +long cpld_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + int rc = 0; + int err = 0; + struct cpld_dev_type *dev = (struct cpld_dev_type *)filp->private_data; + struct cpld_rw_msg msg; + + if (_IOC_TYPE(cmd) != CPLD_IOC_MAGIC) + return -ENOTTY; + if (_IOC_NR(cmd) > CPLD_IOC_MAXNR) + return -ENOTTY; + + if (_IOC_DIR(cmd) & _IOC_READ) + err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd)); + if (_IOC_DIR(cmd) & _IOC_WRITE) + err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd)); + if (err) + return -EFAULT; + + if (down_interruptible(&dev->sem)) + return -ERESTARTSYS; + + switch(cmd){ + case CPLD_IOC_RDREG: + rc = copy_from_user(&msg, (void __user *)arg, sizeof(msg)); + if (!rc) { + msg.data = lpc_cpld_getbyte(dev, msg.addr); + rc = copy_to_user((void __user *)arg, &msg, sizeof(msg)); + } + break; + + case CPLD_IOC_WRREG: + rc = copy_from_user(&msg, (void __user *)arg, sizeof(msg)); + if (!rc) { + lpc_cpld_setbyte(dev, msg.addr, msg.data); + } + break; + default: + rc = -ENOTTY; + break; + } + up(&dev->sem); + + return rc; +} + +struct file_operations cpld_fops = { + .owner = THIS_MODULE, + .open = cpld_open, + .unlocked_ioctl = cpld_ioctl, + .release = cpld_release, +}; + + +static void cpld_setup_cdev(struct cpld_dev_type *dev) +{ + int err, devno = MKDEV(cpld_major, cpld_minor); + + cdev_init(&dev->cdev, &cpld_fops); + dev->cdev.owner = THIS_MODULE; + dev->cdev.ops = &cpld_fops; + err = cdev_add(&dev->cdev, devno, 1); + + if (err) + DEB2(printk(KERN_NOTICE "Error %d adding cpld", err);) +} +/********************************************** End ********************************************************/ + + + + +/********************************************** Start ********************************************************/ +#include +#include +#include + +static spinlock_t irq_inter_lock; +static struct delayed_work irq_inter_work; +static unsigned long irq_inter_delay; + + +static int cig_cpld_write_slave_cpld_register(u8 reg_addr, u8 reg_data) +{ + u8 read_status = 0; + u8 wait_time_out = WAIT_TIME_OUT_COUNT; + DEB2(printk("<=======write=========>")); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_ADDR, reg_addr << 1); + DEB2(printk("[62]=%x\n",reg_addr << 1)); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_TX, reg_data); + DEB2(printk("[63]=%x\n",reg_data)); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_COMMAND, 0x80); + DEB2(printk("[65]=%x\n",0x80)); + do{ + cig_cpld_read_register(ADDR_REG_SFP_STATUS_STATUS, &read_status); + DEB2(printk("[66]=%x\n",read_status)); + udelay(60); + wait_time_out--; + if(wait_time_out == 0) + break; + }while(read_status != 0x02); + DEB2(printk("<=======write=========>")); + + + if(wait_time_out == 0) + return -1; + + return 1; +} + + +static int cig_cpld_read_slave_cpld_register(u8 reg_addr, u8 *reg_data) +{ + u8 read_status = 0; + u8 wait_time_out = WAIT_TIME_OUT_COUNT; + DEB2(printk("<========read=========>")); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_ADDR, reg_addr << 1 | 1); + DEB2(printk("[62]=%x\n",reg_addr << 1 | 1)); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_COMMAND, 0x80); + DEB2(printk("[65]=%x\n",0x80)); + do{ + udelay(60); + cig_cpld_read_register(ADDR_REG_SFP_STATUS_STATUS, &read_status); + DEB2(printk("[66]=%x\n",read_status)); + wait_time_out--; + if(wait_time_out == 0) + break; + }while(read_status != 0x01); + + cig_cpld_read_register(ADDR_REG_SFP_STATUS_RX,reg_data); + DEB2(printk("[64]=%x\n",*reg_data)); + DEB2(printk("<========read=========>")); + + if(wait_time_out == 0) + return -1; + + return 1; +} + + + +struct sock *nlsk = NULL; +extern struct net init_net; +#define NETLINK_TEST 26 +#define MSG_LEN 125 +#define USER_PORT 100 +static u32 irq_present_status_low_current,irq_present_status_low_next; +static u32 irq_present_status_high_current,irq_present_status_high_next; +static u32 irq_tx_fault_status_low_current,irq_tx_fault_status_low_next; +static u32 irq_tx_fault_status_high_current,irq_tx_fault_status_high_next; +static u32 irq_rx_lost_status_low_current,irq_rx_lost_status_low_next; +static u32 irq_rx_lost_status_high_current,irq_rx_lost_status_high_next; + +static u8 irq_present_qsfp_current,irq_present_qsfp_next; +static u8 irq_interrupt_qsfp_current,irq_interrupt_qsfp_next; + +struct input_dev *cpld_input_dev; + + + +int send_usrmsg(char *pbuf, uint16_t len) +{ + struct sk_buff *nl_skb; + struct nlmsghdr *nlh; + + int ret; + + + nl_skb = nlmsg_new(len, GFP_ATOMIC); + if(!nl_skb) + { + printk("netlink alloc failure\n"); + return -1; + } + + + nlh = nlmsg_put(nl_skb, 0, 0, NETLINK_TEST, len, 0); + if(nlh == NULL) + { + printk("nlmsg_put failaure \n"); + nlmsg_free(nl_skb); + return -1; + } + + memcpy(nlmsg_data(nlh), pbuf, len); + ret = netlink_unicast(nlsk, nl_skb, USER_PORT, MSG_DONTWAIT); + + return ret; +} + +static void netlink_rcv_msg(struct sk_buff *skb) +{ + + struct nlmsghdr *nlh = NULL; + char *umsg = NULL; + char kmsg[1024] = {0}; + char kmsg_tmp[16] = {0}; + u8 i = 0; + u8 tmp[3]={0}; + + if(skb->len >= nlmsg_total_size(0)) + { + nlh = nlmsg_hdr(skb); + umsg = NLMSG_DATA(nlh); + if(umsg) + { + for(i = 0;i < 24;i++) + { + if(!(irq_present_status_low_current & (0x1 << i))) + { + tmp[0] = 1; + } + else + { + tmp[0] = 0; + } + + if(!(irq_rx_lost_status_low_current & (0x1 << i))) + { + tmp[1] = 1; + } + else + { + tmp[1] = 0; + } + + if(!(irq_tx_fault_status_low_current & (0x1 << i))) + { + tmp[2] = 1; + } + else + { + tmp[2] = 0; + } + memset(kmsg_tmp,0xff,sizeof(kmsg_tmp)); + sprintf(kmsg_tmp,"sfp%02d:%1d:%1d:%1d ",i+1,tmp[0],tmp[1],tmp[2]); + strcat(kmsg,kmsg_tmp); + } + + for(i = 0;i < 24;i++) + { + if(!(irq_present_status_high_current & (0x1 << i))) + { + tmp[0] = 1; + } + else + { + tmp[0] = 0; + } + + if(!(irq_rx_lost_status_high_current & (0x1 << i))) + { + tmp[1] = 1; + } + else + { + tmp[1] = 0; + } + + if(!(irq_tx_fault_status_high_current & (0x1 << i))) + { + tmp[2] = 1; + } + else + { + tmp[2] = 0; + } + memset(kmsg_tmp,0xff,sizeof(kmsg_tmp)); + sprintf(kmsg_tmp,"sfp%02d:%1d:%1d:%1d ",i+25,tmp[0],tmp[1],tmp[2]); + strcat(kmsg,kmsg_tmp); + } + + + for(i = 0;i < 8;i++) + { + if(!(irq_present_qsfp_current & (0x1 << i))) + { + tmp[0] = 1; + } + else + { + tmp[0] = 0; + } + + if(!(irq_interrupt_qsfp_current & (0x1 << i))) + { + tmp[1] = 1; + } + else + { + tmp[1] = 0; + } + + memset(kmsg_tmp,0xff,sizeof(kmsg_tmp)); + sprintf(kmsg_tmp,"qsfp%02d:%1d:%1d:%1d ",i+49,tmp[0],tmp[1],0); + strcat(kmsg,kmsg_tmp); + } + + printk("kernel recv from user: %s\n", umsg); + send_usrmsg(kmsg, strlen(kmsg)); + } + } + + return ; +} + + + +struct netlink_kernel_cfg cfg = { + .input = netlink_rcv_msg, /* set recv callback */ +}; + + + +#define RANGE_OF_BYTE_SHIFT(to_arg,shift,from_arg) {to_arg &= ~(0xff << shift); to_arg |= from_arg << shift;} + + +static void irq_inter_wapper(struct work_struct * work) +{ + + u8 m_data = 0; + u8 data_high8 = 0,data_low8 = 0; + u16 data_16 = 0; + u8 status = 0; + u8 i = 0; + char kmsg[64]={0}; + u8 tmp[3] = {0}; + + DEB2(printk("CPLD_MASTER_INTERRUPT\r\n")); + + m_data = lpc_iic_getbyte(NULL,CPLD_MASTER_INTERRUPT_STATUS_REG); + lpc_iic_setbyte(NULL,CPLD_MASTER_INTERRUPT_STATUS_REG,0xff); + + cig_cpld_write_slave_cpld_register(CPLD_SLAVE1_INTERRUPT_MASK_REG,0xff); + cig_cpld_write_slave_cpld_register(CPLD_SLAVE2_INTERRUPT_MASK_REG,0xff); + if(!(m_data & CPLD_MASTER_INTERRUPT_CPLD1)) + { + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_INTERRUPT_STATUS_H_REG,&data_high8); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_INTERRUPT_STATUS_L_REG,&data_low8); + data_16 = data_low8 | data_high8 << 8; + if( + !(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT08) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT16) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT24) + ) + { + if(!(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT08)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT08\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_PRESENT08_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_low_current,0,status); + + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT16)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT16\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_PRESENT16_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_low_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT24)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT24\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_PRESENT24_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_low_current,16,status); + } + DEB2(printk("irq_present_status_low_next = %08x irq_present_status_low_current = %08x \n",irq_present_status_low_next,irq_present_status_low_current)); + } + + if( + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST08) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST16) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST24) + ) + { + if(!(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST08)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_RX_LOST08\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_RX_LOST08_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_low_current,0,status); + + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST16)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT16\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_RX_LOST16_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_low_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST24)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT24\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_RX_LOST24_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_low_current,16,status); + } + DEB2(printk("irq_rx_lost_status_low_next = %08x irq_rx_lost_status_low_current = %08x \n",irq_rx_lost_status_low_next,irq_rx_lost_status_low_current)); + } + + if( + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST08) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST16) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST24) + ) + { + if(!(data_16 & CPLD_SLAVE1_INTERRUPT_TX_FAULT08)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_TX_FAULT08\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_TX_FAULT08_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_low_current,0,status); + + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_TX_FAULT16)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_TX_FAULT16\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_TX_FAULT16_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_low_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_TX_FAULT24)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_TX_FAULT24\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_TX_FAULT24_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_low_current,16,status); + } + DEB2(printk("irq_tx_fault_status_low_next = %08x irq_tx_fault_status_low_current = %08x \n",irq_tx_fault_status_low_next,irq_tx_fault_status_low_current)); + + } + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_CPLD2)) + { + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_INTERRUPT_STATUS_H_REG,&data_high8); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_INTERRUPT_STATUS_L_REG,&data_low8); + data_16 = data_low8 | data_high8 << 8; + if( + !(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT32) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT40) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT48) + ) + { + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT32)) + { + DEB2(printk("CPLD_SLAVE2_PRESENT32_REG\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_PRESENT32_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_high_current,0,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT40)) + { + DEB2(printk("CPLD_SLAVE2_PRESENT40_REG\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_PRESENT40_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_high_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT48)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT48\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_PRESENT48_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_high_current,16,status); + } + } + + if( + !(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST32) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST40) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST48) + ) + { + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST32)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_RX_LOST32\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_RX_LOST32_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_high_current,0,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST40)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT40\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_RX_LOST40_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_high_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST48)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT48\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_RX_LOST48_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_high_current,16,status); + } + + } + + if( + !(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT32) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT40) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT48) + ) + { + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT32)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_RX_LOST32\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_TX_FAULT32_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_high_current,0,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT40)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT40\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_TX_FAULT40_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_high_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT48)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT48\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_TX_FAULT48_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_high_current,16,status); + } + } + + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT56)) + { + DEB2(printk("CPLD_SLAVE2_PRESENT56_REG\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_PRESENT56_REG,&status); + irq_present_qsfp_current = status; + } + + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_QSFP_CR56)) + { + DEB2(printk("CPLD_SLAVE2_QSFP_CR56_REG\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_QSFP_CR56_REG,&status); + irq_interrupt_qsfp_current = status; + } + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_LSW)) + { + DEB2(printk("CPLD_MASTER_INTERRUPT_LSW\r\n")); + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_PSU1)) + { + DEB2(printk("CPLD_MASTER_INTERRUPT_PSU1\r\n")); + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_PSU2)) + { + DEB2(printk("CPLD_MASTER_INTERRUPT_PSU2\r\n")); + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_6320)) + { + DEB2(printk("CPLD_MASTER_INTERRUPT_6320\r\n")); + } + cig_cpld_write_slave_cpld_register(CPLD_SLAVE1_INTERRUPT_MASK_REG,0x0); + cig_cpld_write_slave_cpld_register(CPLD_SLAVE2_INTERRUPT_MASK_REG,0x0); + + memset(tmp,0xff,sizeof(tmp)); + + for(i = 0;i < 24;i++) + { + if(!(irq_present_status_low_current & (0x1 << i)) && (irq_present_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d is present\r\n",i+1)); + tmp[0] = 1; + } + else if((irq_present_status_low_current & (0x1 << i)) && !(irq_present_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d is absent\r\n",i+1)); + tmp[0] = 0; + } + + if(!(irq_tx_fault_status_low_current & (0x1 << i)) && (irq_tx_fault_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d transmission is right\r\n",i+1)); + tmp[1] = 1; + } + else if((irq_tx_fault_status_low_current & (0x1 << i)) && !(irq_tx_fault_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d transmission is fault\r\n",i+1)); + tmp[1] = 0; + } + + if(!(irq_rx_lost_status_low_current & (0x1 << i)) && (irq_rx_lost_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d optical is meet\r\n",i+1)); + tmp[2] = 1; + } + else if((irq_rx_lost_status_low_current & (0x1 << i)) && !(irq_rx_lost_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d optical is lost\r\n",i+1)); + tmp[2] = 0; + } + + if((tmp[0] != 0xff) || (tmp[1] != 0xff) || (tmp[2] != 0xff)) + { + memset(kmsg,0xff,sizeof(kmsg)); + snprintf(kmsg,sizeof(kmsg),"sfp%02d:%1d:%1d:%1d ",i+1,(tmp[0] == 0xff) ? 0:tmp[0],(tmp[1] == 0xff) ? 0:tmp[1],(tmp[2] == 0xff) ? 0:tmp[2]); + break; + } + } + + memset(tmp,0xff,sizeof(tmp)); + for(i = 0;i < 24;i++) + { + if(!(irq_present_status_high_current & (0x1 << i)) && (irq_present_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d is present\r\n",i+25)); + tmp[0] = 1; + } + else if((irq_present_status_high_current & (0x1 << i)) && !(irq_present_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d is absent\r\n",i+25)); + tmp[0] = 0; + + } + + if(!(irq_rx_lost_status_high_current & (0x1 << i)) && (irq_rx_lost_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d optical is meet\r\n",i+25)); + tmp[1] = 1; + } + else if((irq_rx_lost_status_high_current & (0x1 << i)) && !(irq_rx_lost_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d optical is lost\r\n",i+25)); + tmp[1] = 0; + } + + if(!(irq_tx_fault_status_high_current & (0x1 << i)) && (irq_tx_fault_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d transmission is right\r\n",i+25)); + tmp[2] = 1; + } + else if((irq_tx_fault_status_high_current & (0x1 << i)) && !(irq_tx_fault_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d transmission is fault\r\n",i+25)); + tmp[2] = 0; + } + + if((tmp[0] != 0xff) || (tmp[1] != 0xff) || (tmp[2] != 0xff)) + { + memset(kmsg,0xff,sizeof(kmsg)); + snprintf(kmsg,sizeof(kmsg),"sfp%02d:%1d:%1d:%1d ",i+25,(tmp[0] == 0xff) ? 0:tmp[0],(tmp[1] == 0xff) ? 0:tmp[1],(tmp[2] == 0xff) ? 0:tmp[2]); + break; + } + } + + memset(tmp,0xff,sizeof(tmp)); + for(i = 0 ; i < 8; i++) + { + if(!(irq_present_qsfp_current & (0x1 << i)) && (irq_present_qsfp_next & (0x1 << i))) + { + DEB2(printk("SFP%d is present\r\n",i+49)); + tmp[0] = 1; + } + else if((irq_present_qsfp_current & (0x1 << i)) && !(irq_present_qsfp_next & (0x1 << i))) + { + DEB2(printk("SFP%d is absent\r\n",i+49)); + tmp[0] = 0; + } + + if(!(irq_interrupt_qsfp_current & (0x1 << i)) && (irq_interrupt_qsfp_next & (0x1 << i))) + { + DEB2(printk("SFP%d interrupt is occured \r\n",i+49)); + tmp[1] = 1; + } + else if((irq_interrupt_qsfp_current & (0x1 << i)) && !(irq_interrupt_qsfp_next & (0x1 << i))) + { + DEB2(printk("SFP%d interrupt is cleaned\r\n",i+49)); + tmp[1] = 0; + } + + if((tmp[0] != 0xff) || (tmp[1] != 0xff)) + { + memset(kmsg,0xff,sizeof(kmsg)); + snprintf(kmsg,sizeof(kmsg),"qsfp%02d:%1d:%1d:%1d ",i+49,(tmp[0] == 0xff) ? 0:tmp[0],(tmp[1] == 0xff) ? 0:tmp[1],0); + break; + } + } + + + irq_present_status_low_next = irq_present_status_low_current; + irq_rx_lost_status_low_next = irq_rx_lost_status_low_current; + irq_tx_fault_status_low_next = irq_tx_fault_status_low_current; + irq_present_status_high_next = irq_present_status_high_current; + irq_rx_lost_status_high_next = irq_rx_lost_status_high_current; + irq_tx_fault_status_high_next = irq_tx_fault_status_high_current; + irq_present_qsfp_next = irq_present_qsfp_current; + irq_interrupt_qsfp_next = irq_interrupt_qsfp_current; + + send_usrmsg(kmsg, strlen(kmsg)); +} + +static void disableIrq(unsigned short maskReg, unsigned short mask) +{ + u8 data = 0; + + data = lpc_iic_getbyte(NULL,maskReg); + data |= mask; + lpc_iic_setbyte(NULL,maskReg, data); +} + +static void enableIrq(unsigned short maskReg, unsigned short mask) +{ + unsigned short data; + + data = lpc_iic_getbyte(NULL,maskReg); + data &= ~mask; + lpc_iic_setbyte(NULL,maskReg, data); +} + + +static irqreturn_t irq_inter_isr(int irq, void *handle) +{ + + /* + * use keventd context to read the event fifo registers + * Schedule readout at least 25ms after notification for + * REVID < 4 + */ + + schedule_delayed_work(&irq_inter_work, irq_inter_delay); + + return IRQ_HANDLED; +} + + +#define CIG_CPLD_CHR_NAME "cpld" + + +static int __init cpld_init(void) +{ + int rval,rc=0; + dev_t dev; + u8 s_data; + int isr_GPIO_num = 289; + + DEB2(printk("cpld_init\n");) + +/**************************************************************************************/ + + LPC_INDEX_REG = lpc_base_addr; + LPC_DATA_REG = lpc_base_addr + 1; + + cpld_device = kzalloc(sizeof(struct cpld_dev_type), GFP_KERNEL); + if (!cpld_device) + goto error3; + cpld_device->io_resource = request_region(lpc_base_addr, + lpc_io_space_size, "lpc-i2c"); + if (!cpld_device->io_resource) { + printk("lpc: claim I/O resource fail\n"); + goto error2; + } + sema_init(&cpld_device->sem, 1); + + if (cpld_major) { + dev = MKDEV(cpld_major, cpld_minor); + rc = register_chrdev_region(dev, 1, CIG_CPLD_CHR_NAME); + } else { + rc = alloc_chrdev_region(&dev, cpld_major, 1, CIG_CPLD_CHR_NAME); + cpld_major = MAJOR(dev); + } + + cpld_setup_cdev(cpld_device); + + cpld_class = class_create(THIS_MODULE,CIG_CPLD_CHR_NAME); + if (!cpld_class) { + DEB2(printk("failed to create class\n");) + goto error1; + } + + cpld_class->p->subsys.kobj.ktype= &cpld_kobj_type; + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "read"); + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "write"); + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "reads"); + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "writes"); + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "version"); + + cpld_dev = device_create(cpld_class, NULL, dev, NULL, CIG_CPLD_CHR_NAME); + +/**************************************************************************************/ + + rval = lpc_bus_init(); + rval = lpc_register_driver(&i2c_lpc_driver, 1); + +/**************************************************************************************/ + return 0; +error1: + cdev_del(&cpld_device->cdev); + unregister_chrdev_region(dev, 1); +error2: + release_resource(cpld_device->io_resource); +error3: + kfree(cpld_device); + + return rc; +} + +static void __exit cpld_exit(void) +{ + DEB2(printk("cpld_exit\n")); + + if (nlsk){ + netlink_kernel_release(nlsk); /* release ..*/ + nlsk = NULL; + } + + + lpc_unregister_driver(&i2c_lpc_driver); + lpc_bus_exit(); + dev_t devno = MKDEV(cpld_major, cpld_minor); + + cdev_del(&cpld_device->cdev); + if (cpld_class) { + device_destroy(cpld_class, devno); + class_destroy(cpld_class); + } + + if (cpld_device) { + if (cpld_device->io_resource) + release_resource(cpld_device->io_resource); + + kfree(cpld_device); + } + unregister_chrdev_region(devno, 1); + + +} + +module_param(cpld_major, int, S_IRUGO); +module_param(cpld_minor, int, S_IRUGO); +module_param(i2c_debug, int, S_IRUGO); +module_param(board_id, int, S_IRUGO); + +module_init(cpld_init); +module_exit(cpld_exit); + +MODULE_AUTHOR("Zhang Peng "); +MODULE_DESCRIPTION("cs5435-54p-cpld driver"); +MODULE_LICENSE("GPL"); + + +/********************************************** End ********************************************************/ + + + diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-fan.c b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-fan.c new file mode 100644 index 000000000000..a254dae33c2c --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-fan.c @@ -0,0 +1,521 @@ +/* + * A hwmon driver for the CIG cs5435-54p fan + * + * Copyright (C) 2018 Cambridge, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 + + + +#define FAN_SPEED_DUTY_TO_CPLD_STEP 10 + +static struct cs5435_54p_fan_data *cs5435_54p_fan_update_device(struct device *dev); +static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t set_fan_direction(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); + + +extern int cig_cpld_write_register(u8 reg_off, u8 val); +extern int cig_cpld_read_register(u8 reg_off, u8 *val); + +/* fan related data, the index should match sysfs_fan_attributes + */ +static const u8 fan_reg[] = { + 0x41, /* fan enable/disable */ + 0x40, /* fan PWM(for all fan) */ + 0x42, /* front fan 1 speed(rpm) */ + 0x44, /* front fan 2 speed(rpm) */ + 0x46, /* front fan 3 speed(rpm) */ + 0x48, /* front fan 4 speed(rpm) */ + 0x4a, /* front fan 5 speed(rpm) */ + 0x43, /* rear fan 1 speed(rpm) */ + 0x45, /* rear fan 2 speed(rpm) */ + 0x47, /* rear fan 3 speed(rpm) */ + 0x49, /* rear fan 4 speed(rpm) */ + 0x4b, /* rear fan 5 speed(rpm) */ + 0x4c, /* fan direction rear to front or front to rear */ +}; + + +/* Each client has this additional data */ +struct cs5435_54p_fan_data { + struct platform_device *pdev; + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 reg_val[ARRAY_SIZE(fan_reg)]; /* Register value */ +}; + +static struct cs5435_54p_fan_data *fan_data = NULL; + +enum fan_id { + FAN1_ID, + FAN2_ID, + FAN3_ID, + FAN4_ID, + FAN5_ID, +}; + +enum sysfs_fan_attributes { + FAN_STATE_REG, + FAN_DUTY_CYCLE_PERCENTAGE, /* Only one CPLD register to control duty cycle for all fans */ + FAN1_FRONT_SPEED_RPM, + FAN2_FRONT_SPEED_RPM, + FAN3_FRONT_SPEED_RPM, + FAN4_FRONT_SPEED_RPM, + FAN5_FRONT_SPEED_RPM, + FAN1_REAR_SPEED_RPM, + FAN2_REAR_SPEED_RPM, + FAN3_REAR_SPEED_RPM, + FAN4_REAR_SPEED_RPM, + FAN5_REAR_SPEED_RPM, + FAN_DIRECTION, + FAN1_STATE, + FAN2_STATE, + FAN3_STATE, + FAN4_STATE, + FAN5_STATE, + FAN1_FAULT, + FAN2_FAULT, + FAN3_FAULT, + FAN4_FAULT, + FAN5_FAULT, + FAN1_DIRECTION, + FAN2_DIRECTION, + FAN3_DIRECTION, + FAN4_DIRECTION, + FAN5_DIRECTION, +}; + +/* Define attributes + */ +#define DECLARE_FAN_STATE_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_state, S_IRUGO, fan_show_value, NULL, FAN##index##_STATE) +#define DECLARE_FAN_STATE_ATTR(index) &sensor_dev_attr_fan##index##_state.dev_attr.attr + +#define DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_fault, S_IRUGO, fan_show_value, NULL, FAN##index##_FAULT) +#define DECLARE_FAN_FAULT_ATTR(index) &sensor_dev_attr_fan##index##_fault.dev_attr.attr + +#define DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_duty_cycle_percentage, S_IWUSR | S_IRUGO, fan_show_value, set_duty_cycle, FAN##index##_DUTY_CYCLE_PERCENTAGE) +#define DECLARE_FAN_DUTY_CYCLE_ATTR(index) &sensor_dev_attr_fan##index##_duty_cycle_percentage.dev_attr.attr + +#define DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_front_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##index##_FRONT_SPEED_RPM);\ + static SENSOR_DEVICE_ATTR(fan##index##_rear_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##index##_REAR_SPEED_RPM) +#define DECLARE_FAN_SPEED_RPM_ATTR(index) &sensor_dev_attr_fan##index##_front_speed_rpm.dev_attr.attr, \ + &sensor_dev_attr_fan##index##_rear_speed_rpm.dev_attr.attr + +#define DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_direction, S_IWUSR | S_IRUGO, fan_show_value, set_fan_direction, FAN##index##_DIRECTION) +#define DECLARE_FAN_DIRECTION_ATTR(index) &sensor_dev_attr_fan##index##_direction.dev_attr.attr + + +/* 5 fan state attributes in this platform */ +DECLARE_FAN_STATE_SENSOR_DEV_ATTR(1); +DECLARE_FAN_STATE_SENSOR_DEV_ATTR(2); +DECLARE_FAN_STATE_SENSOR_DEV_ATTR(3); +DECLARE_FAN_STATE_SENSOR_DEV_ATTR(4); +DECLARE_FAN_STATE_SENSOR_DEV_ATTR(5); + + +/* 5 fan fault attributes in this platform */ +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(1); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(2); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(3); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(4); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(5); + +/* 5 fan speed(rpm) attributes in this platform */ +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(1); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(2); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(3); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(4); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(5); + +/* 1 fan duty cycle attribute in this platform */ +DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(); + +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(1); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(2); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(3); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(4); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(5); + + +static struct attribute *cs5435_54p_fan_attributes[] = { + /* fan related attributes */ + DECLARE_FAN_STATE_ATTR(1), + DECLARE_FAN_STATE_ATTR(2), + DECLARE_FAN_STATE_ATTR(3), + DECLARE_FAN_STATE_ATTR(4), + DECLARE_FAN_STATE_ATTR(5), + DECLARE_FAN_FAULT_ATTR(1), + DECLARE_FAN_FAULT_ATTR(2), + DECLARE_FAN_FAULT_ATTR(3), + DECLARE_FAN_FAULT_ATTR(4), + DECLARE_FAN_FAULT_ATTR(5), + DECLARE_FAN_SPEED_RPM_ATTR(1), + DECLARE_FAN_SPEED_RPM_ATTR(2), + DECLARE_FAN_SPEED_RPM_ATTR(3), + DECLARE_FAN_SPEED_RPM_ATTR(4), + DECLARE_FAN_SPEED_RPM_ATTR(5), + DECLARE_FAN_DUTY_CYCLE_ATTR(), + DECLARE_FAN_DIRECTION_ATTR(1), + DECLARE_FAN_DIRECTION_ATTR(2), + DECLARE_FAN_DIRECTION_ATTR(3), + DECLARE_FAN_DIRECTION_ATTR(4), + DECLARE_FAN_DIRECTION_ATTR(5), + NULL +}; + +#define FAN_MAX_DUTY_CYCLE 100 +#define FAN_REG_VAL_TO_SPEED_RPM_STEP 100 + +/* fan utility functions + */ +static u32 reg_val_to_duty_cycle(u8 reg_val) +{ + if (reg_val +== 0xFF) { + return 100; + } + return ((u32)(reg_val) * 100)/ 255; +} + +static u8 duty_cycle_to_reg_val(u8 duty_cycle) +{ + if (duty_cycle >= FAN_MAX_DUTY_CYCLE) { + return 0xFF; + } + + return 255 / 10 * (duty_cycle / 10); +} + +static u32 reg_val_to_speed_rpm(u8 reg_val) +{ + return (u32)reg_val * FAN_REG_VAL_TO_SPEED_RPM_STEP; +} + +static u8 reg_val_to_is_state(u8 reg_val, enum fan_id id) +{ + u8 mask = (1 << id); + + reg_val &= mask; + + return reg_val ? 0 : 1; +} + +static u8 is_fan_fault(struct cs5435_54p_fan_data *data, enum fan_id id) +{ + u8 ret = 1; + int front_fan_index = FAN1_FRONT_SPEED_RPM + id; + int rear_fan_index = FAN1_REAR_SPEED_RPM + id; + + /* Check if the speed of front or rear fan is ZERO, + */ + if (reg_val_to_speed_rpm(data->reg_val[front_fan_index]) && + reg_val_to_speed_rpm(data->reg_val[rear_fan_index])) { + ret = 0; + } + + return ret; +} + + +static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int error, value; + + error = kstrtoint(buf, 10, &value); + if (error) + return error; + + if (value <= 0 || value > FAN_MAX_DUTY_CYCLE) + return -EINVAL; + + cig_cpld_write_register(fan_reg[FAN_DUTY_CYCLE_PERCENTAGE], duty_cycle_to_reg_val(value)); + + return count; +} + +static ssize_t set_fan_direction(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int error, value,fan_index; + u8 mask,reg_val; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + fan_index = attr->index - FAN1_DIRECTION; + error = kstrtoint(buf, 10, &value); + if (error) + return error; + + if (!(value == 0 || value == 1)) + return -EINVAL; + + + cig_cpld_read_register(fan_reg[FAN_DIRECTION],®_val); + + if(value == 1) + { + reg_val |= (1 << fan_index); + } + else + { + reg_val &= ~(1 << fan_index); + } + + cig_cpld_write_register(fan_reg[FAN_DIRECTION], reg_val); + + return count; +} + + + + + +static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + cs5435_54p_fan_update_device(dev); + + struct cs5435_54p_fan_data *data = fan_data; + + ssize_t ret = 0; + + if (data->valid) { + switch (attr->index) { + + case FAN1_STATE: + case FAN2_STATE: + case FAN3_STATE: + case FAN4_STATE: + case FAN5_STATE: + //printk("FAN_STATE_REG: 0x%x\n", data->reg_val[FAN_STATE_REG]); + //printk("index: %d\n", attr->index); + ret = sprintf(buf, "%d\n", + reg_val_to_is_state(data->reg_val[FAN_STATE_REG], + attr->index - FAN1_STATE)); + break; + case FAN_DUTY_CYCLE_PERCENTAGE: + { + u32 duty_cycle = reg_val_to_duty_cycle(data->reg_val[FAN_DUTY_CYCLE_PERCENTAGE]); + ret = sprintf(buf, "%u\n", duty_cycle); + break; + } + case FAN1_FRONT_SPEED_RPM: + case FAN2_FRONT_SPEED_RPM: + case FAN3_FRONT_SPEED_RPM: + case FAN4_FRONT_SPEED_RPM: + case FAN5_FRONT_SPEED_RPM: + case FAN1_REAR_SPEED_RPM: + case FAN2_REAR_SPEED_RPM: + case FAN3_REAR_SPEED_RPM: + case FAN4_REAR_SPEED_RPM: + case FAN5_REAR_SPEED_RPM: +// printk("FAN_seed_REG: 0x%x\n", data->reg_val[attr->index]); +// printk("index: %d\n", attr->index); + ret = sprintf(buf, "%u\n", reg_val_to_speed_rpm(data->reg_val[attr->index])); + break; + + case FAN1_FAULT: + case FAN2_FAULT: + case FAN3_FAULT: + case FAN4_FAULT: + case FAN5_FAULT: + ret = sprintf(buf, "%d\n", is_fan_fault(data, attr->index - FAN1_FAULT)); + break; + case FAN1_DIRECTION: + case FAN2_DIRECTION: + case FAN3_DIRECTION: + case FAN4_DIRECTION: + case FAN5_DIRECTION: + ret = sprintf(buf, "%d\n",reg_val_to_is_state(data->reg_val[FAN_DIRECTION],attr->index - FAN1_DIRECTION)); + break; + default: + break; + } + } + + return ret; +} + +static const struct attribute_group cs5435_54p_fan_group = { + .attrs = cs5435_54p_fan_attributes, +}; + +static struct cs5435_54p_fan_data *cs5435_54p_fan_update_device(struct device *dev) +{ + struct cs5435_54p_fan_data *data = fan_data; + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || + !data->valid) { + int i; + + data->valid = 0; + + /* Update fan data + */ + for (i = 0; i < ARRAY_SIZE(data->reg_val); i++) { + u8 status; + (void)cig_cpld_read_register(fan_reg[i], &status); + + if (status < 0) { + data->valid = 0; + mutex_unlock(&data->update_lock); + return data; + } + else { + data->reg_val[i] = status; + } + } + + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; +} + +static int cs5435_54p_fan_probe(struct platform_device *pdev) +{ + int status = -1; + /* Register sysfs hooks */ + status = sysfs_create_group(&pdev->dev.kobj, &cs5435_54p_fan_group); + if (status) { + goto exit; + + } + + fan_data->hwmon_dev = hwmon_device_register(&pdev->dev); + if (IS_ERR(fan_data->hwmon_dev)) { + status = PTR_ERR(fan_data->hwmon_dev); + goto exit_remove; + } + + dev_info(&pdev->dev, "cs5435_54p_fan\n"); + + return 0; + +exit_remove: + sysfs_remove_group(&pdev->dev.kobj, &cs5435_54p_fan_group); +exit: + return status; +} + +static int cs5435_54p_fan_remove(struct platform_device *pdev) +{ + hwmon_device_unregister(fan_data->hwmon_dev); + sysfs_remove_group(&fan_data->pdev->dev.kobj, &cs5435_54p_fan_group); + + return 0; +} + +#define DRVNAME "cs5435_54p_fan" + +static struct platform_driver cs5435_54p_fan_driver = { + .probe = cs5435_54p_fan_probe, + .remove = cs5435_54p_fan_remove, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, +}; + + + + + +static int __init cs5435_54p_fan_init(void) +{ + int ret; + + cig_cpld_write_register(0x40, duty_cycle_to_reg_val(50)); + + ret = platform_driver_register(&cs5435_54p_fan_driver); + if (ret < 0) { + goto exit; + } + + fan_data = kzalloc(sizeof(struct cs5435_54p_fan_data), GFP_KERNEL); + if (!fan_data) { + ret = -ENOMEM; + platform_driver_unregister(&cs5435_54p_fan_driver); + goto exit; + } + + mutex_init(&fan_data->update_lock); + fan_data->valid = 0; + + fan_data->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(fan_data->pdev)) { + ret = PTR_ERR(fan_data->pdev); + platform_driver_unregister(&cs5435_54p_fan_driver); + kfree(fan_data); + goto exit; + } + +exit: + return ret; +} + +static void __exit cs5435_54p_fan_exit(void) +{ + platform_device_unregister(fan_data->pdev); + platform_driver_unregister(&cs5435_54p_fan_driver); + kfree(fan_data); +} + +MODULE_AUTHOR("CIG"); +MODULE_DESCRIPTION("cs5435_54p_fan driver"); +MODULE_LICENSE("GPL"); + +module_init(cs5435_54p_fan_init); +module_exit(cs5435_54p_fan_exit); + +MODULE_AUTHOR("Zhang Peng "); +MODULE_DESCRIPTION("cs5435_54p_fan driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-led.c b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-led.c new file mode 100644 index 000000000000..dae49967592e --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-led.c @@ -0,0 +1,594 @@ +/* + * A hwmon driver for the CIG cs5435-54P LED + * + * Copyright (C) 2018 Cambridge, Inc. + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/*#define DEBUG*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +extern int cig_cpld_write_register(u8 reg_off, u8 val); + +extern int cig_cpld_read_register(u8 reg_off, u8 *val); + +extern void led_classdev_unregister(struct led_classdev *led_cdev); +extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); +extern void led_classdev_resume(struct led_classdev *led_cdev); +extern void led_classdev_suspend(struct led_classdev *led_cdev); + +#define DRVNAME "cs5435_54p_led" + +struct cs5435_54p_led_data { + struct platform_device *pdev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 reg_val[6]; /* 0: system & location + 1: PSU1 &PSU12 + 2: fan & management + 3: console & ToD + 4-5 : fan1-fan5*/ +}; + +static struct cs5435_54p_led_data *ledctl = NULL; + +/* LED related data + */ +#define LED_TYPE_PSU1_REG_MASK 0x0C +#define LED_MODE_PSU1_GREEN_MASK 0x08 +#define LED_MODE_PSU1_RED_MASK 0x04 +#define LED_MODE_PSU1_AMBER_MASK 0x0C +#define LED_MODE_PSU1_OFF_MASK 0x00 + +#define LED_TYPE_PSU2_REG_MASK 0x30 +#define LED_MODE_PSU2_GREEN_MASK 0x20 +#define LED_MODE_PSU2_RED_MASK 0x10 +#define LED_MODE_PSU2_AMBER_MASK 0x30 +#define LED_MODE_PSU2_OFF_MASK 0x00 + +#define LED_TYPE_SYS_REG_MASK 0xF0 +#define LED_MODE_SYS_GREEN_MASK 0x40 +#define LED_MODE_SYS_RED_MASK 0x20 +#define LED_MODE_SYS_AMBER_MASK 0x60 +#define LED_MODE_SYS_AMBER_FLASHING_MASK 0x70 +#define LED_MODE_SYS_OFF_MASK 0x00 + +#define LED_TYPE_RES_REG_MASK 0x0F +#define LED_MODE_RES_GREEN_MASK 0x04 +#define LED_MODE_RES_RED_MASK 0x02 +#define LED_MODE_RES_AMBER_MASK 0x06 +#define LED_MODE_RES_AMBER_FLASHING_MASK 0x07 +#define LED_MODE_RES_OFF_MASK 0x00 + +#define LED_TYPE_FAN_REG_MASK 0x03 +#define LED_MODE_FAN_GREEN_MASK 0x02 +#define LED_MODE_FAN_RED_MASK 0x01 +#define LED_MODE_FAN_AMBER_MASK 0x03 +#define LED_MODE_FAN_OFF_MASK 0x00 + +#define LED_TYPE_FAN1_REG_MASK 0x03 +#define LED_TYPE_FAN2_REG_MASK 0x0C +#define LED_TYPE_FAN3_REG_MASK 0x30 +#define LED_TYPE_FAN4_REG_MASK 0xC0 +#define LED_TYPE_FAN5_REG_MASK 0x03 + +#define LED_MODE_FANX_GREEN_MASK 0x02 +#define LED_MODE_FANX_RED_MASK 0x01 +#define LED_MODE_FANX_AMBER_MASK 0x03 +#define LED_MODE_FANX_OFF_MASK 0x00 + +enum led_type { + LED_TYPE_SYS, + LED_TYPE_PSU2, + LED_TYPE_PSU1, + LED_TYPE_FAN, + LED_TYPE_FAN1, + LED_TYPE_FAN2, + LED_TYPE_FAN3, + LED_TYPE_FAN4, + LED_TYPE_FAN5, +}; + +static const u8 led_reg[] = { + 0x30, /* system & reserved*/ + 0x31, /* fan & PSU1 & PSU2 */ + 0x32, /* FAN5 LED */ + 0x33, /* FAN1-4 LED */ +}; + + +enum led_light_mode { + LED_MODE_OFF = 0, + LED_MODE_GREEN, + LED_MODE_AMBER, + LED_MODE_RED, + LED_MODE_GREEN_BLINK, + LED_MODE_AMBER_BLINK, + LED_MODE_RED_BLINK, + LED_MODE_GREEN_FLASHING, + LED_MODE_AMBER_FLASHING, + LED_MODE_RED_FLASHING, + LED_MODE_AUTO, + LED_MODE_UNKNOWN +}; + +struct led_type_mode { + enum led_type type; + int type_mask; + enum led_light_mode mode; + int mode_mask; +}; + +static struct led_type_mode led_type_mode_data[] = { +{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_GREEN, LED_MODE_PSU1_GREEN_MASK}, +{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_AMBER, LED_MODE_PSU1_AMBER_MASK}, +{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_RED, LED_MODE_PSU1_RED_MASK}, +{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_OFF, LED_MODE_PSU1_OFF_MASK}, + +{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_GREEN, LED_MODE_PSU2_GREEN_MASK}, +{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_AMBER, LED_MODE_PSU2_AMBER_MASK}, +{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_RED, LED_MODE_PSU2_RED_MASK}, +{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_OFF, LED_MODE_PSU2_OFF_MASK}, + +{LED_TYPE_SYS, LED_TYPE_SYS_REG_MASK, LED_MODE_GREEN, LED_MODE_SYS_GREEN_MASK}, +{LED_TYPE_SYS, LED_TYPE_SYS_REG_MASK, LED_MODE_AMBER, LED_MODE_SYS_AMBER_MASK}, +{LED_TYPE_SYS, LED_TYPE_SYS_REG_MASK, LED_MODE_RED, LED_MODE_SYS_RED_MASK}, +{LED_TYPE_SYS, LED_TYPE_SYS_REG_MASK, LED_MODE_AMBER_FLASHING, LED_MODE_SYS_AMBER_FLASHING_MASK}, +{LED_TYPE_SYS, LED_TYPE_SYS_REG_MASK, LED_MODE_OFF, LED_MODE_SYS_OFF_MASK}, + +{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_GREEN, LED_MODE_FAN_GREEN_MASK}, +{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_AMBER, LED_MODE_FAN_AMBER_MASK}, +{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_RED, LED_MODE_FAN_RED_MASK}, +{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_OFF, LED_MODE_FAN_OFF_MASK}, + +{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 0}, +{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 0}, +{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_AMBER, LED_MODE_FANX_AMBER_MASK << 0}, +{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 0}, +{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 2}, +{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 2}, +{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_AMBER, LED_MODE_FANX_AMBER_MASK << 2}, +{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 2}, +{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 4}, +{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 4}, +{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_AMBER, LED_MODE_FANX_AMBER_MASK << 4}, +{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 4}, +{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 6}, +{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 6}, +{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_AMBER, LED_MODE_FANX_AMBER_MASK << 6}, +{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 6}, +{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 0}, +{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 0}, +{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_AMBER, LED_MODE_FANX_AMBER_MASK << 0}, +{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 0}, +}; + +struct fanx_info_s { + u8 cname; /* device name */ + enum led_type type; + u8 reg_id; /* map to led_reg & reg_val */ +}; + +static struct fanx_info_s fanx_info[] = { + {'1', LED_TYPE_FAN1, 3}, + {'2', LED_TYPE_FAN2, 3}, + {'3', LED_TYPE_FAN3, 3}, + {'4', LED_TYPE_FAN4, 3}, + {'5', LED_TYPE_FAN5, 2}, +}; + + +static int led_reg_val_to_light_mode(enum led_type type, u8 reg_val) { + int i; + + for (i = 0; i < ARRAY_SIZE(led_type_mode_data); i++) { + + if (type != led_type_mode_data[i].type) + continue; + + if ((led_type_mode_data[i].type_mask & reg_val) == + led_type_mode_data[i].mode_mask) + { + return led_type_mode_data[i].mode; + } + } + + return 0; +} + +static u8 led_light_mode_to_reg_val(enum led_type type, + enum led_light_mode mode, u8 reg_val) { + int i; + + for (i = 0; i < ARRAY_SIZE(led_type_mode_data); i++) { + if (type != led_type_mode_data[i].type) + continue; + + if (mode != led_type_mode_data[i].mode) + continue; + + reg_val = led_type_mode_data[i].mode_mask | + (reg_val & (~led_type_mode_data[i].type_mask)); + break; + } + + return reg_val; +} + +static void cs5435_54p_led_update(void) +{ + mutex_lock(&ledctl->update_lock); + + if (time_after(jiffies, ledctl->last_updated + HZ + HZ / 2) + || !ledctl->valid) { + int i; + + dev_dbg(&ledctl->pdev->dev, "Starting cs5435_54p_led update\n"); + + /* Update LED data + */ + for (i = 0; i < ARRAY_SIZE(ledctl->reg_val); i++) { + u8 status; + cig_cpld_read_register(led_reg[i], &status); + + if (status < 0) { + ledctl->valid = 0; + dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", led_reg[i], status); + goto exit; + } + else + { + ledctl->reg_val[i] = status; + } + } + + ledctl->last_updated = jiffies; + ledctl->valid = 1; + } + +exit: + mutex_unlock(&ledctl->update_lock); +} + +static void cs5435_54p_led_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode, + u8 reg, enum led_type type) +{ + u8 reg_val; + mutex_lock(&ledctl->update_lock); + + cig_cpld_read_register(reg, ®_val); + if (reg_val < 0) { + dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", reg, reg_val); + goto exit; + } + + reg_val = led_light_mode_to_reg_val(type, led_light_mode, reg_val); + + cig_cpld_write_register(reg, reg_val); + + /* to prevent the slow-update issue */ + ledctl->valid = 0; + +exit: + mutex_unlock(&ledctl->update_lock); +} + +static void cs5435_54p_led_fanx_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + enum led_type led_type1; + int reg_id; + int i, nsize; + int ncount = sizeof(fanx_info)/sizeof(struct fanx_info_s); + + for(i=0;iname); + + if (led_cdev->name[nsize-1] == fanx_info[i].cname) + { + led_type1 = fanx_info[i].type; + reg_id = fanx_info[i].reg_id; + + cs5435_54p_led_set(led_cdev, led_light_mode, led_reg[reg_id], led_type1); + return; + } + } +} + + +static enum led_brightness cs5435_54p_led_fanx_get(struct led_classdev *cdev) +{ + enum led_type led_type1; + int reg_id; + int i, nsize; + int ncount = sizeof(fanx_info)/sizeof(struct fanx_info_s); + + for(i=0;iname); + + if (cdev->name[nsize-1] == fanx_info[i].cname) + { + led_type1 = fanx_info[i].type; + reg_id = fanx_info[i].reg_id; + cs5435_54p_led_update(); + return led_reg_val_to_light_mode(led_type1, ledctl->reg_val[reg_id]); + } + } + + return led_reg_val_to_light_mode(LED_TYPE_FAN1, ledctl->reg_val[5]); +} + + +static void cs5435_54p_led_psu1_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + cs5435_54p_led_set(led_cdev, led_light_mode, led_reg[1], LED_TYPE_PSU1); +} + +static enum led_brightness cs5435_54p_led_psu1_get(struct led_classdev *cdev) +{ + cs5435_54p_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_PSU1, ledctl->reg_val[1]); +} + +static void cs5435_54p_led_psu2_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + cs5435_54p_led_set(led_cdev, led_light_mode, led_reg[1], LED_TYPE_PSU2); +} + +static enum led_brightness cs5435_54p_led_psu2_get(struct led_classdev *cdev) +{ + cs5435_54p_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_PSU2, ledctl->reg_val[1]); +} + +static void cs5435_54p_led_sys_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + cs5435_54p_led_set(led_cdev, led_light_mode,led_reg[0], LED_TYPE_SYS); +} + +static enum led_brightness cs5435_54p_led_sys_get(struct led_classdev *cdev) +{ + cs5435_54p_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_SYS, ledctl->reg_val[0]); +} + + +static enum led_brightness cs5435_54p_led_fan_get(struct led_classdev *cdev) +{ + cs5435_54p_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_FAN, ledctl->reg_val[1]); +} + +static void cs5435_54p_led_fan_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + cs5435_54p_led_set(led_cdev, led_light_mode, led_reg[1], LED_TYPE_FAN); +} + + +static struct led_classdev cs5435_54p_leds[] = { + [LED_TYPE_SYS] = { + .name = "cs5435_54p_led::sys", + .default_trigger = "unused", + .brightness_set = cs5435_54p_led_sys_set, + .brightness_get = cs5435_54p_led_sys_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN] = { + .name = "cs5435_54p_led::fan", + .default_trigger = "unused", + .brightness_set = cs5435_54p_led_fan_set, + .brightness_get = cs5435_54p_led_fan_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + + [LED_TYPE_PSU1] = { + .name = "cs5435_54p_led::psu1", + .default_trigger = "unused", + .brightness_set = cs5435_54p_led_psu1_set, + .brightness_get = cs5435_54p_led_psu1_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_PSU2] = { + .name = "cs5435_54p_led::psu2", + .default_trigger = "unused", + .brightness_set = cs5435_54p_led_psu2_set, + .brightness_get = cs5435_54p_led_psu2_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + + [LED_TYPE_FAN1] = { + .name = "cs5435_54p_led::fan1", + .default_trigger = "unused", + .brightness_set = cs5435_54p_led_fanx_set, + .brightness_get = cs5435_54p_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN2] = { + .name = "cs5435_54p_led::fan2", + .default_trigger = "unused", + .brightness_set = cs5435_54p_led_fanx_set, + .brightness_get = cs5435_54p_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN3] = { + .name = "cs5435_54p_led::fan3", + .default_trigger = "unused", + .brightness_set = cs5435_54p_led_fanx_set, + .brightness_get = cs5435_54p_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN4] = { + .name = "cs5435_54p_led::fan4", + .default_trigger = "unused", + .brightness_set = cs5435_54p_led_fanx_set, + .brightness_get = cs5435_54p_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN5] = { + .name = "cs5435_54p_led::fan5", + .default_trigger = "unused", + .brightness_set = cs5435_54p_led_fanx_set, + .brightness_get = cs5435_54p_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + } +}; + +static int cs5435_54p_led_suspend(struct platform_device *dev, + pm_message_t state) +{ + int i = 0; + + for (i = 0; i < ARRAY_SIZE(cs5435_54p_leds); i++) { + led_classdev_suspend(&cs5435_54p_leds[i]); + } + + return 0; +} + +static int cs5435_54p_led_resume(struct platform_device *dev) +{ + int i = 0; + + for (i = 0; i < ARRAY_SIZE(cs5435_54p_leds); i++) { + led_classdev_resume(&cs5435_54p_leds[i]); + } + + return 0; +} + +static int cs5435_54p_led_probe(struct platform_device *pdev) +{ + int ret, i; + + for (i = 0; i < ARRAY_SIZE(cs5435_54p_leds); i++) { + ret = led_classdev_register(&pdev->dev, &cs5435_54p_leds[i]); + + if (ret < 0) + break; + } + + /* Check if all LEDs were successfully registered */ + if (i != ARRAY_SIZE(cs5435_54p_leds)) { + int j; + + /* only unregister the LEDs that were successfully registered */ + for (j = 0; j < i; j++) { + led_classdev_unregister(&cs5435_54p_leds[i]); + } + } + + return ret; +} + +static int cs5435_54p_led_remove(struct platform_device *pdev) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(cs5435_54p_leds); i++) { + led_classdev_unregister(&cs5435_54p_leds[i]); + } + + return 0; +} + +static struct platform_driver cs5435_54p_led_driver = { + .probe = cs5435_54p_led_probe, + .remove = cs5435_54p_led_remove, + .suspend = cs5435_54p_led_suspend, + .resume = cs5435_54p_led_resume, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, +}; + +static int cs5435_54p_led_default(void) +{ + cig_cpld_write_register(0x30, 0x40);// system green led solid on +} + +static int __init cs5435_54p_led_init(void) +{ + int ret; + + ret = platform_driver_register(&cs5435_54p_led_driver); + if (ret < 0) { + goto exit; + } + + ledctl = kzalloc(sizeof(struct cs5435_54p_led_data), GFP_KERNEL); + if (!ledctl) { + ret = -ENOMEM; + platform_driver_unregister(&cs5435_54p_led_driver); + goto exit; + } + + mutex_init(&ledctl->update_lock); + + ledctl->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(ledctl->pdev)) { + ret = PTR_ERR(ledctl->pdev); + platform_driver_unregister(&cs5435_54p_led_driver); + kfree(ledctl); + goto exit; + } + + cs5435_54p_led_default(); + +exit: + return ret; +} + +static void __exit cs5435_54p_led_exit(void) +{ + platform_device_unregister(ledctl->pdev); + platform_driver_unregister(&cs5435_54p_led_driver); + kfree(ledctl); +} + +module_init(cs5435_54p_led_init); +module_exit(cs5435_54p_led_exit); + +MODULE_AUTHOR("Zhang Peng "); +MODULE_DESCRIPTION("cs5435_54p_led driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-psu.c b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-psu.c new file mode 100644 index 000000000000..5a7942653fc3 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-psu.c @@ -0,0 +1,946 @@ +/* + * A hwmon driver for the CIG cs5435-54P Power Module + * + * Copyright (C) 2018 Cambridge, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 "i2c-algo-lpc.h" + + + +#define MAX_FAN_DUTY_CYCLE 100 + +/* Address scanned */ +static const unsigned short normal_i2c[] = {I2C_CLIENT_END }; + +/* This is additional data */ +struct cs5435_54p_psu_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; + unsigned long last_updated; /* In jiffies */ + + /* Registers value */ + u8 vout_mode; + u16 v_in; + u16 v_out; + u16 i_in; + u16 i_out; + u16 p_in; + u16 p_out; + u16 temp_input[3]; + u8 temp_fault; + u8 fan_fault; + u16 fan_duty_cycle[2]; + u16 fan_speed[2]; + u8 mfr_id[8]; + u8 mfr_model[20]; + u8 mfr_serial[20]; + u8 psu_is_present; + u8 psu_is_good; + struct i2c_client *client; + struct bin_attribute *bin; /* eeprom data */ +}; + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask); +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *dev_attr, const char *buf, size_t count); +static ssize_t for_linear_data(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_fan_fault(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_fan_warning(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_temp_fault(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_temp_warning(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_vout_data(struct device *dev, struct device_attribute *dev_attr, char *buf); +static int cs5435_54p_psu_read_byte(struct i2c_client *client, u8 reg); +static int cs5435_54p_psu_read_word(struct i2c_client *client, u8 reg); +static int cs5435_54p_psu_write_word(struct i2c_client *client, u8 reg, u16 value); +static int cs5435_54p_psu_read_block(struct i2c_client *client, u8 command, u8 *data, int data_len); +static struct cs5435_54p_psu_data *cs5435_54p_psu_update_device(struct device *dev); +static ssize_t for_ascii(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_status(struct device *dev, struct device_attribute *dev_attr, char *buf); + +enum cs5435_54p_psu_sysfs_attributes { + PSU_V_IN, + PSU_V_OUT, + PSU_I_IN, + PSU_I_OUT, + PSU_P_IN, + PSU_P_OUT, + PSU_TEMP1_INPUT, + PSU_TEMP2_INPUT, + PSU_TEMP3_INPUT, + PSU_TEMP_FAULT, + PSU_TEMP_WARN, + PSU_FAN1_FAULT, + PSU_FAN1_WARN, + PSU_FAN1_DUTY_CYCLE, + PSU_FAN1_SPEED, + PSU_MFR_ID, + PSU_MFR_MODEL, + PSU_MFR_SERIAL, + PSU_PRESENT, + PSU_P_GOOD, +}; + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask) +{ + u16 valid_data = data & mask; + + bool is_negative = valid_data >> (valid_bit - 1); + return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; +} + +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute \ + *dev_attr, const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct i2c_client *client = to_i2c_client(dev); + struct cs5435_54p_psu_data *data = i2c_get_clientdata(client); + int nr = (attr->index == PSU_FAN1_DUTY_CYCLE) ? 0 : 1; + long speed; + int error; + + if (data->valid != 1) + { + return -ENODEV; + } + + error = kstrtol(buf, 10, &speed); + if (error) + return error; + + if (speed < 0 || speed > MAX_FAN_DUTY_CYCLE) + return -EINVAL; + + + mutex_lock(&data->update_lock); + data->fan_duty_cycle[nr] = speed; + cs5435_54p_psu_write_word(client, 0x3B + nr, data->fan_duty_cycle[nr]); + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t for_linear_data(struct device *dev, struct device_attribute *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs5435_54p_psu_data *data = cs5435_54p_psu_update_device(dev); + + u16 value = 0; + int exponent, mantissa; + int multiplier = 1000; + + if (data->valid != 1) + { + return -ENODEV; + } + + switch (attr->index) { + case PSU_V_IN: + value = data->v_in; + break; + case PSU_I_IN: + value = data->i_in; + break; + case PSU_I_OUT: + value = data->i_out; + break; + case PSU_P_IN: + value = data->p_in; + break; + case PSU_P_OUT: + value = data->p_out; + break; + case PSU_TEMP1_INPUT: + value = data->temp_input[0]; + break; + case PSU_TEMP2_INPUT: + value = data->temp_input[1]; + break; + case PSU_TEMP3_INPUT: + value = data->temp_input[2]; + break; + case PSU_FAN1_DUTY_CYCLE: + multiplier = 1; + value = data->fan_duty_cycle[0]; + break; + case PSU_FAN1_SPEED: + multiplier = 1; + value = data->fan_speed[0]; + break; + default: + break; + } + + exponent = two_complement_to_int(value >> 11, 5, 0x1f); + mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); + + return (exponent >= 0) ? sprintf(buf, "%d\n", \ + (mantissa << exponent) * multiplier) : \ + sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); +} + +static ssize_t for_fan_fault(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs5435_54p_psu_data *data = cs5435_54p_psu_update_device(dev); + + if (data->valid != 1) + { + return -ENODEV; + } + + u8 shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6; + + return sprintf(buf, "%d\n", data->fan_fault >> shift); +} + +static ssize_t for_fan_warning(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs5435_54p_psu_data *data = cs5435_54p_psu_update_device(dev); + + if (data->valid != 1) + { + return -ENODEV; + } + + u8 shift = (attr->index == PSU_FAN1_WARN) ? 5 : 4; + + return sprintf(buf, "%d\n", data->fan_fault >> shift); +} + +static ssize_t for_temp_fault(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs5435_54p_psu_data *data = cs5435_54p_psu_update_device(dev); + + if (data->valid != 1) + { + return -ENODEV; + } + + + + return sprintf(buf, "%d\n", data->temp_fault >> 7); +} + +static ssize_t for_temp_warning(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs5435_54p_psu_data *data = cs5435_54p_psu_update_device(dev); + if (data->valid != 1) + { + return -ENODEV; + } + + + return sprintf(buf, "%d\n", data->temp_fault >> 6); +} +static ssize_t for_vout_data(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct cs5435_54p_psu_data *data = cs5435_54p_psu_update_device(dev); + int exponent, mantissa; + int multiplier = 1000; + if (data->valid != 1) + { + return -ENODEV; + } + + + exponent = two_complement_to_int(data->vout_mode, 5, 0x1f); + mantissa = data->v_out; + + return (exponent > 0) ? sprintf(buf, "%d\n", \ + (mantissa << exponent) * multiplier) : \ + sprintf(buf, "%d\n", ((mantissa * multiplier) >> (-exponent))); +} + +static ssize_t for_ascii(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs5435_54p_psu_data *data = cs5435_54p_psu_update_device(dev); + u8 *ptr = NULL; + + if (data->valid != 1) + { + return -ENODEV; + } + + switch (attr->index) { + case PSU_MFR_ID: + ptr = data->mfr_id + 1; + break; + case PSU_MFR_MODEL: + ptr = data->mfr_model + 1; + break; + case PSU_MFR_SERIAL: + ptr = data->mfr_serial + 1; + break; + default: + return 0; + } + return sprintf(buf, "%s\n", ptr); +} + + +static ssize_t for_status(struct device *dev, struct device_attribute *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs5435_54p_psu_data *data = cs5435_54p_psu_update_device(dev); + u8 *ptr = NULL; + + u8 status = 0; + + if (attr->index == PSU_PRESENT) { + status = data->psu_is_present; + } + else { /* PSU_POWER_GOOD */ + if (!data->valid) { + return -ENODEV; + } + + status = data->psu_is_good; + } + + return sprintf(buf, "%d\n", status); +} + + +static int cs5435_54p_psu_read_byte(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_byte_data(client, reg); +} + +static int cs5435_54p_psu_read_word(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_word_data(client, reg); +} + +static int cs5435_54p_psu_write_word(struct i2c_client *client, u8 reg, \ + u16 value) +{ + union i2c_smbus_data data; + data.word = value; + return i2c_smbus_xfer(client->adapter, client->addr, + client->flags |= I2C_CLIENT_PEC, + I2C_SMBUS_WRITE, reg, + I2C_SMBUS_WORD_DATA, &data); + +} + +static int cs5435_54p_psu_read_block(struct i2c_client *client, u8 command, \ + u8 *data, int data_len) +{ + int result = i2c_smbus_read_i2c_block_data(client, command, data_len, + data); + if (unlikely(result < 0)) + goto abort; + if (unlikely(result != data_len)) { + result = -EIO; + goto abort; + } + + result = 0; +abort: + return result; + +} + +struct reg_data_byte { + u8 reg; + u8 *value; +}; + +struct reg_data_word { + u8 reg; + u16 *value; +}; + + + +#define EEPROM_NAME "psu_eeprom" +#define EEPROM_SIZE 256 /* 256 byte eeprom */ + +/* Platform dependent --- */ +static ssize_t psu_eeprom_write(struct i2c_client *client, u8 command, const char *data, + int data_len) +{ + int status, retry = 3; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + status = i2c_smbus_write_i2c_block_data(client, command, data_len, data); + if (unlikely(status < 0)) { + msleep(100); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + return status; + } + + return data_len; + +} + + +static ssize_t psu_page_write(struct i2c_client *client,const char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + return count; + } + + /* + * Write data to chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + + + while (count) { + ssize_t status; + + status = psu_eeprom_write(client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + buf += status; + off += status; + count -= status; + retval += status; + } + + + return retval; +} + + + +static ssize_t psu_bin_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + int present; + struct cs5435_54p_psu_data *data; + ssize_t retval = 0; + struct i2c_client *client; + + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + client = to_i2c_client(container_of(kobj, struct device, kobj)); + + mutex_lock(&data->update_lock); + retval = psu_page_write(client, buf, off, count); + mutex_unlock(&data->update_lock); + return retval; +} + + +static ssize_t psu_eeprom_read(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ + int status, retry = 3; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + status = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + if (unlikely(status < 0)) { + msleep(100); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + goto abort; + } + if (unlikely(status != data_len)) { + status = -EIO; + goto abort; + } + +abort: + return status; +} + + + +static ssize_t psu_page_read(struct i2c_client *client,char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + printk("Count = 0, return"); + return count; + } + /* + * Read data from chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + + + while (count) { + ssize_t status; + + status = psu_eeprom_read(client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + + buf += status; + off += status; + count -= status; + retval += status; + } + + + return retval; + +} + + +static ssize_t psu_bin_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + int present; + struct cs5435_54p_psu_data *data; + struct i2c_client *client; + ssize_t retval = 0; + + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + client = to_i2c_client(container_of(kobj, struct device, kobj)); + mutex_lock(&data->update_lock); + retval = psu_page_read(client, buf, off, count); + mutex_unlock(&data->update_lock); + + return retval; +} + + + +static int psu_sysfs_eeprom_init(struct kobject *kobj, struct bin_attribute *eeprom) +{ + int err; + + sysfs_bin_attr_init(eeprom); + eeprom->attr.name = EEPROM_NAME; + eeprom->attr.mode = S_IWUSR | S_IRUGO; + eeprom->read = psu_bin_read; + eeprom->write = psu_bin_write; + eeprom->size = EEPROM_SIZE; + + /* Create eeprom file */ + err = sysfs_create_bin_file(kobj, eeprom); + if (err) { + return err; + } + + return 0; +} + + +static int psu_sysfs_eeprom_cleanup(struct kobject *kobj, struct bin_attribute *eeprom) +{ + sysfs_remove_bin_file(kobj, eeprom); + return 0; +} + + +static int psu_i2c_check_functionality(struct i2c_client *client) +{ + return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_I2C_BLOCK); +} + + + +static int psu_eeprom_probe(struct i2c_client *client, const struct i2c_device_id *dev_id) +{ + int status; + + struct cs5435_54p_psu_data *data; + + if (!psu_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + mutex_init(&data->update_lock); + + data->bin = kzalloc(sizeof(struct bin_attribute), GFP_KERNEL); + if (!data->bin) { + status = -ENOMEM; + goto eeprom_bin_error; + } + + /* init eeprom */ + status = psu_sysfs_eeprom_init(&client->dev.kobj, data->bin); + if (status) { + status = -ENOMEM; + goto sys_init_error; + } + + dev_info(&client->dev, "psu eeprom '%s'\n", client->name); + + return 0; + + sys_init_error: + kfree(data->bin); + + eeprom_bin_error: + kfree(data); + + exit: + return status; +} + + + + +static struct cs5435_54p_psu_data *cs5435_54p_psu_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cs5435_54p_psu_data *data = i2c_get_clientdata(client); + + + mutex_lock(&data->update_lock); + + + if (time_after(jiffies, data->last_updated)) { + int i, status; + u8 command; + struct reg_data_byte regs_byte[] = { + {0x20, &data->vout_mode}, + {0x81, &data->fan_fault}, + {0x7d, &data->temp_fault}, + }; + struct reg_data_word regs_word[] = { + {0x88, &data->v_in}, + {0x8b, &data->v_out}, + {0x89, &data->i_in}, + {0x8c, &data->i_out}, + {0x96, &data->p_out}, + {0x97, &data->p_in}, + {0x8d, &(data->temp_input[0])}, + {0x8e, &(data->temp_input[1])}, + {0x3b, &(data->fan_duty_cycle[0])}, + {0x90, &(data->fan_speed[0])}, + }; + data->valid = 1; + + dev_dbg(&client->dev, "start data update\n"); + + /* one milliseconds from now */ + data->last_updated = jiffies + HZ / 1000; + + for (i = 0; i < ARRAY_SIZE(regs_byte); i++) { + status = cs5435_54p_psu_read_byte(client, + regs_byte[i].reg); + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_byte[i].reg, status); + *(regs_byte[i].value) = 0; + data->valid = 0; + } else { + *(regs_byte[i].value) = status; + } + } + + for (i = 0; i < ARRAY_SIZE(regs_word); i++) + { + status = cs5435_54p_psu_read_word(client,regs_word[i].reg); + if (status < 0) + { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_word[i].reg, status); + *(regs_word[i].value) = 0; + data->valid = 0; + } + else + { + *(regs_word[i].value) = status; + } + } + + command = 0x99; /* PSU mfr_id */ + status = cs5435_54p_psu_read_block(client, command, + data->mfr_id, ARRAY_SIZE(data->mfr_id) - 1); + data->mfr_id[ARRAY_SIZE(data->mfr_id) - 1] = '\0'; + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + memset(data->mfr_id, 0, sizeof(data->mfr_id)); + data->valid = 0; + } + + command = 0x9a; /* PSU mfr_model */ + status = cs5435_54p_psu_read_block(client, command, + data->mfr_model, ARRAY_SIZE(data->mfr_model) - 1); + data->mfr_model[ARRAY_SIZE(data->mfr_model) - 1] = '\0'; + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + memset(data->mfr_model, 0, sizeof(data->mfr_id)); + data->valid = 0; + } + + command = 0x9e; /* PSU mfr_serial */ + status = cs5435_54p_psu_read_block(client, command, + data->mfr_serial, ARRAY_SIZE(data->mfr_serial) - 1); + data->mfr_serial[ARRAY_SIZE(data->mfr_serial) - 1] = '\0'; + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + memset(data->mfr_serial, 0, sizeof(data->mfr_id)); + data->valid = 0; + } + + data->psu_is_present = strlen(data->mfr_id) > 1 ? 1:0; + if(data->psu_is_present) + { + data->psu_is_good = ((data->fan_fault) || (data->temp_fault))? 0:1; + } + else + { + data->valid = 0; + data->psu_is_good = 0; + } + } + + mutex_unlock(&data->update_lock); + + return data; + +} + +/* sysfs attributes for hwmon */ +static SENSOR_DEVICE_ATTR(psu_v_in, S_IRUGO, for_linear_data, NULL, PSU_V_IN); +static SENSOR_DEVICE_ATTR(psu_v_out, S_IRUGO, for_vout_data, NULL, PSU_V_OUT); +static SENSOR_DEVICE_ATTR(psu_i_in, S_IRUGO, for_linear_data, NULL, PSU_I_IN); +static SENSOR_DEVICE_ATTR(psu_i_out, S_IRUGO, for_linear_data, NULL, PSU_I_OUT); +static SENSOR_DEVICE_ATTR(psu_p_in, S_IRUGO, for_linear_data, NULL, PSU_P_IN); +static SENSOR_DEVICE_ATTR(psu_p_out, S_IRUGO, for_linear_data, NULL, PSU_P_OUT); +static SENSOR_DEVICE_ATTR(psu_temp1_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP1_INPUT); +static SENSOR_DEVICE_ATTR(psu_temp2_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP2_INPUT); +static SENSOR_DEVICE_ATTR(psu_temp3_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP3_INPUT); +static SENSOR_DEVICE_ATTR(psu_temp_fault, S_IRUGO, for_temp_fault, NULL, PSU_TEMP_FAULT); +static SENSOR_DEVICE_ATTR(psu_temp_warning, S_IRUGO, for_temp_warning, NULL, PSU_TEMP_WARN); +static SENSOR_DEVICE_ATTR(psu_fan1_fault, S_IRUGO, for_fan_fault, NULL, PSU_FAN1_FAULT); +static SENSOR_DEVICE_ATTR(psu_fan1_warning, S_IRUGO, for_fan_warning, NULL, PSU_FAN1_WARN); +static SENSOR_DEVICE_ATTR(psu_fan1_duty_cycle_percentage, S_IWUSR | S_IRUGO, for_linear_data, set_fan_duty_cycle, PSU_FAN1_DUTY_CYCLE); +static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm, S_IRUGO, for_linear_data, NULL, PSU_FAN1_SPEED); +static SENSOR_DEVICE_ATTR(psu_mfr_id, S_IRUGO, for_ascii, NULL, PSU_MFR_ID); +static SENSOR_DEVICE_ATTR(psu_mfr_model, S_IRUGO, for_ascii, NULL, PSU_MFR_MODEL); +static SENSOR_DEVICE_ATTR(psu_mfr_serial, S_IRUGO, for_ascii, NULL, PSU_MFR_SERIAL); +static SENSOR_DEVICE_ATTR(psu_present, S_IRUGO, for_status, NULL, PSU_PRESENT); +static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, for_status, NULL, PSU_P_GOOD); + + + +static struct attribute *cs5435_54p_psu_attributes[] = { + &sensor_dev_attr_psu_v_in.dev_attr.attr, + &sensor_dev_attr_psu_v_out.dev_attr.attr, + &sensor_dev_attr_psu_i_in.dev_attr.attr, + &sensor_dev_attr_psu_i_out.dev_attr.attr, + &sensor_dev_attr_psu_p_in.dev_attr.attr, + &sensor_dev_attr_psu_p_out.dev_attr.attr, + &sensor_dev_attr_psu_temp1_input.dev_attr.attr, + &sensor_dev_attr_psu_temp2_input.dev_attr.attr, + &sensor_dev_attr_psu_temp3_input.dev_attr.attr, + &sensor_dev_attr_psu_temp_fault.dev_attr.attr, + &sensor_dev_attr_psu_temp_warning.dev_attr.attr, + &sensor_dev_attr_psu_fan1_fault.dev_attr.attr, + &sensor_dev_attr_psu_fan1_warning.dev_attr.attr, + &sensor_dev_attr_psu_fan1_duty_cycle_percentage.dev_attr.attr, + &sensor_dev_attr_psu_fan1_speed_rpm.dev_attr.attr, + &sensor_dev_attr_psu_mfr_id.dev_attr.attr, + &sensor_dev_attr_psu_mfr_model.dev_attr.attr, + &sensor_dev_attr_psu_mfr_serial.dev_attr.attr, + &sensor_dev_attr_psu_present.dev_attr.attr, + &sensor_dev_attr_psu_power_good.dev_attr.attr, + NULL +}; + +static const struct attribute_group cs5435_54p_psu_group = { + .attrs = cs5435_54p_psu_attributes, +}; + + +static int psu_register_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int status; + + + struct cs5435_54p_psu_data *data; + + if (!psu_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + mutex_init(&data->update_lock); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &cs5435_54p_psu_group); + if (status) + goto exit_sysfs_create_group; + + cs5435_54p_sysfs_add_client(client); + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_hwmon_device_register; + } + + /* init eeprom */ + + return 0; + + exit_hwmon_device_register: + sysfs_remove_group(&client->dev.kobj, &cs5435_54p_psu_group); + exit_sysfs_create_group: + kfree(data); + exit: + return status; + +} + + +static int cs5435_54p_psu_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int status; + + if((client->addr == 0x52) ||(client->addr == 0x53)) + { + status = psu_eeprom_probe(client, id); + } + else if((client->addr == 0x5a) ||(client->addr == 0x5b)) + { + status = psu_register_probe(client, id); + } + return status; +} + +static int cs5435_54p_psu_remove(struct i2c_client *client) +{ + cs5435_54p_sysfs_remove_client(client); + + if((client->addr == 0x52) ||(client->addr == 0x53)) + { + struct cs5435_54p_psu_data *data; + data = i2c_get_clientdata(client); + psu_sysfs_eeprom_cleanup(&client->dev.kobj,data->bin); + kfree(data); + } + else if((client->addr == 0x5a) ||(client->addr == 0x5b)) + { + struct cs5435_54p_psu_data *data; + data = i2c_get_clientdata(client); + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &cs5435_54p_psu_group); + kfree(data); + } + + return 0; +} + +enum psu_index +{ + cs5435_54p_psu1, + cs5435_54p_psu2 +}; + +static const struct i2c_device_id cs5435_54p_psu_id[] = { + { "cs5435_54p_psu1", cs5435_54p_psu1 }, + { "cs5435_54p_psu2", cs5435_54p_psu2 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, cs5435_54p_psu_id); + +static struct i2c_driver cs5435_54p_psu_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "cs5435_54p_psu", + }, + .probe = cs5435_54p_psu_probe, + .remove = cs5435_54p_psu_remove, + .id_table = cs5435_54p_psu_id, + .address_list = normal_i2c, +}; + +module_i2c_driver(cs5435_54p_psu_driver); + +MODULE_AUTHOR("Zhang Peng "); +MODULE_DESCRIPTION("cs5435_54p_psu driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-sfp.c b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-sfp.c new file mode 100644 index 000000000000..3bdb3d2de791 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-sfp.c @@ -0,0 +1,1713 @@ +/* + * A hwmon driver for the CIG cs5435-54P SFP Module + * + * Copyright (C) 2018 Cambridge, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 "i2c-algo-lpc.h" + +#define DRIVER_NAME "cs5435_54p_sfp" /* Platform dependent */ + +#define DEBUG_MODE 0 + +#if (DEBUG_MODE == 1) + #define DEBUG_PRINT(fmt, args...) \ + printk (KERN_INFO "%s:%s[%d]: " fmt "\r\n", __FILE__, __FUNCTION__, __LINE__, ##args) +#else + #define DEBUG_PRINT(fmt, args...) +#endif + +#define EEPROM_NAME "sfp_eeprom" +#define EEPROM_SIZE 256 /* 256 byte eeprom */ +#define BIT_INDEX(i) (1ULL << (i)) +#define USE_I2C_BLOCK_READ 1 /* Platform dependent */ +#define I2C_RW_RETRY_COUNT 3 +#define I2C_RW_RETRY_INTERVAL 100 /* ms */ + +#define SFP_EEPROM_A0_I2C_ADDR (0xA0 >> 1) +#define SFP_EEPROM_A2_I2C_ADDR (0xA2 >> 1) + +#define SFF8024_PHYSICAL_DEVICE_ID_ADDR 0x0 +#define SFF8024_DEVICE_ID_SFP 0x3 +#define SFF8024_DEVICE_ID_QSFP 0xC +#define SFF8024_DEVICE_ID_QSFP_PLUS 0xD +#define SFF8024_DEVICE_ID_QSFP28 0x11 + +#define SFF8472_DIAG_MON_TYPE_ADDR 92 +#define SFF8472_DIAG_MON_TYPE_DDM_MASK 0x40 +#define SFF8472_10G_ETH_COMPLIANCE_ADDR 0x3 +#define SFF8472_10G_BASE_MASK 0xF0 + +#define SFF8436_RX_LOS_ADDR 3 +#define SFF8436_TX_FAULT_ADDR 4 +#define SFF8436_TX_DISABLE_ADDR 86 +#define QSFP_RESET_ADDR 0x1b +#define QSFP_INTER_ADDR 0x1a +#define QSFP_LPMODE_ADDR 0x1c + +static ssize_t show_port_number(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_port_type(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_present(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t sfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t sfp_set_tx_disable(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t qsfp_set_tx_disable(struct device *dev, struct device_attribute *da, const char *buf, size_t count);; +static ssize_t sfp_show_ddm_implemented(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t sfp_eeprom_read(struct i2c_client *, u8, u8 *,int); +static ssize_t sfp_eeprom_write(struct i2c_client *, u8 , const char *,int); +extern int cig_cpld_read_register(u8 reg_off, u8 *val); +extern int cig_cpld_write_register(u8 reg_off, u8 val); + +static ssize_t qsfp_reset_read(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_reset_write(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t qsfp_inter_read(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_lpmode_read(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_lpmode_write(struct device *dev, struct device_attribute *da, const char *buf, size_t count); + +enum sfp_sysfs_attributes { + PRESENT, + PRESENT_ALL, + PORT_NUMBER, + PORT_TYPE, + DDM_IMPLEMENTED, + TX_FAULT, + TX_FAULT1, + TX_FAULT2, + TX_FAULT3, + TX_FAULT4, + TX_DISABLE, + TX_DISABLE1, + TX_DISABLE2, + TX_DISABLE3, + TX_DISABLE4, + RX_LOS, + RX_LOS1, + RX_LOS2, + RX_LOS3, + RX_LOS4, + RX_LOS_ALL, + QSFPRESET, + QSFPINT, + QSFPLPMODE +}; + +/* SFP/QSFP common attributes for sysfs */ +static SENSOR_DEVICE_ATTR(sfp_port_number, S_IRUGO, show_port_number, NULL, PORT_NUMBER); +static SENSOR_DEVICE_ATTR(sfp_port_type, S_IRUGO, show_port_type, NULL, PORT_TYPE); +static SENSOR_DEVICE_ATTR(sfp_is_present, S_IRUGO, show_present, NULL, PRESENT); +static SENSOR_DEVICE_ATTR(sfp_is_present_all, S_IRUGO, show_present, NULL, PRESENT_ALL); +static SENSOR_DEVICE_ATTR(sfp_rx_los, S_IRUGO, sfp_show_tx_rx_status, NULL, RX_LOS); +static SENSOR_DEVICE_ATTR(sfp_tx_disable, S_IWUSR | S_IRUGO, sfp_show_tx_rx_status, sfp_set_tx_disable, TX_DISABLE); +static SENSOR_DEVICE_ATTR(sfp_tx_fault, S_IRUGO, sfp_show_tx_rx_status, NULL, TX_FAULT); + +/* QSFP attributes for sysfs */ +static SENSOR_DEVICE_ATTR(sfp_rx_los1, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS1); +static SENSOR_DEVICE_ATTR(sfp_rx_los2, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS2); +static SENSOR_DEVICE_ATTR(sfp_rx_los3, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS3); +static SENSOR_DEVICE_ATTR(sfp_rx_los4, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS4); +static SENSOR_DEVICE_ATTR(sfp_tx_disable1, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE1); +static SENSOR_DEVICE_ATTR(sfp_tx_disable2, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE2); +static SENSOR_DEVICE_ATTR(sfp_tx_disable3, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE3); +static SENSOR_DEVICE_ATTR(sfp_tx_disable4, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE4); +static SENSOR_DEVICE_ATTR(sfp_tx_fault1, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT1); +static SENSOR_DEVICE_ATTR(sfp_tx_fault2, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT2); +static SENSOR_DEVICE_ATTR(sfp_tx_fault3, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT3); +static SENSOR_DEVICE_ATTR(sfp_tx_fault4, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT4); +static SENSOR_DEVICE_ATTR(sfp_reset, S_IWUSR | S_IRUGO, qsfp_reset_read, qsfp_reset_write, QSFPRESET); +static SENSOR_DEVICE_ATTR(sfp_inter, S_IRUGO, qsfp_inter_read, NULL, QSFPINT); +static SENSOR_DEVICE_ATTR(sfp_lpmode, S_IWUSR | S_IRUGO, qsfp_lpmode_read, qsfp_lpmode_write, QSFPLPMODE); +static struct attribute *qsfp_attributes[] = { + &sensor_dev_attr_sfp_port_number.dev_attr.attr, + &sensor_dev_attr_sfp_port_type.dev_attr.attr, + &sensor_dev_attr_sfp_is_present.dev_attr.attr, + &sensor_dev_attr_sfp_is_present_all.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los1.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los2.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los3.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los4.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable1.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable2.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable3.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable4.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault1.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault2.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault3.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault4.dev_attr.attr, + &sensor_dev_attr_sfp_reset.dev_attr.attr, + &sensor_dev_attr_sfp_inter.dev_attr.attr, + &sensor_dev_attr_sfp_lpmode.dev_attr.attr, + NULL +}; + +/* SFP msa attributes for sysfs */ +static SENSOR_DEVICE_ATTR(sfp_ddm_implemented, S_IRUGO, sfp_show_ddm_implemented, NULL, DDM_IMPLEMENTED); +static SENSOR_DEVICE_ATTR(sfp_rx_los_all, S_IRUGO, sfp_show_tx_rx_status, NULL, RX_LOS_ALL); +static struct attribute *sfp_msa_attributes[] = { + &sensor_dev_attr_sfp_port_number.dev_attr.attr, + &sensor_dev_attr_sfp_port_type.dev_attr.attr, + &sensor_dev_attr_sfp_is_present.dev_attr.attr, + &sensor_dev_attr_sfp_is_present_all.dev_attr.attr, + &sensor_dev_attr_sfp_ddm_implemented.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los_all.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable.dev_attr.attr, + NULL +}; + +/* SFP ddm attributes for sysfs */ +static struct attribute *sfp_ddm_attributes[] = { + NULL +}; + +/* Platform dependent +++ */ +#define CPLD_PORT_TO_FRONT_PORT(port) (port+1) + +enum port_numbers { +cs5435_54p_sfp1, cs5435_54p_sfp2, cs5435_54p_sfp3, cs5435_54p_sfp4, +cs5435_54p_sfp5, cs5435_54p_sfp6, cs5435_54p_sfp7, cs5435_54p_sfp8, +cs5435_54p_sfp9, cs5435_54p_sfp10, cs5435_54p_sfp11, cs5435_54p_sfp12, +cs5435_54p_sfp13, cs5435_54p_sfp14, cs5435_54p_sfp15, cs5435_54p_sfp16, +cs5435_54p_sfp17, cs5435_54p_sfp18, cs5435_54p_sfp19, cs5435_54p_sfp20, +cs5435_54p_sfp21, cs5435_54p_sfp22, cs5435_54p_sfp23, cs5435_54p_sfp24, +cs5435_54p_sfp25, cs5435_54p_sfp26, cs5435_54p_sfp27, cs5435_54p_sfp28, +cs5435_54p_sfp29, cs5435_54p_sfp30, cs5435_54p_sfp31, cs5435_54p_sfp32, +cs5435_54p_sfp33, cs5435_54p_sfp34, cs5435_54p_sfp35, cs5435_54p_sfp36, +cs5435_54p_sfp37, cs5435_54p_sfp38, cs5435_54p_sfp39, cs5435_54p_sfp40, +cs5435_54p_sfp41, cs5435_54p_sfp42, cs5435_54p_sfp43, cs5435_54p_sfp44, +cs5435_54p_sfp45, cs5435_54p_sfp46, cs5435_54p_sfp47, cs5435_54p_sfp48, +cs5435_54p_sfp49, cs5435_54p_sfp50, cs5435_54p_sfp51, cs5435_54p_sfp52, +cs5435_54p_sfp53, cs5435_54p_sfp54, cs5435_54p_sfp55, cs5435_54p_sfp56 +}; + +#define I2C_DEV_ID(x) { #x, x} + +static const struct i2c_device_id sfp_device_id[] = { +I2C_DEV_ID(cs5435_54p_sfp1), +I2C_DEV_ID(cs5435_54p_sfp2), +I2C_DEV_ID(cs5435_54p_sfp3), +I2C_DEV_ID(cs5435_54p_sfp4), +I2C_DEV_ID(cs5435_54p_sfp5), +I2C_DEV_ID(cs5435_54p_sfp6), +I2C_DEV_ID(cs5435_54p_sfp7), +I2C_DEV_ID(cs5435_54p_sfp8), +I2C_DEV_ID(cs5435_54p_sfp9), +I2C_DEV_ID(cs5435_54p_sfp10), +I2C_DEV_ID(cs5435_54p_sfp11), +I2C_DEV_ID(cs5435_54p_sfp12), +I2C_DEV_ID(cs5435_54p_sfp13), +I2C_DEV_ID(cs5435_54p_sfp14), +I2C_DEV_ID(cs5435_54p_sfp15), +I2C_DEV_ID(cs5435_54p_sfp16), +I2C_DEV_ID(cs5435_54p_sfp17), +I2C_DEV_ID(cs5435_54p_sfp18), +I2C_DEV_ID(cs5435_54p_sfp19), +I2C_DEV_ID(cs5435_54p_sfp20), +I2C_DEV_ID(cs5435_54p_sfp21), +I2C_DEV_ID(cs5435_54p_sfp22), +I2C_DEV_ID(cs5435_54p_sfp23), +I2C_DEV_ID(cs5435_54p_sfp24), +I2C_DEV_ID(cs5435_54p_sfp25), +I2C_DEV_ID(cs5435_54p_sfp26), +I2C_DEV_ID(cs5435_54p_sfp27), +I2C_DEV_ID(cs5435_54p_sfp28), +I2C_DEV_ID(cs5435_54p_sfp29), +I2C_DEV_ID(cs5435_54p_sfp30), +I2C_DEV_ID(cs5435_54p_sfp31), +I2C_DEV_ID(cs5435_54p_sfp32), +I2C_DEV_ID(cs5435_54p_sfp33), +I2C_DEV_ID(cs5435_54p_sfp34), +I2C_DEV_ID(cs5435_54p_sfp35), +I2C_DEV_ID(cs5435_54p_sfp36), +I2C_DEV_ID(cs5435_54p_sfp37), +I2C_DEV_ID(cs5435_54p_sfp38), +I2C_DEV_ID(cs5435_54p_sfp39), +I2C_DEV_ID(cs5435_54p_sfp40), +I2C_DEV_ID(cs5435_54p_sfp41), +I2C_DEV_ID(cs5435_54p_sfp42), +I2C_DEV_ID(cs5435_54p_sfp43), +I2C_DEV_ID(cs5435_54p_sfp44), +I2C_DEV_ID(cs5435_54p_sfp45), +I2C_DEV_ID(cs5435_54p_sfp46), +I2C_DEV_ID(cs5435_54p_sfp47), +I2C_DEV_ID(cs5435_54p_sfp48), +I2C_DEV_ID(cs5435_54p_sfp49), +I2C_DEV_ID(cs5435_54p_sfp50), +I2C_DEV_ID(cs5435_54p_sfp51), +I2C_DEV_ID(cs5435_54p_sfp52), +I2C_DEV_ID(cs5435_54p_sfp53), +I2C_DEV_ID(cs5435_54p_sfp54), +I2C_DEV_ID(cs5435_54p_sfp55), +I2C_DEV_ID(cs5435_54p_sfp56), +{ /* LIST END */ } +}; +MODULE_DEVICE_TABLE(i2c, sfp_device_id); + +/* + * list of valid port types + * note OOM_PORT_TYPE_NOT_PRESENT to indicate no + * module is present in this port + */ +typedef enum oom_driver_port_type_e { + OOM_DRIVER_PORT_TYPE_INVALID, + OOM_DRIVER_PORT_TYPE_NOT_PRESENT, + OOM_DRIVER_PORT_TYPE_SFP, + OOM_DRIVER_PORT_TYPE_SFP_PLUS, + OOM_DRIVER_PORT_TYPE_QSFP, + OOM_DRIVER_PORT_TYPE_QSFP_PLUS, + OOM_DRIVER_PORT_TYPE_QSFP28 +} oom_driver_port_type_t; + +enum driver_type_e { + DRIVER_TYPE_SFP_MSA, + DRIVER_TYPE_SFP_DDM, + DRIVER_TYPE_QSFP +}; + +/* Each client has this additional data + */ +struct eeprom_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + struct bin_attribute bin; /* eeprom data */ +}; + +struct sfp_msa_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u64 status[6]; /* bit0:port0, bit1:port1 and so on */ + /* index 0 => tx_fail + 1 => tx_disable + 2 => rx_loss + 3 => device id + 4 => 10G Ethernet Compliance Codes + to distinguish SFP or SFP+ + 5 => DIAGNOSTIC MONITORING TYPE */ + struct eeprom_data eeprom; +}; + +struct sfp_ddm_data { + struct eeprom_data eeprom; +}; + +struct qsfp_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 status[3]; /* bit0:port0, bit1:port1 and so on */ + /* index 0 => tx_fail + 1 => tx_disable + 2 => rx_loss */ + + u8 device_id; + struct eeprom_data eeprom; +}; + +struct sfp_port_data { + struct mutex update_lock; + enum driver_type_e driver_type; + int port; /* CPLD port index */ + oom_driver_port_type_t port_type; + u64 present; /* present status, bit0:port0, bit1:port1 and so on */ + + struct sfp_msa_data *msa; + struct sfp_ddm_data *ddm; + struct qsfp_data *qsfp; + + struct i2c_client *client; +}; + +static ssize_t show_port_number(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + return sprintf(buf, "%d\n", CPLD_PORT_TO_FRONT_PORT(data->port)); +} + + + +static int cig_cpld_write_sfp_register(u8 sfp_reg_addr, u8 sfp_write_reg_data) +{ + u8 sfp_read_status = 0; + u8 wait_time_out = WAIT_TIME_OUT_COUNT; + + cig_cpld_write_register(ADDR_REG_SFP_STATUS_ADDR, sfp_reg_addr << 1); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_TX, sfp_write_reg_data); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_COMMAND, 0x80); + do{ + cig_cpld_read_register(ADDR_REG_SFP_STATUS_STATUS, &sfp_read_status); + udelay(60); + wait_time_out--; + if(wait_time_out == 0) + break; + }while(sfp_read_status != 0x02); + + if(wait_time_out == 0) + return -1; + + return 1; +} + + +static int cig_cpld_read_sfp_register(u8 sfp_reg_addr, u8 *sfp_read_reg_data) +{ + u8 sfp_read_status = 0; + u8 wait_time_out = WAIT_TIME_OUT_COUNT; + + cig_cpld_write_register(ADDR_REG_SFP_STATUS_ADDR, sfp_reg_addr << 1 | 1); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_COMMAND, 0x80); + do{ + udelay(60); + cig_cpld_read_register(ADDR_REG_SFP_STATUS_STATUS, &sfp_read_status); + wait_time_out--; + if(wait_time_out == 0) + break; + }while(sfp_read_status != 0x01); + + cig_cpld_read_register(ADDR_REG_SFP_STATUS_RX,sfp_read_reg_data); + + if(wait_time_out == 0) + return -1; + + return 1; +} + + + + + + +/* Platform dependent +++ */ +static struct sfp_port_data *sfp_update_present(struct i2c_client *client) +{ + int i = 0, j = 0, status = -1; + unsigned char cpld_reg_data = 0,cpld_reg_addr = 0; + struct sfp_port_data *data = i2c_get_clientdata(client); + + DEBUG_PRINT("Starting sfp present status update"); + mutex_lock(&data->update_lock); + data->present = 0; + + udelay(6000); + + /* Read present status of port 1~48(SFP port) */ + for (i = 0; i < 6; i++) { + cpld_reg_addr = 1 + i; + + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); + + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status); + goto exit; + } + + data->present |= (u64)cpld_reg_data << (i*8); + + DEBUG_PRINT("Present status = 0x%lx\r\n", data->present); + } + + /* Read present status of port 49-56(QSFP port) */ + cpld_reg_addr = 25; + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status); + goto exit; + } + else { + data->present |= (u64)cpld_reg_data << 48; + } + + DEBUG_PRINT("Present status = 0x%lx", data->present); +exit: + mutex_unlock(&data->update_lock); + return (status < 0) ? ERR_PTR(status) : data; +} + +static struct sfp_port_data *sfp_update_tx_rx_status(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + int i = 0, j = 0; + int status = -1; + unsigned char cpld_reg_data = 0,cpld_reg_addr = 0; + + if (time_before(jiffies, data->msa->last_updated + HZ + HZ / 2) && data->msa->valid) { + return data; + } + + DEBUG_PRINT("Starting cs5435_54p sfp tx rx status update"); + mutex_lock(&data->update_lock); + data->msa->valid = 0; + memset(data->msa->status, 0, sizeof(data->msa->status)); + + udelay(6000); + + /* Read status of port 1~48(SFP port) */ + for (i = 0; i < 6; i++) { + cpld_reg_addr = 13+i; + + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status); + goto exit; + } + + data->msa->status[0] |= (u64)cpld_reg_data << (i * 8); + + DEBUG_PRINT("tx rx status[0] = 0x%lx\r\n", data->msa->status[0]); + } + + + for (i = 0; i < 6; i++) { + cpld_reg_addr = 19+i; + + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status); + goto exit; + } + + data->msa->status[1] |= (u64)cpld_reg_data << (i * 8); + + DEBUG_PRINT("tx rx status[1] = 0x%lx\r\n", data->msa->status[1]); + } + + for (i = 0; i < 6; i++) { + cpld_reg_addr = 7+i; + + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status); + goto exit; + } + + data->msa->status[2] |= (u64)cpld_reg_data << (i * 8); + + DEBUG_PRINT("tx rx status[2] = 0x%lx\r\n", data->msa->status[2]); + } + + data->msa->valid = 1; + data->msa->last_updated = jiffies; + +exit: + mutex_unlock(&data->update_lock); + return (status < 0) ? ERR_PTR(status) : data; +} + +static ssize_t sfp_set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + unsigned char cpld_reg_data = 0,cpld_reg_addr = 0,cpld_reg_bit = 0,cpld_reg_val = 0; + long disable; + int error; + + if (data->driver_type == DRIVER_TYPE_QSFP) { + return qsfp_set_tx_disable(dev, da, buf, count); + } + + error = kstrtol(buf, 10, &disable); + if (error) { + return error; + } + + mutex_lock(&data->update_lock); + + udelay(6000); + + if(data->port <= 48) { + cpld_reg_addr = 19 + data->port / 8; + cpld_reg_bit = 1 << ((data->port) % 8); + } + + /* Read current status */ + error = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); + + /* Update tx_disable status */ + if (disable) { + data->msa->status[1] |= BIT_INDEX(data->port); + cpld_reg_data |= cpld_reg_bit; + } + else { + data->msa->status[1] &= ~ BIT_INDEX(data->port); + cpld_reg_data &= ~cpld_reg_bit; + } + + error = cig_cpld_write_sfp_register(cpld_reg_addr,cpld_reg_data); + + mutex_unlock(&data->update_lock); + return count; +} +/* Platform dependent --- */ + +static int sfp_is_port_present(struct i2c_client *client, int port) +{ + struct sfp_port_data *data = i2c_get_clientdata(client); + + data = sfp_update_present(client); + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + return !(data->present & BIT_INDEX(data->port)); /* Platform dependent */ +} + +/* Platform dependent +++ */ +static ssize_t show_present(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + + if (PRESENT_ALL == attr->index) { + int i; + u8 values[7] = {0}; + struct sfp_port_data *data = sfp_update_present(client); + + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + for (i = 0; i < ARRAY_SIZE(values); i++) { + values[i] = ~(u8)(data->present >> (i * 8)); + } + + /* Return values 1 -> 56 in order */ + return sprintf(buf, "%.2x %.2x %.2x %.2x %.2x %.2x %.2x\n", + values[0], values[1], values[2], + values[3], values[4], values[5], + values[6]); + } + else { + struct sfp_port_data *data = i2c_get_clientdata(client); + int present = sfp_is_port_present(client, data->port); + + if (IS_ERR_VALUE(present)) { + return present; + } + + /* PRESENT */ + return sprintf(buf, "%d\n", present); + } +} +/* Platform dependent --- */ + +static struct sfp_port_data *sfp_update_port_type(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + u8 buf = 0; + int status; + + mutex_lock(&data->update_lock); + + switch (data->driver_type) { + case DRIVER_TYPE_SFP_MSA: + { + status = sfp_eeprom_read(client, SFF8024_PHYSICAL_DEVICE_ID_ADDR, &buf, sizeof(buf)); + if (unlikely(status < 0)) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + if (buf != SFF8024_DEVICE_ID_SFP) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + status = sfp_eeprom_read(client, SFF8472_10G_ETH_COMPLIANCE_ADDR, &buf, sizeof(buf)); + if (unlikely(status < 0)) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + DEBUG_PRINT("sfp port type (0x3) data = (0x%x)", buf); + data->port_type = buf & SFF8472_10G_BASE_MASK ? OOM_DRIVER_PORT_TYPE_SFP_PLUS : OOM_DRIVER_PORT_TYPE_SFP; + break; + } + case DRIVER_TYPE_QSFP: + { + status = sfp_eeprom_read(client, SFF8024_PHYSICAL_DEVICE_ID_ADDR, &buf, sizeof(buf)); + if (unlikely(status < 0)) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + DEBUG_PRINT("qsfp port type (0x0) buf = (0x%x)", buf); + switch (buf) { + case SFF8024_DEVICE_ID_QSFP: + data->port_type = OOM_DRIVER_PORT_TYPE_QSFP; + break; + case SFF8024_DEVICE_ID_QSFP_PLUS: + data->port_type = OOM_DRIVER_PORT_TYPE_QSFP_PLUS; + break; + case SFF8024_DEVICE_ID_QSFP28: + data->port_type = OOM_DRIVER_PORT_TYPE_QSFP_PLUS; + break; + default: + data->port_type = buf; + break; + } + + break; + } + default: + break; + } + + mutex_unlock(&data->update_lock); + return data; +} + +static ssize_t show_port_type(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + int present = sfp_is_port_present(client, data->port); + + if (IS_ERR_VALUE(present)) { + return present; + } + + if (!present) { + /* port is not present */ + return sprintf(buf, "%d\n", OOM_DRIVER_PORT_TYPE_NOT_PRESENT); + } + + sfp_update_port_type(dev); + return sprintf(buf, "%d\n", data->port_type); +} + +static struct sfp_port_data *qsfp_update_tx_rx_status(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + int i, status = -1; + u8 buf = 0; + u8 reg[] = {SFF8436_TX_FAULT_ADDR, SFF8436_TX_DISABLE_ADDR, SFF8436_RX_LOS_ADDR}; + + DEBUG_PRINT(""); + if (time_before(jiffies, data->qsfp->last_updated + HZ + HZ / 2) && data->qsfp->valid) { + return data; + } + + DEBUG_PRINT("Starting sfp tx rx status update"); + mutex_lock(&data->update_lock); + data->qsfp->valid = 0; + memset(data->qsfp->status, 0, sizeof(data->qsfp->status)); + + DEBUG_PRINT(""); + /* Notify device to update tx fault/ tx disable/ rx los status */ + for (i = 0; i < ARRAY_SIZE(reg); i++) { + status = sfp_eeprom_read(client, reg[i], &buf, sizeof(buf)); + if (unlikely(status < 0)) { + DEBUG_PRINT(""); + goto exit; + } + } + msleep(200); + DEBUG_PRINT(""); + + /* Read actual tx fault/ tx disable/ rx los status */ + for (i = 0; i < ARRAY_SIZE(reg); i++) { + status = sfp_eeprom_read(client, reg[i], &buf, sizeof(buf)); + if (unlikely(status < 0)) { + DEBUG_PRINT(""); + goto exit; + } + + DEBUG_PRINT("qsfp reg(0x%x) status = (0x%x)", reg[i], data->qsfp->status[i]); + data->qsfp->status[i] = (buf & 0xF); + } + + DEBUG_PRINT(""); + data->qsfp->valid = 1; + data->qsfp->last_updated = jiffies; + +exit: + DEBUG_PRINT(""); + mutex_unlock(&data->update_lock); + return (status < 0) ? ERR_PTR(status) : data; +} + +static ssize_t qsfp_inter_read(struct device *dev, struct device_attribute *da, char *buf) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_INTER_ADDR, &cpld_reg_data); + index = data->port - 48; + index = 1 << index; + val = (cpld_reg_data & index) > 0 ? 1 : 0; + + printk("inter read:data->port = %d, index = %hhu, cpld_reg_data = %hhu\n", data->port, index, cpld_reg_data); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", val); +} + + +static ssize_t qsfp_reset_read(struct device *dev, struct device_attribute *da, char *buf) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_RESET_ADDR, &cpld_reg_data); + index = data->port - 48; + index = 1 << index; + val = (cpld_reg_data & index) > 0 ? 1 : 0; + + printk("reset read:data->port = %d, index = %hhu, cpld_reg_data = %hhu\n", data->port, index, cpld_reg_data); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", val); +} + +static ssize_t qsfp_reset_write(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + long usrdata; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + ret = kstrtol(buf, 10, &usrdata); + if (ret) { + return ret; + } + + usrdata = usrdata > 0 ? 1 : 0; + index = data->port - 48; + + DEBUG_PRINT("usrdata = %u, index = %hhu\n", usrdata, index); + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_RESET_ADDR, &cpld_reg_data); + if (ret == 1) + { + + DEBUG_PRINT("cpld_reg_data = %x\n", cpld_reg_data); + cpld_reg_data &= ~(1 << index); + cpld_reg_data |= usrdata << index; + + DEBUG_PRINT("cpld_reg_data = %x\n", cpld_reg_data); + ret = cig_cpld_write_sfp_register(QSFP_RESET_ADDR, cpld_reg_data); + if (1 != ret) + { + DEBUG_PRINT("write failed\n"); + } + } + else + { + DEBUG_PRINT("read failed\n"); + } + + mutex_unlock(&data->update_lock); + + if (ret != 1) + return -1; + + return count; +} + + + + +static ssize_t qsfp_lpmode_read(struct device *dev, struct device_attribute *da, char *buf) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_LPMODE_ADDR, &cpld_reg_data); + index = data->port - 48; + index = 1 << index; + val = (cpld_reg_data & index) > 0 ? 1 : 0; + + printk("lpmode read:data->port = %d, index = %hhu, cpld_reg_data = %hhu\n", data->port, index, cpld_reg_data); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", val); +} + +static ssize_t qsfp_lpmode_write(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + long usrdata; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + ret = kstrtol(buf, 10, &usrdata); + if (ret) { + return ret; + } + + usrdata = usrdata > 0 ? 1 : 0; + index = data->port - 48; + + DEBUG_PRINT("usrdata = %u, index = %hhu\n", usrdata, index); + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_LPMODE_ADDR, &cpld_reg_data); + if (ret == 1) + { + + DEBUG_PRINT("cpld_reg_data = %x\n", cpld_reg_data); + cpld_reg_data &= ~(1 << index); + cpld_reg_data |= usrdata << index; + + DEBUG_PRINT("cpld_reg_data = %x\n", cpld_reg_data); + ret = cig_cpld_write_sfp_register(QSFP_LPMODE_ADDR, cpld_reg_data); + if (1 != ret) + { + DEBUG_PRINT("write failed\n"); + } + } + else + { + DEBUG_PRINT("read failed\n"); + } + + mutex_unlock(&data->update_lock); + + if (ret != 1) + return -1; + + return count; +} + + + +static ssize_t qsfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + int present; + u8 val = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + DEBUG_PRINT(""); + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + DEBUG_PRINT(""); + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + DEBUG_PRINT(""); + data = qsfp_update_tx_rx_status(dev); + DEBUG_PRINT(""); + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + DEBUG_PRINT(""); + switch (attr->index) { + case TX_FAULT: + val = !!(data->qsfp->status[2] & 0xF); + break; + case TX_FAULT1: + case TX_FAULT2: + case TX_FAULT3: + case TX_FAULT4: + val = !!(data->qsfp->status[2] & BIT_INDEX(attr->index - TX_FAULT1)); + break; + case TX_DISABLE: + val = data->qsfp->status[1] & 0xF; + break; + case TX_DISABLE1: + case TX_DISABLE2: + case TX_DISABLE3: + case TX_DISABLE4: + val = !!(data->qsfp->status[1] & BIT_INDEX(attr->index - TX_DISABLE1)); + break; + case RX_LOS: + val = !!(data->qsfp->status[0] & 0xF); + break; + case RX_LOS1: + case RX_LOS2: + case RX_LOS3: + case RX_LOS4: + val = !!(data->qsfp->status[0] & BIT_INDEX(attr->index - RX_LOS1)); + break; + default: + break; + } + + DEBUG_PRINT(""); + return sprintf(buf, "%d\n", val); +} + +static ssize_t qsfp_set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + long disable; + int status; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + status = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(status)) { + return status; + } + + if (!status) { + /* port is not present */ + return -ENXIO; + } + + status = kstrtol(buf, 10, &disable); + if (status) { + return status; + } + + data = qsfp_update_tx_rx_status(dev); + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + mutex_lock(&data->update_lock); + + if (attr->index == TX_DISABLE) { + data->qsfp->status[1] = disable & 0xF; + } + else {/* TX_DISABLE1 ~ TX_DISABLE4*/ + if (disable) { + data->qsfp->status[1] |= (1 << (attr->index - TX_DISABLE1)); + } + else { + data->qsfp->status[1] &= ~(1 << (attr->index - TX_DISABLE1)); + } + } + + DEBUG_PRINT("index = (%d), status = (0x%x)", attr->index, data->qsfp->status[1]); + status = sfp_eeprom_write(data->client, SFF8436_TX_DISABLE_ADDR, &data->qsfp->status[1], sizeof(data->qsfp->status[1])); + if (unlikely(status < 0)) { + count = status; + } + + mutex_unlock(&data->update_lock); + return count; +} + +static ssize_t sfp_show_ddm_implemented(struct device *dev, struct device_attribute *da, + char *buf) +{ + int status; + char ddm; + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + status = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(status)) { + return status; + } + + if (status == 0) { + /* port is not present */ + return -ENODEV; + } + + status = sfp_eeprom_read(client, SFF8472_DIAG_MON_TYPE_ADDR, &ddm, sizeof(ddm)); + if (unlikely(status < 0)) { + return status; + } + + return sprintf(buf, "%d\n", !!(ddm & SFF8472_DIAG_MON_TYPE_DDM_MASK)); +} + +/* Platform dependent +++ */ +static ssize_t sfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + u8 val = 0, index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + DEBUG_PRINT("driver type = (%d)", data->driver_type); + if (data->driver_type == DRIVER_TYPE_QSFP) { + DEBUG_PRINT(""); + return qsfp_show_tx_rx_status(dev, da, buf); + } + + DEBUG_PRINT(""); + data = sfp_update_tx_rx_status(dev); + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + if(attr->index == RX_LOS_ALL) { + int i = 0; + u8 values[6] = {0}; + + for (i = 0; i < ARRAY_SIZE(values); i++) { + values[i] = (u8)(data->msa->status[2] >> (i * 8)); + } + + /** Return values 1 -> 48 in order */ + return sprintf(buf, "%.2x %.2x %.2x %.2x %.2x %.2x\n", + values[0], values[1], values[2], + values[3], values[4], values[5]); + } + + switch (attr->index) { + case TX_FAULT: + index = 0; + break; + case TX_DISABLE: + index = 1; + break; + case RX_LOS: + index = 2; + break; + default: + break; + } + + val = !!(data->msa->status[index] & BIT_INDEX(data->port)); + return sprintf(buf, "%d\n", val); +} +/* Platform dependent --- */ +static ssize_t sfp_eeprom_write(struct i2c_client *client, u8 command, const char *data, + int data_len) +{ +#if USE_I2C_BLOCK_READ + int status, retry = I2C_RW_RETRY_COUNT; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + status = i2c_smbus_write_i2c_block_data(client, command, data_len, data); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + return status; + } + + return data_len; +#else + int status, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_write_byte_data(client, command, *data); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + return status; + } + + return 1; +#endif + + +} + +static ssize_t sfp_port_write(struct sfp_port_data *data, + const char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + return count; + } + + /* + * Write data to chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&data->update_lock); + + while (count) { + ssize_t status; + + status = sfp_eeprom_write(data->client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + buf += status; + off += status; + count -= status; + retval += status; + } + + mutex_unlock(&data->update_lock); + return retval; +} + + +static ssize_t sfp_bin_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + int present; + struct sfp_port_data *data; + DEBUG_PRINT("%s(%d) offset = (%d), count = (%d)", off, count); + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + + present = sfp_is_port_present(data->client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + return sfp_port_write(data, buf, off, count); +} + +static ssize_t sfp_eeprom_read(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ +#if USE_I2C_BLOCK_READ + int status, retry = I2C_RW_RETRY_COUNT; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + status = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + goto abort; + } + if (unlikely(status != data_len)) { + status = -EIO; + goto abort; + } + + //result = data_len; + +abort: + return status; +#else + int status, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_read_byte_data(client, command); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "sfp read byte data failed, command(0x%2x), data(0x%2x)\r\n", command, status); + goto abort; + } + + *data = (u8)status; + status = 1; + +abort: + return status; +#endif +} + +static ssize_t sfp_port_read(struct sfp_port_data *data, + char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + DEBUG_PRINT("Count = 0, return"); + return count; + } + + /* + * Read data from chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&data->update_lock); + + while (count) { + ssize_t status; + + status = sfp_eeprom_read(data->client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + + buf += status; + off += status; + count -= status; + retval += status; + } + + mutex_unlock(&data->update_lock); + return retval; + +} + +static ssize_t sfp_bin_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + int present; + struct sfp_port_data *data; + DEBUG_PRINT("offset = (%d), count = (%d)", off, count); + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + + present = sfp_is_port_present(data->client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + return sfp_port_read(data, buf, off, count); +} + +static int sfp_sysfs_eeprom_init(struct kobject *kobj, struct bin_attribute *eeprom) +{ + int err; + + sysfs_bin_attr_init(eeprom); + eeprom->attr.name = EEPROM_NAME; + eeprom->attr.mode = S_IWUSR | S_IRUGO; + eeprom->read = sfp_bin_read; + eeprom->write = sfp_bin_write; + eeprom->size = EEPROM_SIZE; + + /* Create eeprom file */ + err = sysfs_create_bin_file(kobj, eeprom); + if (err) { + return err; + } + + return 0; +} + +static int sfp_sysfs_eeprom_cleanup(struct kobject *kobj, struct bin_attribute *eeprom) +{ + sysfs_remove_bin_file(kobj, eeprom); + return 0; +} + +static const struct attribute_group sfp_msa_group = { + .attrs = sfp_msa_attributes, +}; + +static int sfp_i2c_check_functionality(struct i2c_client *client) +{ +#if USE_I2C_BLOCK_READ + return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK); +#else + return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA); +#endif +} + +static int sfp_msa_probe(struct i2c_client *client, const struct i2c_device_id *dev_id, + struct sfp_msa_data **data) +{ + int status; + struct sfp_msa_data *msa; + + if (!sfp_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + msa = kzalloc(sizeof(struct sfp_msa_data), GFP_KERNEL); + if (!msa) { + status = -ENOMEM; + goto exit; + } + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &sfp_msa_group); + if (status) { + goto exit_free; + } + + /* init eeprom */ + status = sfp_sysfs_eeprom_init(&client->dev.kobj, &msa->eeprom.bin); + if (status) { + goto exit_remove; + } + + *data = msa; + dev_info(&client->dev, "sfp msa '%s'\n", client->name); + + cs5435_54p_sysfs_add_client(client); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &sfp_msa_group); +exit_free: + kfree(msa); +exit: + + return status; +} + +static const struct attribute_group sfp_ddm_group = { + .attrs = sfp_ddm_attributes, +}; + +static int sfp_ddm_probe(struct i2c_client *client, const struct i2c_device_id *dev_id, + struct sfp_ddm_data **data) +{ + int status; + struct sfp_ddm_data *ddm; + + if (!sfp_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + ddm = kzalloc(sizeof(struct sfp_ddm_data), GFP_KERNEL); + if (!ddm) { + status = -ENOMEM; + goto exit; + } + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &sfp_ddm_group); + if (status) { + goto exit_free; + } + + /* init eeprom */ + status = sfp_sysfs_eeprom_init(&client->dev.kobj, &ddm->eeprom.bin); + if (status) { + goto exit_remove; + } + + *data = ddm; + dev_info(&client->dev, "sfp ddm '%s'\n", client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &sfp_ddm_group); +exit_free: + kfree(ddm); +exit: + + return status; +} + +static const struct attribute_group qsfp_group = { + .attrs = qsfp_attributes, +}; + +static int qsfp_probe(struct i2c_client *client, const struct i2c_device_id *dev_id, + struct qsfp_data **data) +{ + int status; + struct qsfp_data *qsfp; + + if (!sfp_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + qsfp = kzalloc(sizeof(struct qsfp_data), GFP_KERNEL); + if (!qsfp) { + status = -ENOMEM; + goto exit; + } + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &qsfp_group); + if (status) { + goto exit_free; + } + + /* init eeprom */ + status = sfp_sysfs_eeprom_init(&client->dev.kobj, &qsfp->eeprom.bin); + if (status) { + goto exit_remove; + } + + /* Bring QSFPs out of reset */ + //cig_lpc_write(0x62, 0x15, 0x3F); + + *data = qsfp; + dev_info(&client->dev, "qsfp '%s'\n", client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &qsfp_group); +exit_free: + kfree(qsfp); +exit: + + return status; +} + +/* Platform dependent +++ */ +static int sfp_device_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct sfp_port_data *data = NULL; + + data = kzalloc(sizeof(struct sfp_port_data), GFP_KERNEL); + if (!data) { + return -ENOMEM; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + data->port = dev_id->driver_data; + data->client = client; + + if (dev_id->driver_data >= cs5435_54p_sfp1 && dev_id->driver_data <= cs5435_54p_sfp48) { + if (client->addr == SFP_EEPROM_A0_I2C_ADDR) { + data->driver_type = DRIVER_TYPE_SFP_MSA; + return sfp_msa_probe(client, dev_id, &data->msa); + } + else if (client->addr == SFP_EEPROM_A2_I2C_ADDR) { + data->driver_type = DRIVER_TYPE_SFP_DDM; + return sfp_ddm_probe(client, dev_id, &data->ddm); + } + } + else { /* cs5435_54p_sfp49 ~ cs5435_54p_sfp56 */ + if (client->addr == SFP_EEPROM_A0_I2C_ADDR) { + data->driver_type = DRIVER_TYPE_QSFP; + return qsfp_probe(client, dev_id, &data->qsfp); + } + } + + return -ENODEV; +} +/* Platform dependent --- */ + +static int sfp_msa_remove(struct i2c_client *client, struct sfp_msa_data *data) +{ + sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin); + sysfs_remove_group(&client->dev.kobj, &sfp_msa_group); + kfree(data); + return 0; +} + +static int sfp_ddm_remove(struct i2c_client *client, struct sfp_ddm_data *data) +{ + sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin); + sysfs_remove_group(&client->dev.kobj, &sfp_ddm_group); + kfree(data); + return 0; +} + +static int qfp_remove(struct i2c_client *client, struct qsfp_data *data) +{ + sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin); + sysfs_remove_group(&client->dev.kobj, &qsfp_group); + kfree(data); + return 0; +} + +static int sfp_device_remove(struct i2c_client *client) +{ + struct sfp_port_data *data = i2c_get_clientdata(client); + + cs5435_54p_sysfs_remove_client(client); + switch (data->driver_type) { + case DRIVER_TYPE_SFP_MSA: + return sfp_msa_remove(client, data->msa); + case DRIVER_TYPE_SFP_DDM: + return sfp_ddm_remove(client, data->ddm); + case DRIVER_TYPE_QSFP: + return qfp_remove(client, data->qsfp); + } + + return 0; +} + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +static struct i2c_driver cs5435_54p_sfp_driver = { + .driver = { + .name = DRIVER_NAME, + }, + .probe = sfp_device_probe, + .remove = sfp_device_remove, + .id_table = sfp_device_id, + .address_list = normal_i2c, +}; + +module_i2c_driver(cs5435_54p_sfp_driver); + + +MODULE_AUTHOR("Zhang Peng "); +MODULE_DESCRIPTION("cs5435_54p_sfp driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-sysfs.c b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-sysfs.c new file mode 100644 index 000000000000..0ba8836cf33a --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/modules/x86-64-cig-cs5435-54p-sysfs.c @@ -0,0 +1,335 @@ +/* + * A hwmon driver for the CIG cs5435-54P sysfs Module + * + * Copyright (C) 2018 Cambridge, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 +#include +#include + +#include "i2c-algo-lpc.h" + + +static LIST_HEAD(sysfs_client_list); +static struct mutex list_lock; + +struct sysfs_client_node { + struct i2c_client *client; + struct list_head list; +}; + +#define DEVICE_NAME "cigfs" +static int dev_major; +static struct class *dev_class; +static struct cdev *dev_cdev; +static struct device *dev_device; +static struct class *psu_class; +static struct class *sfp_class; + + +void cs5435_54p_sysfs_add_client(struct i2c_client *client) +{ + struct sysfs_client_node *node = kzalloc(sizeof(struct sysfs_client_node), GFP_KERNEL); + + if (!node) { + dev_dbg(&client->dev, "Can't allocate sysfs_client_node (0x%x)\n", client->addr); + return; + } + node->client = client; + + mutex_lock(&list_lock); + list_add(&node->list, &sysfs_client_list); + mutex_unlock(&list_lock); +} + +EXPORT_SYMBOL(cs5435_54p_sysfs_add_client); + +void cs5435_54p_sysfs_remove_client(struct i2c_client *client) +{ + struct list_head *list_node = NULL; + struct sysfs_client_node *sysfs_node = NULL; + int found = 0; + + mutex_lock(&list_lock); + + list_for_each(list_node, &sysfs_client_list) + { + sysfs_node = list_entry(list_node, struct sysfs_client_node, list); + if (IS_ERR(sysfs_node)) + { + break; + } + if (sysfs_node->client == client) { + found = 1; + break; + } + } + if (found) { + list_del(list_node); + kfree(sysfs_node); + } + + mutex_unlock(&list_lock); +} + +EXPORT_SYMBOL(cs5435_54p_sysfs_remove_client); + +struct class * cs5435_54p_sysfs_create_symclass(char *cls_name) +{ + int rc = 0; + struct class *my_class; +/**************************************************************************************/ + my_class = class_create(THIS_MODULE,cls_name); + if (IS_ERR(my_class)) { + pr_err("failed to create my class\n"); + } + return my_class; + +/**************************************************************************************/ +} + +void cs5435_54p_sysfs_delete_symclass(struct class *my_class) +{ +/**************************************************************************************/ + + if (IS_ERR(my_class)) { + pr_err("Pointer is invaild\n"); + } + class_destroy(my_class); + +/**************************************************************************************/ +} + + + + + +int cs5435_54p_sysfs_create_symlink(struct class *my_class,char * driver_name,char *device_name) +{ + struct list_head *list_node = NULL; + struct sysfs_client_node *sysfs_node = NULL; + int ret = -EPERM; + int rc = 0; + + mutex_lock(&list_lock); + list_for_each(list_node, &sysfs_client_list) + { + sysfs_node = list_entry(list_node, struct sysfs_client_node, list); + if (!strcmp(sysfs_node->client->name,driver_name)) { + rc = sysfs_create_link(&my_class->p->subsys.kobj, &sysfs_node->client->dev.kobj,device_name); + if(rc) + { + pr_err("failed to create symlink %d\n",rc); + } + break; + } + } + mutex_unlock(&list_lock); + return ret; +} + + +int cs5435_54p_sysfs_delete_symlink(struct class *my_class,char * driver_name,char *device_name) +{ + struct list_head *list_node = NULL; + struct sysfs_client_node *sysfs_node = NULL; + int ret = -EPERM; + int rc = 0; + + mutex_lock(&list_lock); + list_for_each(list_node, &sysfs_client_list) + { + sysfs_node = list_entry(list_node, struct sysfs_client_node, list); + if (!strcmp(sysfs_node->client->name,driver_name)) { + sysfs_remove_link(&my_class->p->subsys.kobj,device_name); + break; + } + } + mutex_unlock(&list_lock); + return ret; +} + + +static int cs5435_54p_sysfs_open(struct inode *inode, struct file *file) +{ + return 0; +} + + + +static ssize_t cs5435_54p_sysfs_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos) +{ + char str[10],name[18],port[8]; + int ret; + int i; + memset(str, 0, sizeof(str)); + ret = copy_from_user(str, buf, count); + if (ret) + { + printk(KERN_ERR "copy_from_user fail\n"); + return -EINVAL; + } + + if(!strncmp(str,"start",5)) + { + psu_class = cs5435_54p_sysfs_create_symclass("psu"); + cs5435_54p_sysfs_create_symlink(psu_class,"cs5435_54p_psu1","psu1"); + cs5435_54p_sysfs_create_symlink(psu_class,"cs5435_54p_psu2","psu2"); + sfp_class = cs5435_54p_sysfs_create_symclass("swps"); + for(i = 1; i <= 48;i++) + { + memset(name,0xff,sizeof(name)); + memset(port,0xff,sizeof(port)); + snprintf(name,sizeof(name),"cs5435_54p_sfp%d",i); + snprintf(port,sizeof(port),"port%d",i); + cs5435_54p_sysfs_create_symlink(sfp_class,name,port); + } + } + else if(!strncmp(str,"stop",4)) + { + cs5435_54p_sysfs_delete_symlink(psu_class,"cs5435_54p_psu1","psu1"); + cs5435_54p_sysfs_delete_symlink(psu_class,"cs5435_54p_psu2","psu2"); + cs5435_54p_sysfs_delete_symclass(psu_class); + + for(i = 1; i <= 48;i++) + { + memset(name,0xff,sizeof(name)); + memset(port,0xff,sizeof(port)); + snprintf(name,sizeof(name),"cs5435_54p_sfp%d",i); + snprintf(port,sizeof(port),"port%d",i); + cs5435_54p_sysfs_delete_symlink(sfp_class,name,port); + } + cs5435_54p_sysfs_delete_symclass(sfp_class); + } + return count; +} + + +static struct file_operations cs5435_54p_sysfs_fops = { + .owner = THIS_MODULE, + .open = cs5435_54p_sysfs_open, + .write = cs5435_54p_sysfs_write, +}; + + +static int __init cs5435_54p_sysfs_init(void) +{ + int result = 0; + int err = 0; + dev_t dev = MKDEV(dev_major, 0); + + if (dev_major) + result = register_chrdev_region(dev, 1, DEVICE_NAME); + else { + result = alloc_chrdev_region(&dev, 0, 1, DEVICE_NAME); + dev_major = MAJOR(dev); + } + if (result < 0) + { + printk("unable to get major %d\n", dev_major); + err= -EINVAL; + } + printk("get major is %d\n", dev_major); + if (dev_major == 0) + dev_major = result; + + dev_cdev= kmalloc(sizeof(struct cdev), GFP_KERNEL); + if(IS_ERR(dev_cdev)) { + err= -ENOMEM; + } + + cdev_init(dev_cdev, &cs5435_54p_sysfs_fops); + dev_cdev->owner = THIS_MODULE; + dev_cdev->ops = &cs5435_54p_sysfs_fops; + err = cdev_add(dev_cdev, dev, 1); + if (err) + { + printk("error %d add fpga ", err); + goto err_malloc; + } + + dev_class = class_create(THIS_MODULE, DEVICE_NAME); + if (IS_ERR(dev_class)) + { + printk("Err:failed in creating class.\n"); + goto err_cdev_add; + } + + dev_device = device_create(dev_class, NULL, MKDEV(dev_major, 0), NULL, DEVICE_NAME); + if (IS_ERR(dev_device)) + { + printk("Err:failed in creating device.\n"); + goto err_class_crt; + } + + mutex_init(&list_lock); + + return err; + + err_class_crt: + cdev_del(dev_cdev); + err_cdev_add: + kfree(dev_cdev); + err_malloc: + unregister_chrdev_region(MKDEV(dev_major,0), 1); + + return err; + +} + +static void __exit cs5435_54p_sysfs_exit(void) +{ + cdev_del(dev_cdev); + printk("cdev_del ok\n"); + device_destroy(dev_class, MKDEV(dev_major, 0)); + + class_destroy(dev_class); + + if(dev_cdev != NULL) + kfree(dev_cdev); + + unregister_chrdev_region(MKDEV(dev_major, 0), 1); + printk("cs5435_54p_sysfs_exit...\r\n"); +} + + +MODULE_AUTHOR("Zhang Peng "); +MODULE_DESCRIPTION("cs5435-54p-sysfs driver"); +MODULE_LICENSE("GPL"); + +module_init(cs5435_54p_sysfs_init); +module_exit(cs5435_54p_sysfs_exit); + + diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/service/cs5435-platform-init.service b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/service/cs5435-platform-init.service new file mode 100644 index 000000000000..b609a2be45c7 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/service/cs5435-platform-init.service @@ -0,0 +1,13 @@ +[Unit] +Description=Cig CS5435-54P Platform initialization service +Before=pmon.service +DefaultDependencies=no + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/cig_cs5435_util.py install +ExecStop=/usr/local/bin/cig_cs5435_util.py clean +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/service/cs5435-platform-misc.service b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/service/cs5435-platform-misc.service new file mode 100644 index 000000000000..852ab5689a70 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/service/cs5435-platform-misc.service @@ -0,0 +1,15 @@ +[Unit] +Description=Cig CS5435-54P Platform miscellaneous service +After=cs5435-platform-init.service +DefaultDependencies=no + +[Service] +ExecStart=/usr/local/bin/cig_cs5435_misc.py +KillSignal=SIGKILL +SuccessExitStatus=SIGKILL + +# Resource Limitations +LimitCORE=infinity + +[Install] +WantedBy=multi-user.target diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/setup.py b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/setup.py new file mode 100755 index 000000000000..1d4fa7f36452 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/setup.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +import os +import sys +from setuptools import setup +os.listdir + +setup( + name='cs5435-54p', + version='1.0.0', + description='Module to initialize Cig CS5435-54P platforms', + + packages=['cs5435-54p'], + package_dir={'cs5435-54p': 'cs5435-54p/classes'}, + ) diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/utils/cig_cs5435_misc.py b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/utils/cig_cs5435_misc.py new file mode 100755 index 000000000000..0a78085fd49b --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/utils/cig_cs5435_misc.py @@ -0,0 +1,574 @@ +#!/usr/bin/env python +# +# Copyright (C) 2018 Cambridge, Inc. +# +# This program is free software: you can 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 commands +import sys, getopt +import logging +import re +import time +import datetime +from collections import namedtuple +from threading import Thread + +DEBUG = False +i2c_prefix = '/sys/bus/i2c/devices/' +leds_prefix = '/sys/devices/platform/cs5435_54p_led/leds/' +fans_prefix = '/sys/devices/platform/cs5435_54p_fan/' +fansdir_prefix = fans_prefix + 'fan{}_direction' + +ageing_controlfile = '/etc/sonic/agcontrol' +AGFlag = 0 + + +platform_misc_log = '/var/log/platform_misc.log' +misclogger = logging.getLogger('platform_misc') +misclogger.setLevel(logging.INFO) +miscformatter = logging.Formatter('%(asctime)s-%(levelname)s-%(message)s') + +if not os.path.isfile(platform_misc_log): + try: + os.mknod(platform_misc_log) + except: + print 'Failed to creat platform_misc.log' + +fileHandler = logging.FileHandler(platform_misc_log) +fileHandler.setLevel(logging.INFO) +fileHandler.setFormatter(miscformatter) +misclogger.addHandler(fileHandler) + + +starttime = datetime.datetime.now() +IsGetlswt = 0 +coretemp_prefix = '/sys/class/hwmon/hwmon1/' +coretemp_ps = [] +psu1_p = '/sys/bus/i2c/devices/5-005a/psu_present' +psu2_p = '/sys/bus/i2c/devices/5-005b/psu_present' +psu1_d = '/sys/bus/i2c/devices/5-0052/psu_eeprom' +psu2_d = '/sys/bus/i2c/devices/5-0053/psu_eeprom' +psu1led_d = leds_prefix + 'cs5435_54p_led::psu1/brightness' +psu2led_d = leds_prefix + 'cs5435_54p_led::psu2/brightness' +cs5435_ledpath = {'fan':leds_prefix + 'cs5435_54p_led::fan/brightness', + 'fan1':leds_prefix + 'cs5435_54p_led::fan1/brightness', + 'fan2':leds_prefix + 'cs5435_54p_led::fan2/brightness', + 'fan3':leds_prefix + 'cs5435_54p_led::fan3/brightness', + 'fan4':leds_prefix + 'cs5435_54p_led::fan4/brightness', + 'fan5':leds_prefix + 'cs5435_54p_led::fan5/brightness', + 'psu1':leds_prefix + 'cs5435_54p_led::psu1/brightness', + 'psu2':leds_prefix + 'cs5435_54p_led::psu2/brightness', + 'sys':leds_prefix + 'cs5435_54p_led::sys/brightness'} + + +def system_read_filestr(node): + with open(node, 'r') as f: + try: + str = f.read() + except IOError as e: + misclogger.error('Failed to get node, str={}'.format(node)) + return "0" + return str + + +def system_bright_leds(dev, colour): + global AGFlag + + if AGFlag == 1: + return + + cmd = 'echo {} > {}'.format(colour, dev) + log_os_system(cmd, 1) + return + +''' +1: front in tail out +0: front out tail in +''' +def system_getpsu_direction(dev): + try: + with open(dev) as f: + f.seek(0x30) + str = f.read(2) + except IOError as e: + misclogger.error('Failed to get psu eep') + return 1 + if str == 'AA': ## front in tail out + return 1 + elif str == 'RA':## tail in front out + return 0 + else: + misclogger.error('Failed to get psu eep, str={}'.format(str)) + return -1 + + +def system_get_cputype(): + cmdretfd = os.popen("lscpu | grep 'Model name'") + retstring = cmdretfd.read() + endindex = retstring.find('@') - 1 + startindex = retstring[:endindex].rfind(' ') + 1 + cputype = retstring[startindex:endindex] + + return cputype + + +def system_init_coretemppath(): + global coretemp_ps + + cmdstr = "ls {} | grep 'input'".format(coretemp_prefix) + cmdretfd = os.popen(cmdstr) + + coretemppss = cmdretfd.read().splitlines() + if len(coretemppss) < 3: + cputype = system_get_cputype() + misclogger.error('Failed to init core temperature path.' + ' cpu type = {}, num thermal = {}'.format(cputype, len(coretemp_ps))) + return 1 + + for i in range(0,3): + coretemp_ps.append(coretemp_prefix + coretemppss[i]) + + print coretemp_ps + + return 0 + + +class cs5435_fanattr: + def __init__(self, name): + self.name = name + self.direction = 0 + self.direction_p = '' + self.rear = 0 + self.rear_p = '' + self.front = 0 + self.front_p = '' + self.fault = 0 + self.fault_p = '' + self.status = 0 + self.setpath() + self.updatedevice() + + return + + def setpath(self): + self.direction_p = fans_prefix + '{}_direction'.format(self.name) + self.rear_p = fans_prefix + '{}_rear_speed_rpm'.format(self.name) + self.front_p = fans_prefix + '{}_front_speed_rpm'.format(self.name) + self.fault_p = fans_prefix + '{}_fault'.format(self.name) + + return + + def updatedevice(self): + self.direction = int(system_read_filestr(self.direction_p)) + self.rear = int(system_read_filestr(self.rear_p)) + self.front = int(system_read_filestr(self.front_p)) + self.fault = int(system_read_filestr(self.fault_p)) + + return + + def checkspeedrpm(self, speedrpm): + frontrpmexp = speedrpm * 21000 / 100 + rearrpmexp = speedrpm * 19000 / 100 + deviationfront = abs(frontrpmexp - self.front) / float(frontrpmexp) + deviationrear = abs(rearrpmexp - self.rear) / float(rearrpmexp) + + if deviationfront < 0.3 and deviationrear < 0.3: + return 0 + else: + misclogger.error(':{} speed wrong. frontexp is {}, but rpm is {}.rearexp is {}, but rpm is {}'.format(self.name, frontrpmexp, self.front, rearrpmexp, self.rear)) + return 1 + + def checkstatus(self, speedrpm, totaldirct): + speedstatus = self.checkspeedrpm(speedrpm) + if self.direction != totaldirct: + self.status = 1 + misclogger.error(':{} direction = {}.fan direction is not ok.'.format(self.name, self.direction)) + elif speedstatus != 0: + self.status = 1 + elif self.fault != 0: + misclogger.error(':{} fault.'.format(self.name)) + self.status = 1 + else: + self.status = 0 + + if self.status == 1: + system_bright_leds(cs5435_ledpath[self.name], 3) + else: + system_bright_leds(cs5435_ledpath[self.name], 1) + + return self.status + +cs5435_fanattrnodes = [] + + +class cs5435_psuattr: + def __init__(self, name): + self.name = name + self.direction = 0 + self.direction_p = '' + self.present = 0 + self.present_p = '' + self.status = 0 + + self.setpath() + self.updatepresent() + self.updatedirection() + + return + + def setpath(self): + if self.name == 'psu1': + self.present_p = psu1_p + self.direction_p = psu1_d + if self.name == 'psu2': + self.present_p = psu2_p + self.direction_p = psu2_d + + return + + def updatepresent(self): + self.present = int(system_read_filestr(self.present_p)) + + return + + def updatedirection(self): + if self.present == 1: + self.direction = system_getpsu_direction(self.direction_p) + else: + self.direction = 2 + + return + + def checkstatus(self, totaldirct): + if self.present != 1: + self.status = 1 + misclogger.error(':{} not present.'.format(self.name)) + elif self.direction == 2: + self.status = 0 + misclogger.info(':{} direction need to be update.'.format(self.name)) + elif self.direction != totaldirct: + self.status = 1 + misclogger.info(':{} direction is wrong.'.format(self.name)) + else: + self.status = 0 + + if self.status == 1: + system_bright_leds(cs5435_ledpath[self.name], 3) + else: + system_bright_leds(cs5435_ledpath[self.name], 1) + + return self.status + +cs5435_psuattrnodes = [] + + + +def my_log(txt): + if DEBUG == True: + print "[ROY]"+txt + return + +def device_exist(): + ret1, log = log_os_system("ls "+i2c_prefix+"5-005a", 0) + ret2, log = log_os_system("ls "+i2c_prefix+"5-005b", 0) + ret3, log = log_os_system("ls "+leds_prefix+"cs5435_54p_led*", 0) + return not(ret1 or ret2 or ret3) + + +def log_os_system(cmd, show): + logging.info('Run :'+cmd) + status, output = commands.getstatusoutput(cmd) + my_log (cmd +"with result:" + str(status)) + my_log (" output:"+output) + if status: + logging.info('Failed :'+cmd) + if show: + print('Failed :'+cmd) + return status, output + + +def system_get_coretemp(): + temp1 = system_read_filestr(coretemp_ps[0]).strip() + temp2 = system_read_filestr(coretemp_ps[1]).strip() + temp3 = system_read_filestr(coretemp_ps[2]).strip() + + return int(temp1), int(temp2), int(temp3) + +def system_get_boardtemp(): + for i in range(0,16): + temp1path = "/sys/bus/i2c/devices/5-004a/hwmon/hwmon%d/temp1_input" % i + if os.access(temp1path, os.F_OK): + break + for i in range(0,16): + temp2path = "/sys/bus/i2c/devices/5-004b/hwmon/hwmon%d/temp1_input" % i + if os.access(temp2path, os.F_OK): + break + temp1 = system_read_filestr(temp1path).strip() + temp2 = system_read_filestr(temp2path).strip() + + return int(temp1), int(temp2) + + +def system_get_lswtemp(): + global IsGetlswt + global starttime + if IsGetlswt == 0: + now = datetime.datetime.now() + misclogger.info("time wait.") + misclogger.info("start = {}, now = {}.".format(starttime, now)) + if (now - starttime).seconds > 150: + misclogger.info("time = ".format((now - starttime).seconds)) + IsGetlswt = 1 + + return 25 + +# chp = subprocess.Popen("docker ps --filter name=syncd", shell=True, stdout=subprocess.PIPE) +# if chp.poll() == None: +# misclogger.info("No subp.") +# chp.kill() +# +# return 25 + +# retstring = chp.stdout.read() +# chp.kill() +# if 'Up' not in retstring: +# misclogger.info("lsw not up.") +# +# return 25 + + status, output = log_os_system('npx_diag swc show temperature', 1) + if status: + misclogger.error('failed to show lsw temperature') + + return 25 + + output = output.strip() + if output.find("it 0, temperature ") > 0: + startindex = output.find('temperature') + len('temperature') + 1 + endindex = output[startindex:].find(" ") + endindex = startindex + endindex + temp = output[startindex:endindex] + b = temp.find('.') + if b > 0: + temp=temp[:b] + temp = int(temp) + else: + misclogger.error("Failed to get temperature.") + temp = 0 + + return int(temp) + +def system_monitor_temperature(): + + ctemp1, ctemp2, ctemp3 = system_get_coretemp() + btemp1, btemp2 = system_get_boardtemp() + ltemp = system_get_lswtemp() + fan_speed_str = system_cs5435_getfanexspeed() + fan_speed = int(fan_speed_str) + policy = 'stay' + pos = 0 + #speed c1 c2 c3 b1 b2 lsw + fan_policy_up = ([30, 40000, 40000, 40000, 42000, 35000, 95], + [40, 44000, 44000, 44000, 44000, 39000, 96], + [50, 49000, 49000, 49000, 47000, 44000, 91], + [60, 52000, 52000, 52000, 51500, 47500, 92], + [70, 53000, 53000, 53000, 52000, 49000, 93], + [100,999999,999999,999999,999999,999999,999]) + + fan_policy_down=([30, 0, 0, 0, 0, 0, 0], + [40, 34000, 34000, 34000, 34000, 30000, 80], + [50, 38000, 38000, 38000, 37000, 33000, 81], + [60, 44000, 44000, 44000, 43000, 39000, 84], + [70, 44000, 44000, 44000, 43000, 40000, 84], + [100, 48000, 48000, 48000, 46000, 42000, 85],) + + for policytable in fan_policy_up: + if fan_speed <= policytable[0]: + break + pos = pos + 1 + fan_speed = policytable[0] + if (ctemp1 < policytable[1]) and (ctemp2 < policytable[2]) and (ctemp3 < policytable[3]) and (btemp1 < policytable[4]) and (btemp2 < policytable[5]) and (ltemp < policytable[6]): + policy = 'stay' + policytable = fan_policy_down[pos] + if (ctemp1 < policytable[1]) and (ctemp2 < policytable[2]) and (ctemp3 < policytable[3]) and (btemp1 < policytable[4]) and (btemp2 < policytable[5]) and (ltemp < policytable[6]): + policy = 'down' + else: + policy = 'up' + + if policy == 'up': + misclogger.info("speed = %d." % fan_speed) + misclogger.info("core1 = %d, core2 = %d, core3 = %d." % (ctemp1, ctemp2, ctemp3)) + misclogger.info("board1 = %d, board2 = %d." % (btemp1, btemp2)) + misclogger.info("lsw = %d" % ltemp) + fan_speed = fan_policy_down[pos + 1][0] + misclogger.info("fan policy: up. speedexp = {}".format(fan_speed)) + + if policy == 'stay': + fan_speed = fan_policy_down[pos] + return + + if policy == 'down': + misclogger.info("speed = %d." % fan_speed) + misclogger.info("core1 = %d, core2 = %d, core3 = %d." % (ctemp1, ctemp2, ctemp3)) + misclogger.info("board1 = %d, board2 = %d." % (btemp1, btemp2)) + misclogger.info("lsw = %d" % ltemp) + fan_speed = fan_policy_down[pos - 1][0] + misclogger.info("fan policy: down.speedexp = {}".format(fan_speed)) + + cmd = "echo %d > /sys/devices/platform/cs5435_54p_fan/fan_duty_cycle_percentage" % fan_speed + status, output = log_os_system(cmd, 1) + if status: + misclogger.error("set fan speed fault") + + return + + +def system_cs5435_setfanexspeed(num): + fanspeednode = fans_prefix + 'fan_duty_cycle_percentage' + numstr = str(num) + with open(fanspeednode, 'w') as f: + f.write(numstr) + + +def system_cs5435_getfanexspeed(): + fanspeednode = fans_prefix + 'fan_duty_cycle_percentage' + fanspeedstr = system_read_filestr(fanspeednode) + fanspeedexp = int(fanspeedstr) + + return fanspeedexp + + +def system_cs5435_getdirection(): + global cs5435_fanattrnodes + direction = 0 + + for fan in cs5435_fanattrnodes: + direction = direction + fan.direction + + if direction > 2: + direction = 1 + else: + direction = 0 + + return direction + + +def system_check_psusdirection(): + global cs5435_psuattrnodes + cs5435totaldirct = system_cs5435_getdirection() + psutatus = 0 + + for psu in cs5435_psuattrnodes: + psu.updatedirection() + psu.checkstatus(cs5435totaldirct) + psutatus = psu.status + psutatus + + return (psutatus != 0) + + +def system_check_psuspresent(): + global cs5435_psuattrnodes + cs5435totaldirct = system_cs5435_getdirection() + psutatus = 0 + + for psu in cs5435_psuattrnodes: + psu.updatepresent() + psu.checkstatus(cs5435totaldirct) + psutatus = psu.status + psutatus + + return (psutatus != 0) + + +def system_check_fansstate(): + global cs5435_fanattrnodes + global cs5435_ledpath + cs5435totaldirct = system_cs5435_getdirection() + fanstatus = 0 + fanexspeed = 0 + + fanexspeed = system_cs5435_getfanexspeed() + + for fan in cs5435_fanattrnodes: + fan.updatedevice() + fan.checkstatus(fanexspeed, cs5435totaldirct) + fanstatus = fanstatus + fan.status + + if fanstatus > 0: + misclogger.error(':fan error.set fans speed 100.') + system_cs5435_setfanexspeed(100) + system_bright_leds(cs5435_ledpath['fan'], 3) + else: + system_bright_leds(cs5435_ledpath['fan'], 1) + + return (fanstatus != 0) + + +def system_misc_polling(threadName,delay): + for count in range(1,5): + if device_exist() == False: + time.sleep(delay+3) + print "%s: %s, count=%d" % ( threadName, time.ctime(time.time()), count) + else: + break + + if count == 4: + return + + status, output = log_os_system("echo 1 > /sys/devices/platform/cs5435_54p_led/leds/cs5435_54p_led::sys/brightness", 1) + status, output = log_os_system("hwconfig -cfp 1", 1) + + global AGFlag + if os.access(ageing_controlfile, os.F_OK): + AGFlag = 1 + else: + AGFlag = 0 + + os.system('csw_daemon &') + + + global cs5435_fanattrnodes + global cs5435_psuattrnodes + + for num in range(1,6): + name = 'fan{}'.format(num) + fannode = cs5435_fanattr(name) + cs5435_fanattrnodes.append(fannode) + for num in range(1,3): + name = 'psu{}'.format(num) + psunode = cs5435_psuattr(name) + cs5435_psuattrnodes.append(psunode) + + tempcontrol = system_init_coretemppath() + + misclogger.info("%s: %s misc start." % ( threadName, time.ctime(time.time()))) + count = 0 + while 1: + count = count + 1 + ret = system_check_psuspresent() + ret = system_check_fansstate() + + if count % 10 == 0: + misclogger.info(": adjust fans and check psu direction.") + system_check_psusdirection() + if tempcontrol == 0: + system_monitor_temperature() + count = 0 + time.sleep(delay) + + return + +if __name__ == '__main__': + target=system_misc_polling("Thread-misc",10) + diff --git a/platform/nephos/sonic-platform-modules-cig/cs5435-54p/utils/cig_cs5435_util.py b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/utils/cig_cs5435_util.py new file mode 100755 index 000000000000..03302592257c --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs5435-54p/utils/cig_cs5435_util.py @@ -0,0 +1,563 @@ +#!/usr/bin/env python +# +# Copyright (C) 2018 Cambridge, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +""" +Usage: %(scriptName)s [options] command object + +options: + -h | --help : this help message + -d | --debug : run with debug mode + -f | --force : ignore error during installation or clean +command: + install : install drivers and generate related sysfs nodes + clean : uninstall drivers and remove related sysfs nodes + show : show all systen status + sff : dump SFP eeprom + set : change board setting with fan|led|sfp +""" + +import os +import commands +import sys, getopt +import logging +import re +import time +from collections import namedtuple + + + + +PROJECT_NAME = 'cs5435_54p' +version = '0.1.1' +verbose = False +DEBUG = False +args = [] +ALL_DEVICE = {} +DEVICE_NO = {'led':9, 'fan':5, 'thermal':4, 'psu':2, 'sfp':54} +FORCE = 0 +CPU_TYPE = 'C3308' + +if DEBUG == True: + print sys.argv[0] + print 'ARGV :', sys.argv[1:] + + +def main(): + global DEBUG + global args + global FORCE + + if len(sys.argv)<2: + show_help() + + options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help', + 'debug', + 'force', + ]) + if DEBUG == True: + print options + print args + print len(sys.argv) + + for opt, arg in options: + if opt in ('-h', '--help'): + show_help() + elif opt in ('-d', '--debug'): + DEBUG = True + logging.basicConfig(level=logging.INFO) + elif opt in ('-f', '--force'): + FORCE = 1 + else: + logging.info('no option') + for arg in args: + if arg == 'install': + do_install() + elif arg == 'clean': + do_uninstall() + elif arg == 'show': + device_traversal() + elif arg == 'sff': + if len(args)!=2: + show_eeprom_help() + elif int(args[1]) ==0 or int(args[1]) > DEVICE_NO['sfp']: + show_eeprom_help() + else: + show_eeprom(args[1]) + return + elif arg == 'set': + if len(args)<3: + show_set_help() + else: + set_device(args[1:]) + return + else: + show_help() + + + return 0 + +def show_help(): + print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]} + sys.exit(0) + +def show_set_help(): + cmd = sys.argv[0].split("/")[-1]+ " " + args[0] + print cmd +" [led|sfp|fan]" + print " use \""+ cmd + " led 0-4 \" to set led color" + print " use \""+ cmd + " fan 0-100\" to set fan duty percetage" + print " use \""+ cmd + " sfp 1-54 {0|1}\" to set sfp# tx_disable" + sys.exit(0) + +def show_eeprom_help(): + cmd = sys.argv[0].split("/")[-1]+ " " + args[0] + print " use \""+ cmd + " 1-54 \" to dump sfp# eeprom" + sys.exit(0) + +def my_log(txt): + if DEBUG == True: + print "[ROY]"+txt + return + +def log_os_system(cmd, show): + logging.info('Run :'+cmd) + status, output = commands.getstatusoutput(cmd) + my_log (cmd +"with result:" + str(status)) + my_log (" output:"+output) + if status: + logging.info('Failed :'+cmd) + if show: + print('Failed :'+cmd) + return status, output + +def driver_check(): + for count in range(1,5): + time.sleep(1) + ret, lsmod = log_os_system("lsmod| grep i2c_i801", 0) + if len(lsmod) > 2: + log_os_system("rmmod i2c_i801", 0) + break + + ret, lsmod = log_os_system("lsmod| grep i2c_designware_platform", 0) + if len(lsmod) > 2: + log_os_system("rmmod i2c_designware_platform", 0) + log_os_system("modprobe i2c-designware-platform", 0) + + ret, lsmod = log_os_system("lsmod| grep cig", 0) + logging.info('mods:'+lsmod) + if len(lsmod) ==0: + return False + return True + + + +kos = [ + 'depmod', + 'modprobe i2c_dev', + 'modprobe i2c_mux_pca954x force_deselect_on_exit=1', + 'modprobe x86-64-cig-cs5435-54p-sysfs ' , + 'modprobe x86-64-cig-cs5435-54p-cpld ' , + 'modprobe x86-64-cig-cs5435-54p-fan' , + 'modprobe x86-64-cig-cs5435-54p-psu' , + 'modprobe x86-64-cig-cs5435-54p-sfp' , + 'modprobe x86-64-cig-cs5435-54p-led' ] + +def driver_install(): + global FORCE + + for i in range(0,len(kos)): + if i == 4: + ret, CPU_TYPE = log_os_system("cat /proc/cpuinfo | grep \"model name\" | cut -b 32-39 | head -n 1", 0) + if CPU_TYPE=='i3-6100U': + kos[i] =kos[i] + 'board_id=1' + ret, CPU_TYPE = log_os_system("cat /proc/cpuinfo | grep \"model name\" | cut -b 36-40 | head -n 1", 0) + if CPU_TYPE=='C3758' or CPU_TYPE=='C3308': + kos[i] =kos[i] + 'board_id=2' + + status, output = log_os_system(kos[i], 1) + if status: + if FORCE == 0: + return status + return 0 + +def driver_uninstall(): + global FORCE + for i in range(0,len(kos)): + rm = kos[-(i+1)].replace("modprobe", "modprobe -rq") + rm = rm.replace("insmod", "rmmod") + status, output = log_os_system(rm, 1) + if status: + if FORCE == 0: + return status + return 0 + +led_prefix ='/sys/class/leds/'+PROJECT_NAME+'_led::' +hwmon_types = {'led': ['sys','fan','fan1','fan2','fan3','fan4','fan5','psu1','psu2']} +hwmon_nodes = {'led': ['brightness'] } +hwmon_prefix ={'led': led_prefix} + +i2c_prefix = '/sys/bus/i2c/devices/' +i2c_bus = {'thermal': ['4-0048','4-0049', '5-004a', '5-004b'] , + 'psu': ['5-005a','5-005b'], + 'sfp': ['-0050']} +i2c_nodes = {'thermal': ['hwmon/hwmon*/temp1_input'] , + 'psu': ['psu_present ', 'psu_power_good'] , + 'sfp': ['sfp_is_present ', 'sfp_tx_disable']} + +fan_prefix ='/sys/bus/platform/devices/'+PROJECT_NAME+'_fan' +fan_types = {'fan': ['fan1','fan2', 'fan3', 'fan4', 'fan5']} +fan_nodes = {'fan': ['state', 'front_speed_rpm', 'rear_speed_rpm', 'fault']} + + +sfp_map = [8,9,10,11,12,13,14,15,16, + 17,18,19,20,21,22,23,24,25,26, + 27,28,29,30,31,32,33,34,35,36, + 37,38,39,40,41,42,43,44,45,46, + 47,48,49,50,51,52,53,54,55,56, + 57,60,61,62,63] + +mknod =[ + 'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-2/new_device', + 'echo pca9548 0x72 > /sys/bus/i2c/devices/i2c-2/new_device', + 'echo pca9548 0x73 > /sys/bus/i2c/devices/i2c-2/new_device', + 'echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-2/new_device', + 'echo pca9548 0x75 > /sys/bus/i2c/devices/i2c-3/new_device', + 'echo pca9548 0x76 > /sys/bus/i2c/devices/i2c-3/new_device', + 'echo pca9548 0x77 > /sys/bus/i2c/devices/i2c-3/new_device', + 'echo lm75 0x48 > /sys/bus/i2c/devices/i2c-4/new_device', + 'echo lm75 0x49 > /sys/bus/i2c/devices/i2c-4/new_device', + 'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-5/new_device', + 'echo lm75 0x4b > /sys/bus/i2c/devices/i2c-5/new_device', + 'echo cs5435_54p_psu1 0x5a > /sys/bus/i2c/devices/i2c-5/new_device', + 'echo cs5435_54p_psu2 0x5b > /sys/bus/i2c/devices/i2c-5/new_device', + 'echo cs5435_54p_psu1 0x52 > /sys/bus/i2c/devices/i2c-5/new_device', + 'echo cs5435_54p_psu2 0x53 > /sys/bus/i2c/devices/i2c-5/new_device', + 'echo 24c128 0x57 > /sys/bus/i2c/devices/i2c-7/new_device'] + +port = 0 + +def device_install(): + global FORCE + global port + for i in range(0,len(mknod)): + #all nodes need times to built new i2c buses + time.sleep(1) + + status, output = log_os_system(mknod[i], 1) + if status: + print output + if FORCE == 0: + return status + + for i in range(0,len(sfp_map)): + if (i == 50): + port = port + 3 + else: + port = port + 1 + + + status, output =log_os_system("echo cs5435_54p_sfp"+str(port)+" 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status + + if port <= 48: + status, output =log_os_system("echo cs5435_54p_sfp"+str(port)+" 0x51 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status + + return + +def device_uninstall(): + global FORCE + + for i in range(0,len(sfp_map)): + target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/delete_device" + status, output =log_os_system("echo 0x50 > "+ target, 1) + if status: + print output + if FORCE == 0: + return status + + nodelist = mknod + + for i in range(len(nodelist)): + target = nodelist[-(i+1)] + temp = target.split() + del temp[1] + temp[-1] = temp[-1].replace('new_device', 'delete_device') + status, output = log_os_system(" ".join(temp), 1) + if status: + print output + if FORCE == 0: + return status + + return + +def system_ready(): + if driver_check() == False: + return False + if not device_exist(): + return False + return True + +def do_install(): + print "Checking system...." + if driver_check() == False: + print "No driver, installing...." + status = driver_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper()+" drivers detected...." + if not device_exist(): + print "No device, installing...." + status = device_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper()+" devices detected...." + return + +def do_uninstall(): + print "Checking system...." + if not device_exist(): + print PROJECT_NAME.upper() +" has no device installed...." + else: + print "Removing device...." + status = device_uninstall() + if status: + if FORCE == 0: + return status + + if driver_check()== False : + print PROJECT_NAME.upper() +" has no driver installed...." + else: + print "Removing installed driver...." + status = driver_uninstall() + if status: + if FORCE == 0: + return status + + return + +def devices_info(): + global DEVICE_NO + global ALL_DEVICE + global i2c_bus, hwmon_types, fan_types + for key in DEVICE_NO: + ALL_DEVICE[key]= {} + for i in range(0,DEVICE_NO[key]): + ALL_DEVICE[key][key+str(i+1)] = [] + + for key in i2c_bus: + buses = i2c_bus[key] + nodes = i2c_nodes[key] + for i in range(0,len(buses)): + for j in range(0,len(nodes)): + if 'sfp' == key: + for k in range(0,DEVICE_NO[key]): + node = key+str(k+1) + path = i2c_prefix+ str(sfp_map[k])+ buses[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + else: + node = key+str(i+1) + path = i2c_prefix+ buses[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + + for key in hwmon_types: + itypes = hwmon_types[key] + nodes = hwmon_nodes[key] + for i in range(0,len(itypes)): + for j in range(0,len(nodes)): + node = key+"_"+itypes[i] + path = hwmon_prefix[key]+ itypes[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][ key+str(i+1)].append(path) + + for key in fan_types: + itypes = fan_types[key] + nodes = fan_nodes[key] + for i in range(0,len(itypes)): + for j in range(0,len(nodes)): + node = key+"_"+itypes[i] + path = fan_prefix+"/"+ itypes[i]+"_"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][ key+str(i+1)].append(path) + + #show dict all in the order + if DEBUG == True: + for i in sorted(ALL_DEVICE.keys()): + print(i+": ") + for j in sorted(ALL_DEVICE[i].keys()): + print(" "+j) + for k in (ALL_DEVICE[i][j]): + print(" "+" "+k) + return + +def show_eeprom(index): + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + node = ALL_DEVICE['sfp'] ['sfp'+str(index)][0] + node = node.replace(node.split("/")[-1], 'sfp_eeprom') + # check if got hexdump command in current environment + ret, log = log_os_system("which hexdump", 0) + ret, log2 = log_os_system("which busybox hexdump", 0) + if len(log): + hex_cmd = 'hexdump' + elif len(log2): + hex_cmd = ' busybox hexdump' + else: + log = 'Failed : no hexdump cmd!!' + logging.info(log) + print log + return 1 + + print node + ":" + ret, log = log_os_system("cat "+node+"| "+hex_cmd+" -C", 1) + if ret==0: + print log + else: + print "**********device no found**********" + return + +def set_device(args): + global DEVICE_NO + global ALL_DEVICE + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + + if args[0]=='led': + if int(args[1])>4: + show_set_help() + return + #print ALL_DEVICE['led'] + for i in range(0,len(ALL_DEVICE['led'])): + for k in (ALL_DEVICE['led']['led'+str(i+1)]): + ret, log = log_os_system("echo "+args[1]+" >"+k, 1) + if ret: + return ret + elif args[0]=='fan': + if int(args[1])>100: + show_set_help() + return + #print ALL_DEVICE['fan'] + #fan1~6 is all fine, all fan share same setting + node = ALL_DEVICE['fan'] ['fan1'][0] + node = node.replace(node.split("/")[-1], 'fan_duty_cycle_percentage') + ret, log = log_os_system("cat "+ node, 1) + if ret==0: + print ("Previous fan duty: " + log.strip() +"%") + ret, log = log_os_system("echo "+args[1]+" >"+node, 1) + if ret==0: + print ("Current fan duty: " + args[1] +"%") + return ret + elif args[0]=='sfp': + if int(args[1])> DEVICE_NO[args[0]] or int(args[1])==0: + show_set_help() + return + if len(args)<2: + show_set_help() + return + + if int(args[2])>1: + show_set_help() + return + + #print ALL_DEVICE[args[0]] + for i in range(0,len(ALL_DEVICE[args[0]])): + for j in ALL_DEVICE[args[0]][args[0]+str(args[1])]: + if j.find('tx_disable')!= -1: + ret, log = log_os_system("echo "+args[2]+" >"+ j, 1) + if ret: + return ret + + return + +def get_value(input): + digit = re.findall('\d+', input) + return int(digit[0]) + + +def get_ledname(ledx): + name_table={'led1':'SYS','led2':'FSTUS','led3':'FAN1','led4':'FAN2','led5':'FAN3','led6':'FAN4','led7':'FAN5','led8':'PSU1','led9':'PSU2'} + if name_table.has_key(ledx): + name = name_table[ledx] + else: + name = ledx + return name + + +def device_traversal(): + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + for i in sorted(ALL_DEVICE.keys()): + print("============================================") + print(i.upper()+": ") + print("============================================") + + for j in sorted(ALL_DEVICE[i].keys(), key=get_value): + nwnamex = get_ledname(j) + if nwnamex == j: + print " "+j+":", + else: + print " "+nwnamex+":", + for k in (ALL_DEVICE[i][j]): + ret, log = log_os_system("cat "+k, 0) + func = k.split("/")[-1].strip() + func = re.sub(j+'_','',func,1) + func = re.sub(i.lower()+'_','',func,1) + if ret==0: + print func+"="+log+" ", + else: + print func+"="+"X"+" ", + print + print("----------------------------------------------------------------") + + + print + return + +def device_exist(): + ret1, log = log_os_system("ls "+i2c_prefix+"*0077", 0) + ret2, log = log_os_system("ls "+i2c_prefix+"i2c-3", 0) + return not(ret1 or ret2) + + +if __name__ == "__main__": + main() diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/classes/__init__.py b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/classes/__init__.py new file mode 100755 index 000000000000..e69de29bb2d1 diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/classes/fanutil.py b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/classes/fanutil.py new file mode 100755 index 000000000000..e69de29bb2d1 diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/classes/thermalutil.py b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/classes/thermalutil.py new file mode 100755 index 000000000000..e69de29bb2d1 diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/Makefile b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/Makefile new file mode 100644 index 000000000000..e37e985a2147 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/Makefile @@ -0,0 +1,6 @@ +obj-m :=x86-64-cig-cs6436-54p-sysfs.o \ + x86-64-cig-cs6436-54p-cpld.o \ + x86-64-cig-cs6436-54p-fan.o \ + x86-64-cig-cs6436-54p-led.o \ + x86-64-cig-cs6436-54p-psu.o \ + x86-64-cig-cs6436-54p-sfp.o diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/i2c-algo-lpc.h b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/i2c-algo-lpc.h new file mode 100644 index 000000000000..749aa94ef934 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/i2c-algo-lpc.h @@ -0,0 +1,222 @@ +/* -------------------------------------------------------------------- + + * A hwmon driver for the CIG cs6436-54P + * + * Copyright (C) 2018 Cambridge, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 I2C_LPC_H +#define I2C_LPC_H 1 + +/* ----- Control register bits ---------------------------------------- */ +#define I2C_LPC_PIN 0x80 +#define I2C_LPC_ESO 0x40 +#define I2C_LPC_ES1 0x20 +#define I2C_LPC_ES2 0x10 +#define I2C_LPC_ENI 0x08 + +#define I2C_LPC_STO 0x40 +#define I2C_LPC_ACK 0x01 + +/*command register*/ +#define I2C_LPC_STA 0x80 +#define I2C_LPC_ABT 0x40 + +/*status register*/ +#define I2C_LPC_TBE 0x02 +#define I2C_LPC_IBB 0x80 +#define I2C_LPC_RBF 0x01 +#define I2C_LPC_TD 0x08 + +#define I2C_LPC_START I2C_LPC_STA +#define I2C_LPC_STOP I2C_LPC_STO +#define I2C_LPC_REPSTART I2C_LPC_STA +#define I2C_LPC_IDLE + +/* ----- Status register bits ----------------------------------------- */ +/*#define I2C_LPC_PIN 0x80 as above*/ + +#define I2C_LPC_INI 0x40 /* 1 if not initialized */ +#define I2C_LPC_STS 0x20 +#define I2C_LPC_BER 0x10 +#define I2C_LPC_AD0 0x08 +#define I2C_LPC_LRB 0x08 +#define I2C_LPC_AAS 0x04 +#define I2C_LPC_LAB 0x02 +#define I2C_LPC_BB 0x80 + +/* ----- Chip clock frequencies --------------------------------------- */ +#define I2C_LPC_CLK3 0x00 +#define I2C_LPC_CLK443 0x10 +#define I2C_LPC_CLK6 0x14 +#define I2C_LPC_CLK 0x18 +#define I2C_LPC_CLK12 0x1c + +/* ----- transmission frequencies ------------------------------------- */ +#define I2C_LPC_TRNS90 0x00 /* 90 kHz */ +#define I2C_LPC_TRNS45 0x01 /* 45 kHz */ +#define I2C_LPC_TRNS11 0x02 /* 11 kHz */ +#define I2C_LPC_TRNS15 0x03 /* 1.5 kHz */ + + +#define I2C_LPC_OWNADR 0 +#define I2C_LPC_INTREG I2C_LPC_ES2 +#define I2C_LPC_CLKREG I2C_LPC_ES1 + +#define I2C_LPC_REG_TEST 0x01 +#define I2C_LPC_REG_BUS_SEL 0x80 +#define I2C_LPC_REG_DEVICE_ADDR 0x81 +#define I2C_LPC_REG_BYTE_COUNT 0x83 +#define I2C_LPC_REG_COMMAND 0x84 +#define I2C_LPC_REG_STATUS 0x85 +#define I2C_LPC_REG_DATA_RX1 0x86 +#define I2C_LPC_REG_DATA_RX2 0x87 +#define I2C_LPC_REG_DATA_RX3 0x88 +#define I2C_LPC_REG_DATA_RX4 0x89 +#define I2C_LPC_REG_DATA_TX1 0x8a +#define I2C_LPC_REG_DATA_TX2 0x8b +#define I2C_LPC_REG_DATA_TX3 0x8c +#define I2C_LPC_REG_DATA_TX4 0x8d + + +#define ADDR_REG_SFP_STATUS_ADDR 0X62 //reg addr +R/W# //1031 +#define ADDR_REG_SFP_STATUS_TX 0X63 // write data +#define ADDR_REG_SFP_STATUS_RX 0X64 //read data +#define ADDR_REG_SFP_STATUS_COMMAND 0X65 //cmd bit7=1,go +#define ADDR_REG_SFP_STATUS_STATUS 0X66 //status + +#define CPLD_MASTER_INTERRUPT_STATUS_REG 0x20 +#define CPLD_MASTER_INTERRUPT_MASK_REG 0x21 +#define CPLD_MASTER_INTERRUPT_ALL 0x3f +#define CPLD_MASTER_INTERRUPT_CPLD2 0x20 +#define CPLD_MASTER_INTERRUPT_CPLD1 0x10 +#define CPLD_MASTER_INTERRUPT_PSU2 0x08 +#define CPLD_MASTER_INTERRUPT_PSU1 0x04 +#define CPLD_MASTER_INTERRUPT_6320 0x02 +#define CPLD_MASTER_INTERRUPT_LSW 0x01 + + + +#define CPLD_SLAVE1_INTERRUPT_STATUS_L_REG 0x20 +#define CPLD_SLAVE1_INTERRUPT_STATUS_H_REG 0x21 +#define CPLD_SLAVE2_INTERRUPT_STATUS_L_REG 0x22 +#define CPLD_SLAVE2_INTERRUPT_STATUS_H_REG 0x23 +#define CPLD_SLAVE1_INTERRUPT_MASK_REG 0x24 +#define CPLD_SLAVE2_INTERRUPT_MASK_REG 0x25 + + +#define CPLD_SLAVE1_PRESENT08_REG 0x01 +#define CPLD_SLAVE1_PRESENT16_REG 0x02 +#define CPLD_SLAVE1_PRESENT24_REG 0x03 +#define CPLD_SLAVE2_PRESENT32_REG 0x04 +#define CPLD_SLAVE2_PRESENT40_REG 0x05 +#define CPLD_SLAVE2_PRESENT48_REG 0x06 + +#define CPLD_SLAVE1_RX_LOST08_REG 0x07 +#define CPLD_SLAVE1_RX_LOST16_REG 0x08 +#define CPLD_SLAVE1_RX_LOST24_REG 0x09 +#define CPLD_SLAVE2_RX_LOST32_REG 0x0a +#define CPLD_SLAVE2_RX_LOST40_REG 0x0b +#define CPLD_SLAVE2_RX_LOST48_REG 0x0c + +#define CPLD_SLAVE1_TX_FAULT08_REG 0x0d +#define CPLD_SLAVE1_TX_FAULT16_REG 0x0e +#define CPLD_SLAVE1_TX_FAULT24_REG 0x0f +#define CPLD_SLAVE2_TX_FAULT32_REG 0x10 +#define CPLD_SLAVE2_TX_FAULT40_REG 0x11 +#define CPLD_SLAVE2_TX_FAULT48_REG 0x12 + +#define CPLD_SLAVE2_PRESENT56_REG 0x19 +#define CPLD_SLAVE2_QSFP_CR56_REG 0x1a + + +#define CPLD_SLAVE1_INTERRUPT_PRESENT08 0x0001 +#define CPLD_SLAVE1_INTERRUPT_PRESENT16 0x0002 +#define CPLD_SLAVE1_INTERRUPT_PRESENT24 0x0004 +#define CPLD_SLAVE2_INTERRUPT_PRESENT32 0x0001 +#define CPLD_SLAVE2_INTERRUPT_PRESENT40 0x0002 +#define CPLD_SLAVE2_INTERRUPT_PRESENT48 0x0004 + +#define CPLD_SLAVE2_INTERRUPT_QSFP_CR56 0x0200 +#define CPLD_SLAVE2_INTERRUPT_PRESENT56 0x0400 + +#define CPLD_SLAVE1_INTERRUPT_RX_LOST08 0x0008 +#define CPLD_SLAVE1_INTERRUPT_RX_LOST16 0x0010 +#define CPLD_SLAVE1_INTERRUPT_RX_LOST24 0x0020 +#define CPLD_SLAVE2_INTERRUPT_RX_LOST32 0x0008 +#define CPLD_SLAVE2_INTERRUPT_RX_LOST40 0x0010 +#define CPLD_SLAVE2_INTERRUPT_RX_LOST48 0x0020 + +#define CPLD_SLAVE1_INTERRUPT_TX_FAULT08 0x0040 +#define CPLD_SLAVE1_INTERRUPT_TX_FAULT16 0x0080 +#define CPLD_SLAVE1_INTERRUPT_TX_FAULT24 0x0100 +#define CPLD_SLAVE2_INTERRUPT_TX_FAULT32 0x0040 +#define CPLD_SLAVE2_INTERRUPT_TX_FAULT40 0x0080 +#define CPLD_SLAVE2_INTERRUPT_TX_FAULT48 0x0100 + + + + + + + +#define WAIT_TIME_OUT_COUNT 100 + + +struct i2c_algo_lpc_data { + void *data; /* private data for lolevel routines */ + void (*setlpc) (void *data, int ctl, int val); + int (*getlpc) (void *data, int ctl); + int (*getown) (void *data); + int (*getclock) (void *data); + void (*waitforpin) (void *data); + + int (*xfer_begin) (void *data); + int (*xfer_end) (void *data); + + /* Multi-master lost arbitration back-off delay (msecs) + * This should be set by the bus adapter or knowledgable client + * if bus is multi-mastered, else zero + */ + unsigned long lab_mdelay; +}; + + +struct subsys_private { + struct kset subsys; + struct kset *devices_kset; + struct list_head interfaces; + struct mutex mutex; + + struct kset *drivers_kset; + struct klist klist_devices; + struct klist klist_drivers; + struct blocking_notifier_head bus_notifier; + unsigned int drivers_autoprobe:1; + struct bus_type *bus; + + struct kset glue_dirs; + struct class *class; +}; + +void cs6436_54p_sysfs_add_client(struct i2c_client *client); +void cs6436_54p_sysfs_remove_client(struct i2c_client *client); + + +#endif /* I2C_LPC8584_H */ diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-cpld.c b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-cpld.c new file mode 100644 index 000000000000..1c7930b3d268 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-cpld.c @@ -0,0 +1,2202 @@ +/* + * A hwmon driver for the CIG cs6436-54P CPLD + * + * Copyright (C) 2018 Cambridge, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 "i2c-algo-lpc.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef CPLD_USER +# include +#else +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + + + + + +/********************************************** Start ********************************************************/ + +/* + * ISA bus. + */ + +static void platform_isa_bus_release(struct device * dev) +{ + return ; +} + + +static struct device isa_bus = { + .init_name = "lpc-isa", + .release = platform_isa_bus_release, +}; + +struct isa_dev { + struct device dev; + struct device *next; + unsigned int id; +}; + +#define to_isa_dev(x) container_of((x), struct isa_dev, dev) + +static int isa_bus_match(struct device *dev, struct device_driver *driver) +{ + struct isa_driver *isa_driver = to_isa_driver(driver); + + if (dev->platform_data == isa_driver) { + if (!isa_driver->match || + isa_driver->match(dev, to_isa_dev(dev)->id)) + return 1; + dev->platform_data = NULL; + } + return 0; +} + +static int isa_bus_probe(struct device *dev) +{ + struct isa_driver *isa_driver = dev->platform_data; + + if (isa_driver->probe) + return isa_driver->probe(dev, to_isa_dev(dev)->id); + + return 0; +} + +static int isa_bus_remove(struct device *dev) +{ + struct isa_driver *isa_driver = dev->platform_data; + + if (isa_driver->remove) + return isa_driver->remove(dev, to_isa_dev(dev)->id); + + return 0; +} + +static void isa_bus_shutdown(struct device *dev) +{ + struct isa_driver *isa_driver = dev->platform_data; + + if (isa_driver->shutdown) + isa_driver->shutdown(dev, to_isa_dev(dev)->id); +} + +static int isa_bus_suspend(struct device *dev, pm_message_t state) +{ + struct isa_driver *isa_driver = dev->platform_data; + + if (isa_driver->suspend) + return isa_driver->suspend(dev, to_isa_dev(dev)->id, state); + + return 0; +} + +static int isa_bus_resume(struct device *dev) +{ + struct isa_driver *isa_driver = dev->platform_data; + + if (isa_driver->resume) + return isa_driver->resume(dev, to_isa_dev(dev)->id); + + return 0; +} + +static struct bus_type isa_bus_type = { + .name = "lpc-isa", + .match = isa_bus_match, + .probe = isa_bus_probe, + .remove = isa_bus_remove, + .shutdown = isa_bus_shutdown, + .suspend = isa_bus_suspend, + .resume = isa_bus_resume +}; + +static void isa_dev_release(struct device *dev) +{ + kfree(to_isa_dev(dev)); +} + +void lpc_unregister_driver(struct isa_driver *isa_driver) +{ + struct device *dev = isa_driver->devices; + + while (dev) { + struct device *tmp = to_isa_dev(dev)->next; + device_unregister(dev); + dev = tmp; + } + driver_unregister(&isa_driver->driver); +} + + +int lpc_register_driver(struct isa_driver *isa_driver, unsigned int ndev) +{ + int error; + unsigned int id; + + isa_driver->driver.bus = &isa_bus_type; + isa_driver->devices = NULL; + + error = driver_register(&isa_driver->driver); + if (error) + return error; + + for (id = 0; id < ndev; id++) { + struct isa_dev *isa_dev; + + isa_dev = kzalloc(sizeof *isa_dev, GFP_KERNEL); + if (!isa_dev) { + error = -ENOMEM; + break; + } + + isa_dev->dev.parent = &isa_bus; + isa_dev->dev.bus = &isa_bus_type; + + dev_set_name(&isa_dev->dev, "%s.%u", + isa_driver->driver.name, id); + isa_dev->dev.platform_data = isa_driver; + isa_dev->dev.release = isa_dev_release; + isa_dev->id = id; + + isa_dev->dev.coherent_dma_mask = DMA_BIT_MASK(24); + isa_dev->dev.dma_mask = &isa_dev->dev.coherent_dma_mask; + + error = device_register(&isa_dev->dev); + if (error) { + put_device(&isa_dev->dev); + break; + } + + if (isa_dev->dev.platform_data) { + isa_dev->next = isa_driver->devices; + isa_driver->devices = &isa_dev->dev; + } else + device_unregister(&isa_dev->dev); + } + + if (!error && !isa_driver->devices) + error = -ENODEV; + + if (error) + isa_unregister_driver(isa_driver); + + return error; +} + + +int lpc_bus_init(void) +{ + int error; + + error = bus_register(&isa_bus_type); + if (!error) { + error = device_register(&isa_bus); + if (error) + bus_unregister(&isa_bus_type); + } + return error; +} + +void lpc_bus_exit(void) +{ + + device_unregister(&isa_bus); + + bus_unregister(&isa_bus_type); +} + + +/********************************************** End ********************************************************/ + + + + + + +/********************************************** Start ********************************************************/ +/* + * module parameters: + */ +static int i2c_debug = 0; +static struct mutex lpc_lock; + + +#define DEB2(x) if (i2c_debug == 2) x +#define DEB3(x) if (i2c_debug == 3) x + /* print several statistical values */ +#define DEBPROTO(x) if (i2c_debug == 9) x; + /* debug the protocol by showing transferred bits */ +#define DEF_TIMEOUT 160 + + + +/* setting states on the bus with the right timing: */ + +#define set_lpc(adap, ctl, val) adap->setlpc(adap->data, ctl, val) +#define get_lpc(adap, ctl) adap->getlpc(adap->data, ctl) +#define get_own(adap) adap->getown(adap->data) +#define get_clock(adap) adap->getclock(adap->data) +#define i2c_outaddr(adap, val) adap->setlpc(adap->data, I2C_LPC_REG_DEVICE_ADDR, val) + +#define i2c_outbyte1(adap, val) adap->setlpc(adap->data, I2C_LPC_REG_DATA_TX1, val) +#define i2c_outbyte2(adap, val) adap->setlpc(adap->data, I2C_LPC_REG_DATA_TX2, val) +#define i2c_outbyte3(adap, val) adap->setlpc(adap->data, I2C_LPC_REG_DATA_TX3, val) +#define i2c_outbyte4(adap, val) adap->setlpc(adap->data, I2C_LPC_REG_DATA_TX4, val) +#define i2c_inbyte1(adap) adap->getlpc(adap->data, I2C_LPC_REG_DATA_RX1) +#define i2c_inbyte2(adap) adap->getlpc(adap->data, I2C_LPC_REG_DATA_RX2) +#define i2c_inbyte3(adap) adap->getlpc(adap->data, I2C_LPC_REG_DATA_RX3) +#define i2c_inbyte4(adap) adap->getlpc(adap->data, I2C_LPC_REG_DATA_RX4) + + + +#define LPC_FPRINTF_LOG_PATH "/tmp/file.log" +struct file *lpc_fprintf_file = NULL; + +static int lpc_fprintf_debug(const char *fmt, ...) +{ + char lpc_fprintf_buf[256]={0}; + struct va_format vaf; + va_list args; + int r; + mm_segment_t old_fs; + struct timeval tv; + struct rtc_time tm; + + do_gettimeofday(&tv); + + rtc_time_to_tm(tv.tv_sec,&tm); + + va_start(args, fmt); + vaf.fmt = fmt; + vaf.va = &args; + r=snprintf(lpc_fprintf_buf,sizeof(lpc_fprintf_buf),"[%04d.%08d] %pV\n",tm.tm_sec, (int)tv.tv_usec, &vaf); + va_end(args); + old_fs = get_fs(); + set_fs(KERNEL_DS); + vfs_write(lpc_fprintf_file, (char *)&lpc_fprintf_buf, strlen(lpc_fprintf_buf), &lpc_fprintf_file->f_pos); + set_fs(old_fs); + memset(lpc_fprintf_buf,0x0,sizeof(lpc_fprintf_buf)); + return r; + +} + + + +static int lpc_fprintf_init(void) +{ + printk("lpc_fprintf_init.\n"); + + if(lpc_fprintf_file == NULL) + lpc_fprintf_file = filp_open(LPC_FPRINTF_LOG_PATH, O_RDWR | O_APPEND | O_CREAT, 0644); + + if (IS_ERR(lpc_fprintf_file)) { + printk("Error occured while opening file %s, exiting...\n", LPC_FPRINTF_LOG_PATH); + return -1; + } + + return 0; +} + +static int lpc_fprintf_exit(void) +{ + printk("lpc_fprintf_exit.\n"); + + if(lpc_fprintf_file != NULL) + filp_close(lpc_fprintf_file, NULL); + + return 0; +} + + +/* other auxiliary functions */ + + +void print_reg(struct i2c_algo_lpc_data *adap) +{ + unsigned char status; + DEBPROTO(lpc_fprintf_debug("================================================\n");) + status = get_lpc(adap, I2C_LPC_REG_BUS_SEL); + DEBPROTO(lpc_fprintf_debug("%s select reg %x : %x\n",__func__,I2C_LPC_REG_BUS_SEL, status);) + status = get_lpc(adap, I2C_LPC_REG_BYTE_COUNT); + DEBPROTO(lpc_fprintf_debug("%s count reg %x : %x\n",__func__,I2C_LPC_REG_BYTE_COUNT, status);) + + status = get_lpc(adap, I2C_LPC_REG_COMMAND); + DEBPROTO(lpc_fprintf_debug("%s command reg %x : %x\n",__func__,I2C_LPC_REG_COMMAND, status);) + status = get_lpc(adap, I2C_LPC_REG_DEVICE_ADDR); + DEBPROTO(lpc_fprintf_debug("%s address reg %x : %x\n",__func__,I2C_LPC_REG_DEVICE_ADDR, status);) + + status = get_lpc(adap, I2C_LPC_REG_STATUS); + DEBPROTO(lpc_fprintf_debug("%s status reg %x : %x\n",__func__,I2C_LPC_REG_STATUS, status);) +} + + + +static void i2c_repstart(struct i2c_algo_lpc_data *adap) +{ + DEBPROTO(lpc_fprintf_debug("%s :\n",__func__);) + set_lpc(adap, I2C_LPC_REG_COMMAND, I2C_LPC_REPSTART); +} + +static void i2c_stop(struct i2c_algo_lpc_data *adap) +{ + DEBPROTO(lpc_fprintf_debug("%s :\n",__func__);) + set_lpc(adap, I2C_LPC_REG_COMMAND, I2C_LPC_STOP); + udelay(60); + set_lpc(adap, I2C_LPC_REG_COMMAND, 0x00); +} + + + + +static void i2c_start(struct i2c_algo_lpc_data *adap) +{ + print_reg(adap); + + set_lpc(adap, I2C_LPC_REG_COMMAND, I2C_LPC_START); + + print_reg(adap); +} + + + + +static int wait_for_bb(struct i2c_algo_lpc_data *adap) +{ + + int timeout = DEF_TIMEOUT; + int status; + + while (--timeout) { + status = get_lpc(adap, I2C_LPC_REG_STATUS); + + DEBPROTO(lpc_fprintf_debug("%s : Waiting for bus free status : %x\n",__func__,status);) + + if(status == I2C_LPC_TD) + { + DEBPROTO(lpc_fprintf_debug("%s : Bus is free status : %x\n",__func__,status);) + break; + } + } + + if (timeout == 0) { + DEBPROTO(lpc_fprintf_debug("%s : Timeout for free busy status : %x\n",__func__,status);) + return -ETIMEDOUT; + } + + + + return 0; +} + + +static int wait_for_be(int mode,struct i2c_algo_lpc_data *adap) +{ + + int timeout = DEF_TIMEOUT; + unsigned char status; + + + while (--timeout) { + + status = get_lpc(adap, I2C_LPC_REG_STATUS); + + DEBPROTO(lpc_fprintf_debug("%s : Waiting for bus empty status : %x\n",__func__,status);) + + if(mode == 1) + { + if((status & I2C_LPC_IBB) && (status & I2C_LPC_TBE)) + { + DEBPROTO(lpc_fprintf_debug("%s : Bus is empty status : %x\n",__func__,status);) + break; + } + } + else + { + if(status & I2C_LPC_TD) + { + DEBPROTO(lpc_fprintf_debug("%s : Bus is empty status : %x\n",__func__,status);) + break; + } + } + + status = get_lpc(adap, I2C_LPC_REG_TEST); + + DEBPROTO(lpc_fprintf_debug("%s : The test register data : %x\n",__func__,status);) + udelay(1); /* wait for 100 us */ + } + + if (timeout == 0) { + DEBPROTO(lpc_fprintf_debug("%s : Timeout waiting for Bus Empty\n",__func__);) + return -ETIMEDOUT; + } + + return 0; +} + + +static int wait_for_bf(struct i2c_algo_lpc_data *adap) +{ + + int timeout = DEF_TIMEOUT; + int status; + + + while (--timeout) { + status = get_lpc(adap, I2C_LPC_REG_STATUS); + + DEBPROTO(lpc_fprintf_debug("%s : Waiting for bus full status : %x\n",__func__,status);) + + if(status & I2C_LPC_RBF) + { + DEBPROTO(lpc_fprintf_debug("%s : Bus is full status : %x\n",__func__,status);) + break; + } + + status = get_lpc(adap, I2C_LPC_REG_TEST); + + DEBPROTO(lpc_fprintf_debug("%s : The test register data : %x\n",__func__,status);) + udelay(1); /* wait for 100 us */ + } + + if (timeout == 0) { + DEBPROTO(lpc_fprintf_debug("%s : Timeout waiting for Bus Full\n",__func__);) + return -ETIMEDOUT; + } + + return 0; +} + +static int wait_for_td(struct i2c_algo_lpc_data *adap) +{ + + int timeout = DEF_TIMEOUT; + int status=0; + + while (--timeout) { + udelay(4); + status = get_lpc(adap, I2C_LPC_REG_STATUS); + + DEBPROTO(lpc_fprintf_debug("%s : Waiting for bus done status : %x\n",__func__,status);) + + if(status == I2C_LPC_TD) + { + DEBPROTO(lpc_fprintf_debug("%s : Bus is done status : %x\n",__func__,status);) + break; + } + } + + if (timeout == 0) { + DEBPROTO(lpc_fprintf_debug("%s : Timeout waiting for Bus Done\n",__func__);) + return -ETIMEDOUT; + } + + return 0; +} + + + +static int wait_for_pin(struct i2c_algo_lpc_data *adap, int *status) +{ + int timeout = DEF_TIMEOUT; + *status = get_lpc(adap, I2C_LPC_REG_STATUS); + + while ((*status & I2C_LPC_TBE) && --timeout) { + *status = get_lpc(adap, I2C_LPC_REG_STATUS); + } + + if (timeout == 0) + return -ETIMEDOUT; + + + return 0; +} + + +static int lpc_doAddress(struct i2c_algo_lpc_data *adap,struct i2c_msg *msg) +{ + unsigned short flags = msg->flags; + unsigned char addr; + + addr = msg->addr << 1; + if (flags & I2C_M_RD) + { + addr |= 1; + DEBPROTO(lpc_fprintf_debug("step 7 : read mode then write device address 0x%x\n",addr);) + } + else + { + DEBPROTO(lpc_fprintf_debug("step 2 : write mode then write device address 0x%x\n",addr);) + } + + if (flags & I2C_M_REV_DIR_ADDR) + { + addr ^= 1; + + } + i2c_outaddr(adap, addr); + return 0; + +} + + +static int lpc_sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) +{ + struct i2c_algo_lpc_data *adap = i2c_adap->algo_data; + int i = 0,timeout=0; + + unsigned int count = msg->len; + unsigned char *buf = msg->buf; + + do{ + lpc_doAddress(adap,msg); + set_lpc(adap, I2C_LPC_REG_BYTE_COUNT, (count-i) >= 4 ? 4:(count - i)); + DEBPROTO(lpc_fprintf_debug("step 3 : write register count %x\n",count);) + + if((count -i) >= 4) + { + i2c_outbyte1(adap, buf[i+0] & 0xff); + i2c_outbyte2(adap, buf[i+1] & 0xff); + i2c_outbyte3(adap, buf[i+2] & 0xff); + i2c_outbyte4(adap, buf[i+3] & 0xff); + + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+0,buf[i+0]);) + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+1,buf[i+1]);) + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+2,buf[i+2]);) + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+3,buf[i+3]);) + i += 4; + } + else if((count -i) == 3) + { + i2c_outbyte1(adap, buf[i+0] & 0xff); + i2c_outbyte2(adap, buf[i+1] & 0xff); + i2c_outbyte3(adap, buf[i+2] & 0xff); + + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+0,buf[i+0]);) + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+1,buf[i+1]);) + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+2,buf[i+2]);) + + i += 3; + } + else if((count -i) == 2) + { + i2c_outbyte1(adap, buf[i+0] & 0xff); + i2c_outbyte2(adap, buf[i+1] & 0xff); + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+0,buf[i+0]);) + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+1,buf[i+1]);) + i += 2; + } + else if((count -i) == 1) + { + i2c_outbyte1(adap, buf[i+0] & 0xff); + DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+0,buf[i+0]);) + i += 1; + } + + /* Send START */ + DEBPROTO(lpc_fprintf_debug("step 5-1 : Delay 6mS \n");) + udelay(6000); + DEBPROTO(lpc_fprintf_debug("step 5-2 : Start to transfrom \n");) + i2c_stop(adap); + i2c_start(adap); + DEBPROTO(lpc_fprintf_debug("step 5-3 : Start done\n");) + + udelay(400); + DEBPROTO(lpc_fprintf_debug("step 6 : Waiting for BE\n");) + timeout = wait_for_td(adap); + if (timeout) { + DEBPROTO(lpc_fprintf_debug("step 6 : Timeout waiting for BE \n");) + return -EREMOTEIO; + } + }while (i < count); + + if(i == count) + { + DEBPROTO(lpc_fprintf_debug("Writen %d bytes successd !\n",count);) + return i; + } + else + { + DEBPROTO(lpc_fprintf_debug("Writen %d bytes failed \n",count);) + return -EIO; + } +} + +static int lpc_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) +{ + int i=0,timeout=0; + struct i2c_algo_lpc_data *adap = i2c_adap->algo_data; + + unsigned int count = msg->len; + unsigned char *buf = msg->buf; + + do{ + lpc_doAddress(adap,msg); + set_lpc(adap, I2C_LPC_REG_BYTE_COUNT, (count-i) >= 4 ? 4:(count - i)); + DEBPROTO(lpc_fprintf_debug("step 8 : write register count %d\n",count);) + + /* Send START */ + DEBPROTO(lpc_fprintf_debug("step 9-1 : Delay 6mS\n");) + udelay(6000); + DEBPROTO(lpc_fprintf_debug("step 9-2 : Start to receive data\n");) + i2c_stop(adap); + i2c_start(adap); + DEBPROTO(lpc_fprintf_debug("step 9-3 : Start done\n");) + + udelay(400); + DEBPROTO(lpc_fprintf_debug("step 10 : Waiting for TD\n");) + timeout = wait_for_td(adap); + if (timeout) { + DEBPROTO(lpc_fprintf_debug("step 10 : Timeout waiting for TD \n");) + return -EREMOTEIO; + } + + if((count -i) >= 4) + { + buf[i+0] = 0xff & i2c_inbyte1(adap); + buf[i+1] = 0xff & i2c_inbyte2(adap); + buf[i+2] = 0xff & i2c_inbyte3(adap); + buf[i+3] = 0xff & i2c_inbyte4(adap); + + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+0,buf[i+0]);) + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+1,buf[i+1]);) + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+2,buf[i+2]);) + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+3,buf[i+3]);) + + i += 4; + } + else if((count -i) == 3) + { + buf[i+0] = 0xff & i2c_inbyte1(adap); + buf[i+1] = 0xff & i2c_inbyte2(adap); + buf[i+2] = 0xff & i2c_inbyte3(adap); + + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+0,buf[i+0]);) + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+1,buf[i+1]);) + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+2,buf[i+2]);) + + i += 3; + } + else if((count -i) == 2) + { + buf[i+0] = 0xff & i2c_inbyte1(adap); + buf[i+1] = 0xff & i2c_inbyte2(adap); + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+0,buf[i+0]);) + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+1,buf[i+1]);) + i += 2; + } + else if((count -i) == 1) + { + buf[i+0] = 0xff & i2c_inbyte1(adap); + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+0,buf[i+0]);) + i += 1; + } + + + }while(i < count); + + if(i == count) + { + DEBPROTO(lpc_fprintf_debug("Read %d bytes successd !\n",count);) + return i; + } + else + { + DEBPROTO(lpc_fprintf_debug("Read %d bytes failed \n",count);) + return -EIO; + } +} + + +struct cpld_client_node { + struct i2c_client *client; + struct list_head list; +}; +#define LPC_I2C_MAX_NCHANS 6 + + +struct lpc_iic { + struct i2c_adapter *virt_adaps[LPC_I2C_MAX_NCHANS]; + u8 last_chan; /* last register value */ +}; + + +static int lpc_master_xfer(struct i2c_adapter *i2c_adap, + struct i2c_msg *msgs, + int num) +{ + struct i2c_algo_lpc_data *adap = i2c_adap->algo_data; + struct i2c_msg *pmsg; + int i; + int ret=0; + + mutex_lock(&lpc_lock); + + if (adap->xfer_begin) + adap->xfer_begin(&i2c_adap->nr); + + + for (i = 0;ret >= 0 && i < num; i++) { + pmsg = &msgs[i]; + + DEBPROTO(lpc_fprintf_debug("lpc_xfer.o: Doing %s %d bytes to 0x%02x - %d of %d messages\n", + pmsg->flags & I2C_M_RD ? "read" : "write", + pmsg->len, pmsg->addr, i + 1, num);) + + DEBPROTO(lpc_fprintf_debug("lpc_xfer.o: Msg %d, addr=0x%x, flags=0x%x, len=%d\n", + i, msgs[i].addr, msgs[i].flags, msgs[i].len);) + + if (pmsg->flags & I2C_M_RD) { + ret = lpc_readbytes(i2c_adap, pmsg); + + if (ret != pmsg->len) { + DEBPROTO(lpc_fprintf_debug("lpc_xfer.o: fail: " + "only read %d bytes.\n",ret)); + } else { + DEBPROTO(lpc_fprintf_debug("lpc_xfer.o: read %d bytes.\n",ret)); + } + } else { + + ret = lpc_sendbytes(i2c_adap, pmsg); + + if (ret != pmsg->len) { + DEBPROTO(lpc_fprintf_debug("lpc_xfer.o: fail: " + "only wrote %d bytes.\n",ret)); + } else { + DEBPROTO(lpc_fprintf_debug("lpc_xfer.o: wrote %d bytes.\n",ret)); + } + } + } + + if (adap->xfer_end) + adap->xfer_end(&i2c_adap->nr); + + mutex_unlock(&lpc_lock); + + DEBPROTO(lpc_fprintf_debug("ret = 0x%x num = 0x%x i = 0x%x.\n",ret,num,i)); + + return ret = (ret < 0) ? ret : num; +} + + +static u32 lpc_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SMBUS_QUICK; +} + +/* exported algorithm data: */ +static const struct i2c_algorithm lpc_algo = { + .master_xfer = lpc_master_xfer, + //.smbus_xfer = lpc_smbus_xfer, + .functionality = lpc_func, +}; + + +/********************************************** End ********************************************************/ + + + + + + +/********************************************** Start ********************************************************/ +#define DEFAULT_BASE 0x0a00 + +static int lpc_base= 0x0a00; +static u8 __iomem *lpc_base_iomem; + +static int lpc_irq; +static int lpc_clock = 0x1c; +static int lpc_own = 0x55; +static int lpc_mmapped; + +static unsigned long lpc_base_addr = 0x0a00; +static unsigned int lpc_io_space_size = 2; + +static unsigned long LPC_INDEX_REG; +static unsigned long LPC_DATA_REG; + + +/* notice : removed static struct i2c_lpc_iic gpi; code - + this module in real supports only one device, due to missing arguments + in some functions, called from the algo-lpc module. Sometimes it's + need to be rewriten - but for now just remove this for simpler reading */ + +static wait_queue_head_t lpc_wait; +static int lpc_pending; +static spinlock_t lock; +static spinlock_t lpc_slock; + +static struct i2c_adapter lpc_iic_ops; + +struct cpld_dev_type { + struct resource *io_resource; + struct semaphore sem; + struct cdev cdev; +}; + +struct cpld_dev_type *cpld_device; + + +/* ----- local functions ---------------------------------------------- */ + +static void lpc_cpld_setbyte(void *data, int ctl, int val) +{ + outb(ctl, LPC_INDEX_REG); + mb(); + + outb(val, LPC_DATA_REG); + mb(); +} + +static int lpc_cpld_getbyte(void *data, int ctl) +{ + u8 val = 0; + + outb(ctl, LPC_INDEX_REG); + mb(); + + val = inb(LPC_DATA_REG); + mb(); + + return val; +} + +static void lpc_iic_setbyte(void *data, int ctl, int val) +{ + if (!cpld_device) + { + return ; + } + + if (down_interruptible(&cpld_device->sem)) + { + return ; + } + + + lpc_cpld_setbyte(data,ctl,val); + + up(&cpld_device->sem); + DEBPROTO(lpc_fprintf_debug("%s REG[%x] = %x\n",__func__,ctl,val);) +} + + +static int lpc_iic_getbyte(void *data, int ctl) +{ + u8 val = 0; + if (!cpld_device) + return -ENOTTY; + + if (down_interruptible(&cpld_device->sem)) + return -ERESTARTSYS; + + val = lpc_cpld_getbyte(data,ctl); + + up(&cpld_device->sem); + DEBPROTO(lpc_fprintf_debug("%s REG[%x] = %x\n",__func__,ctl,val);) + return val; +} + +int cig_cpld_read_register(u8 reg_off, u8 *val) +{ + if (!cpld_device) + return -ENOTTY; + + if (down_interruptible(&cpld_device->sem)) + return -ERESTARTSYS; + + *val = lpc_cpld_getbyte(cpld_device, reg_off); + + up(&cpld_device->sem); + + return 0; +} +EXPORT_SYMBOL(cig_cpld_read_register); + +int cig_cpld_write_register(u8 reg_off, u8 val) +{ + if (!cpld_device) + return -ENOTTY; + + if (down_interruptible(&cpld_device->sem)) + return -ERESTARTSYS; + + lpc_cpld_setbyte(cpld_device, reg_off, val); + up(&cpld_device->sem); + return 0; +} +EXPORT_SYMBOL(cig_cpld_write_register); + + + +static int lpc_iic_getown(void *data) +{ + return (lpc_own); +} + + +static int lpc_iic_getclock(void *data) +{ + return (lpc_clock); +} + +static void lpc_iic_waitforpin(void *data) +{ + DEFINE_WAIT(wait); + int timeout = 2; + unsigned long flags; + + if (lpc_irq > 0) { + spin_lock_irqsave(&lock, flags); + if (lpc_pending == 0) { + spin_unlock_irqrestore(&lock, flags); + prepare_to_wait(&lpc_wait, &wait, TASK_INTERRUPTIBLE); + if (schedule_timeout(timeout*HZ)) { + spin_lock_irqsave(&lock, flags); + if (lpc_pending == 1) { + lpc_pending = 0; + } + spin_unlock_irqrestore(&lock, flags); + } + finish_wait(&lpc_wait, &wait); + } else { + lpc_pending = 0; + spin_unlock_irqrestore(&lock, flags); + } + } else { + udelay(100); + } +} + + +static irqreturn_t lpc_iic_handler(int this_irq, void *dev_id) { + spin_lock(&lock); + lpc_pending = 1; + spin_unlock(&lock); + wake_up_interruptible(&lpc_wait); + return IRQ_HANDLED; +} + +static int board_id = 0; + + +static int lpc_iic_select(void *data) +{ + unsigned int chan_id=0; + chan_id = *(unsigned int *)data; + chan_id -= 2; + DEBPROTO(lpc_fprintf_debug("step 1 : selest channel id = %d\n",chan_id);) + lpc_iic_setbyte(data,I2C_LPC_REG_BUS_SEL,chan_id); + + return 0; +} + +static int lpc_iic_deselect(void *data) +{ + + unsigned int chan_id=0; + chan_id = *(unsigned int *)data; + chan_id -= 2; + DEBPROTO(lpc_fprintf_debug("step last :deselect channel id = %d\n",chan_id);) + + return 0; +} + + +/* ------------------------------------------------------------------------ + * Encapsulate the above functions in the correct operations structure. + * This is only done when more than one hardware adapter is supported. + */ +static struct i2c_algo_lpc_data lpc_iic_data = { + .setlpc = lpc_iic_setbyte, + .getlpc = lpc_iic_getbyte, + .getown = lpc_iic_getown, + .getclock = lpc_iic_getclock, + .waitforpin = lpc_iic_waitforpin, + .xfer_begin = lpc_iic_select, + .xfer_end = lpc_iic_deselect, +}; + +#include + +static struct i2c_adapter lpc_iic_arr_ops[LPC_I2C_MAX_NCHANS] = {0}; + +static void dummy_setscl(void *data, int state) +{ + return; +} + +static void dummy_setsda(void *data, int state) +{ + return; + +} + +static int dummy_getscl(void *data) +{ + return 1; + +} + +static int dummy_getsda(void *data) +{ + return 1; +} + + +static struct i2c_algo_bit_data dummy_algo_data = { + .setsda = dummy_setsda, + .setscl = dummy_setscl, + .getsda = dummy_getsda, + .getscl = dummy_getscl, + .udelay = 50, + .timeout = HZ, +}; + + +static int dummy_xfer(struct i2c_adapter *i2c_adap, + struct i2c_msg *msgs, + int num) +{ + return 1; +} + +static u32 dummy_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SMBUS_QUICK; +} + + +static const struct i2c_algorithm dummy_algo = { + .master_xfer = dummy_xfer, + .functionality = dummy_func, +}; + + + +static struct i2c_adapter i2c_dummy = { + .owner = THIS_MODULE, + .class = I2C_CLASS_HWMON, + .algo_data = &dummy_algo_data, + .algo = &dummy_algo, + .name = "i2c_dummy", +}; + + +static int lpc_iic_match(struct device *dev, unsigned int id) +{ + /* sanity checks for lpc_mmapped I/O */ + + DEB2(printk("lpc_iic_match\n");) + + + if (lpc_base < DEFAULT_BASE) { + dev_err(dev, "incorrect lpc_base address (%#x) specified " + "for lpc_mmapped I/O\n", lpc_base); + return 0; + } + + if (lpc_base == 0) { + lpc_base = DEFAULT_BASE; + } + return 1; +} + +static int lpc_iic_probe(struct device *dev, unsigned int id) +{ + int rval,num; + + lpc_fprintf_init(); + + DEB2(printk("lpc_iic_probe\n");) + + mutex_init(&lpc_lock); + + for(num = 0; num < LPC_I2C_MAX_NCHANS;num++) + { + lpc_iic_arr_ops[num].dev.parent = dev; + lpc_iic_arr_ops[num].owner = THIS_MODULE; + lpc_iic_arr_ops[num].class = I2C_CLASS_HWMON | I2C_CLASS_SPD; + lpc_iic_arr_ops[num].algo = &lpc_algo; + lpc_iic_arr_ops[num].algo_data = &lpc_iic_data, + lpc_iic_arr_ops[num].nr=num; + snprintf(lpc_iic_arr_ops[num].name, sizeof(lpc_iic_arr_ops[num].name), "i2c-%d-lpc", i2c_adapter_id(&lpc_iic_arr_ops[num])); + rval |= i2c_add_adapter(&lpc_iic_arr_ops[num]); + DEB2(printk("%s\n",lpc_iic_arr_ops[num].name);) + } + + return 0; +} + +static int lpc_iic_remove(struct device *dev, unsigned int id) +{ + int num; + DEB2(printk("lpc_iic_remove\n")); + + lpc_fprintf_exit(); + for(num = LPC_I2C_MAX_NCHANS - 1; num >= 0 ;num--) + i2c_del_adapter(&lpc_iic_arr_ops[num]); + + + return 0; +} + +static struct isa_driver i2c_lpc_driver = { + .match = lpc_iic_match, + .probe = lpc_iic_probe, + .remove = lpc_iic_remove, + .driver = { + .owner = THIS_MODULE, + .name = "lpc-iic", + }, +}; + +/********************************************** End ********************************************************/ + + + + + + +/********************************************** Start ********************************************************/ + +static int cpld_major = 0; +static int cpld_minor = 0; + +struct cpld_rw_msg { + unsigned char addr; + unsigned char data; +}; + + +static struct cpld_rw_msg param_read = {-1}; +static struct cpld_rw_msg param_write = {-1}; +static struct cpld_rw_msg param_reads = {-1}; +static struct cpld_rw_msg param_writes = {-1}; + +void cpld_sysfs_kobj_release(struct kobject *kobj) +{ + return; +} + +int cpld_sysfs_add_attr(struct kobject* kobj, char* attr_name) +{ + + struct attribute *attr; + + attr = kmalloc(sizeof(struct attribute), GFP_KERNEL); + attr->name = attr_name; + attr->mode = 0644; + + return sysfs_create_file(kobj, attr); +} + +static int cig_cpld_write_slave_cpld_register(u8 reg_addr, u8 reg_data); +static int cig_cpld_read_slave_cpld_register(u8 reg_addr, u8 *reg_data); + + +static ssize_t cpld_sysfs_show(struct kobject *kobj, struct attribute *attr, char *buffer) +{ + u8 val=0,ret=0,year=0,month=0,day=0,cpld_m=0,cpld_1=0,cpld_2=0; + + if (0 == strcmp(attr->name, "read")) + { + val = lpc_iic_getbyte(NULL,param_read.addr); + ret = sprintf(buffer,"read : addr = 0x%x val = 0x%x\n",param_read.addr, val); + + } + else if (0 == strcmp(attr->name, "write")) + { + lpc_iic_setbyte(NULL, param_write.addr,param_write.data); + ret = sprintf(buffer,"write : addr = 0x%x val = 0x%x\n",param_write.addr, param_write.data); + } + else if (0 == strcmp(attr->name, "version")) + { + cpld_m = lpc_iic_getbyte(NULL, 0x02); + year = lpc_iic_getbyte(NULL, 0x03); + month = lpc_iic_getbyte(NULL, 0x04); + day = lpc_iic_getbyte(NULL, 0x05); + + cig_cpld_read_slave_cpld_register(0x1d,&cpld_1); + cig_cpld_read_slave_cpld_register(0x1e,&cpld_2); + + ret = sprintf(buffer,"Main CPLD version : V%02x\n"\ + "Main CPLD date : 20%02x-%02x-%02x\n"\ + "Slave 1 CPLD version : V%02x\n"\ + "Slave 2 CPLD version : V%02x\n",cpld_m,year,month,day,cpld_1,cpld_2); + } + if (0 == strcmp(attr->name, "reads")) + { + ret = cig_cpld_read_slave_cpld_register(param_reads.addr,&val); + if (ret < 0) + printk("ERROR:Failed to read slave cpld.\n"); + ret = sprintf(buffer,"reads : addr = 0x%x val = 0x%x\n",param_reads.addr, val); + + } + else if (0 == strcmp(attr->name, "writes")) + { + ret = cig_cpld_write_slave_cpld_register(param_writes.addr,param_writes.data); + if (ret < 0) + printk("ERROR:Failed to read slave cpld.\n"); + ret = sprintf(buffer,"writes : addr = 0x%x val = 0x%x\n",param_writes.addr, param_writes.data); + } + + + return ret; + +} + +static ssize_t cpld_sysfs_store(struct kobject *kobj, struct attribute *attr, const char *buffer, size_t count) +{ + int param[3]; + + if (0 == strcmp(attr->name, "read")) + { + sscanf(buffer, "0x%02x", ¶m[0]); + param_read.addr = param[0]; + } + else if (0 == strcmp(attr->name, "write")) + { + sscanf(buffer, "0x%2x 0x%02x", ¶m[0], ¶m[1]); + param_write.addr = param[0]; + param_write.data = param[1]; + } + if (0 == strcmp(attr->name, "reads")) + { + sscanf(buffer, "0x%02x", ¶m[0]); + param_reads.addr = param[0]; + } + else if (0 == strcmp(attr->name, "writes")) + { + sscanf(buffer, "0x%2x 0x%02x", ¶m[0], ¶m[1]); + param_writes.addr = param[0]; + param_writes.data = param[1]; + } + return count; +} + + + +static struct sysfs_ops cpld_sysfs_ops = +{ + .show = cpld_sysfs_show, + .store = cpld_sysfs_store, +}; + +static struct kobj_type cpld_kobj_type = +{ + .release = cpld_sysfs_kobj_release, + .sysfs_ops = &cpld_sysfs_ops, + .default_attrs = NULL, +}; + + +static const char driver_name[] = "cpld_drv"; +static atomic_t cpld_available = ATOMIC_INIT(1); +static struct class *cpld_class; +static struct device *cpld_dev; + + + +#define CPLD_IOC_MAGIC '[' + +#define CPLD_IOC_RDREG _IOR(CPLD_IOC_MAGIC, 0, struct cpld_rw_msg) +#define CPLD_IOC_WRREG _IOW(CPLD_IOC_MAGIC, 1, struct cpld_rw_msg) + +#define CPLD_IOC_MAXNR 2 + + +int cpld_open(struct inode *inode, struct file *filp) +{ + struct cpld_dev_type *dev; + + if (! atomic_dec_and_test(&cpld_available)) { + atomic_inc(&cpld_available); + return -EBUSY; + } + + dev = container_of(inode->i_cdev, struct cpld_dev_type, cdev); + filp->private_data = dev; + + return 0; +} + +int cpld_release(struct inode *inode, struct file *flip) +{ + atomic_inc(&cpld_available); + return 0; +} + + +long cpld_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + int rc = 0; + int err = 0; + struct cpld_dev_type *dev = (struct cpld_dev_type *)filp->private_data; + struct cpld_rw_msg msg; + + if (_IOC_TYPE(cmd) != CPLD_IOC_MAGIC) + return -ENOTTY; + if (_IOC_NR(cmd) > CPLD_IOC_MAXNR) + return -ENOTTY; + + if (_IOC_DIR(cmd) & _IOC_READ) + err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd)); + if (_IOC_DIR(cmd) & _IOC_WRITE) + err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd)); + if (err) + return -EFAULT; + + if (down_interruptible(&dev->sem)) + return -ERESTARTSYS; + + switch(cmd){ + case CPLD_IOC_RDREG: + rc = copy_from_user(&msg, (void __user *)arg, sizeof(msg)); + if (!rc) { + msg.data = lpc_cpld_getbyte(dev, msg.addr); + rc = copy_to_user((void __user *)arg, &msg, sizeof(msg)); + } + break; + + case CPLD_IOC_WRREG: + rc = copy_from_user(&msg, (void __user *)arg, sizeof(msg)); + if (!rc) { + lpc_cpld_setbyte(dev, msg.addr, msg.data); + } + break; + default: + rc = -ENOTTY; + break; + } + up(&dev->sem); + + return rc; +} + +struct file_operations cpld_fops = { + .owner = THIS_MODULE, + .open = cpld_open, + .unlocked_ioctl = cpld_ioctl, + .release = cpld_release, +}; + + +static void cpld_setup_cdev(struct cpld_dev_type *dev) +{ + int err, devno = MKDEV(cpld_major, cpld_minor); + + cdev_init(&dev->cdev, &cpld_fops); + dev->cdev.owner = THIS_MODULE; + dev->cdev.ops = &cpld_fops; + err = cdev_add(&dev->cdev, devno, 1); + + if (err) + DEB2(printk(KERN_NOTICE "Error %d adding cpld", err);) +} +/********************************************** End ********************************************************/ + + + + +/********************************************** Start ********************************************************/ +#include +#include +#include + +static spinlock_t irq_inter_lock; +static struct delayed_work irq_inter_work; +static unsigned long irq_inter_delay; + + +static int cig_cpld_write_slave_cpld_register(u8 reg_addr, u8 reg_data) +{ + u8 read_status = 0; + u8 wait_time_out = WAIT_TIME_OUT_COUNT; + DEB2(printk("<=======write=========>")); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_ADDR, reg_addr << 1); + DEB2(printk("[62]=%x\n",reg_addr << 1)); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_TX, reg_data); + DEB2(printk("[63]=%x\n",reg_data)); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_COMMAND, 0x80); + DEB2(printk("[65]=%x\n",0x80)); + do{ + cig_cpld_read_register(ADDR_REG_SFP_STATUS_STATUS, &read_status); + DEB2(printk("[66]=%x\n",read_status)); + udelay(60); + wait_time_out--; + if(wait_time_out == 0) + break; + }while(read_status != 0x02); + DEB2(printk("<=======write=========>")); + + + if(wait_time_out == 0) + return -1; + + return 1; +} + + +static int cig_cpld_read_slave_cpld_register(u8 reg_addr, u8 *reg_data) +{ + u8 read_status = 0; + u8 wait_time_out = WAIT_TIME_OUT_COUNT; + DEB2(printk("<========read=========>")); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_ADDR, reg_addr << 1 | 1); + DEB2(printk("[62]=%x\n",reg_addr << 1 | 1)); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_COMMAND, 0x80); + DEB2(printk("[65]=%x\n",0x80)); + do{ + udelay(60); + cig_cpld_read_register(ADDR_REG_SFP_STATUS_STATUS, &read_status); + DEB2(printk("[66]=%x\n",read_status)); + wait_time_out--; + if(wait_time_out == 0) + break; + }while(read_status != 0x01); + + cig_cpld_read_register(ADDR_REG_SFP_STATUS_RX,reg_data); + DEB2(printk("[64]=%x\n",*reg_data)); + DEB2(printk("<========read=========>")); + + if(wait_time_out == 0) + return -1; + + return 1; +} + + + +struct sock *nlsk = NULL; +extern struct net init_net; +#define NETLINK_TEST 26 +#define MSG_LEN 125 +#define USER_PORT 100 +static u32 irq_present_status_low_current,irq_present_status_low_next; +static u32 irq_present_status_high_current,irq_present_status_high_next; +static u32 irq_tx_fault_status_low_current,irq_tx_fault_status_low_next; +static u32 irq_tx_fault_status_high_current,irq_tx_fault_status_high_next; +static u32 irq_rx_lost_status_low_current,irq_rx_lost_status_low_next; +static u32 irq_rx_lost_status_high_current,irq_rx_lost_status_high_next; + +static u8 irq_present_qsfp_current,irq_present_qsfp_next; +static u8 irq_interrupt_qsfp_current,irq_interrupt_qsfp_next; + +struct input_dev *cpld_input_dev; + + + +int send_usrmsg(char *pbuf, uint16_t len) +{ + struct sk_buff *nl_skb; + struct nlmsghdr *nlh; + + int ret; + + + nl_skb = nlmsg_new(len, GFP_ATOMIC); + if(!nl_skb) + { + printk("netlink alloc failure\n"); + return -1; + } + + + nlh = nlmsg_put(nl_skb, 0, 0, NETLINK_TEST, len, 0); + if(nlh == NULL) + { + printk("nlmsg_put failaure \n"); + nlmsg_free(nl_skb); + return -1; + } + + memcpy(nlmsg_data(nlh), pbuf, len); + ret = netlink_unicast(nlsk, nl_skb, USER_PORT, MSG_DONTWAIT); + + return ret; +} + +static void netlink_rcv_msg(struct sk_buff *skb) +{ + + struct nlmsghdr *nlh = NULL; + char *umsg = NULL; + char kmsg[1024] = {0}; + char kmsg_tmp[16] = {0}; + u8 i = 0; + u8 tmp[3]={0}; + + if(skb->len >= nlmsg_total_size(0)) + { + nlh = nlmsg_hdr(skb); + umsg = NLMSG_DATA(nlh); + if(umsg) + { + for(i = 0;i < 24;i++) + { + if(!(irq_present_status_low_current & (0x1 << i))) + { + tmp[0] = 1; + } + else + { + tmp[0] = 0; + } + + if(!(irq_rx_lost_status_low_current & (0x1 << i))) + { + tmp[1] = 1; + } + else + { + tmp[1] = 0; + } + + if(!(irq_tx_fault_status_low_current & (0x1 << i))) + { + tmp[2] = 1; + } + else + { + tmp[2] = 0; + } + memset(kmsg_tmp,0xff,sizeof(kmsg_tmp)); + sprintf(kmsg_tmp,"sfp%02d:%1d:%1d:%1d ",i+1,tmp[0],tmp[1],tmp[2]); + strcat(kmsg,kmsg_tmp); + } + + for(i = 0;i < 24;i++) + { + if(!(irq_present_status_high_current & (0x1 << i))) + { + tmp[0] = 1; + } + else + { + tmp[0] = 0; + } + + if(!(irq_rx_lost_status_high_current & (0x1 << i))) + { + tmp[1] = 1; + } + else + { + tmp[1] = 0; + } + + if(!(irq_tx_fault_status_high_current & (0x1 << i))) + { + tmp[2] = 1; + } + else + { + tmp[2] = 0; + } + memset(kmsg_tmp,0xff,sizeof(kmsg_tmp)); + sprintf(kmsg_tmp,"sfp%02d:%1d:%1d:%1d ",i+25,tmp[0],tmp[1],tmp[2]); + strcat(kmsg,kmsg_tmp); + } + + + for(i = 0;i < 8;i++) + { + if(!(irq_present_qsfp_current & (0x1 << i))) + { + tmp[0] = 1; + } + else + { + tmp[0] = 0; + } + + if(!(irq_interrupt_qsfp_current & (0x1 << i))) + { + tmp[1] = 1; + } + else + { + tmp[1] = 0; + } + + memset(kmsg_tmp,0xff,sizeof(kmsg_tmp)); + sprintf(kmsg_tmp,"qsfp%02d:%1d:%1d:%1d ",i+49,tmp[0],tmp[1],0); + strcat(kmsg,kmsg_tmp); + } + + printk("kernel recv from user: %s\n", umsg); + send_usrmsg(kmsg, strlen(kmsg)); + } + } + + return ; +} + + + +struct netlink_kernel_cfg cfg = { + .input = netlink_rcv_msg, /* set recv callback */ +}; + + + +#define RANGE_OF_BYTE_SHIFT(to_arg,shift,from_arg) {to_arg &= ~(0xff << shift); to_arg |= from_arg << shift;} + + +static void irq_inter_wapper(struct work_struct * work) +{ + + u8 m_data = 0; + u8 data_high8 = 0,data_low8 = 0; + u16 data_16 = 0; + u8 status = 0; + u8 i = 0; + char kmsg[64]={0}; + u8 tmp[3] = {0}; + + DEB2(printk("CPLD_MASTER_INTERRUPT\r\n")); + + m_data = lpc_iic_getbyte(NULL,CPLD_MASTER_INTERRUPT_STATUS_REG); + lpc_iic_setbyte(NULL,CPLD_MASTER_INTERRUPT_STATUS_REG,0xff); + + cig_cpld_write_slave_cpld_register(CPLD_SLAVE1_INTERRUPT_MASK_REG,0xff); + cig_cpld_write_slave_cpld_register(CPLD_SLAVE2_INTERRUPT_MASK_REG,0xff); + if(!(m_data & CPLD_MASTER_INTERRUPT_CPLD1)) + { + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_INTERRUPT_STATUS_H_REG,&data_high8); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_INTERRUPT_STATUS_L_REG,&data_low8); + data_16 = data_low8 | data_high8 << 8; + if( + !(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT08) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT16) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT24) + ) + { + if(!(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT08)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT08\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_PRESENT08_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_low_current,0,status); + + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT16)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT16\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_PRESENT16_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_low_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT24)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT24\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_PRESENT24_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_low_current,16,status); + } + DEB2(printk("irq_present_status_low_next = %08x irq_present_status_low_current = %08x \n",irq_present_status_low_next,irq_present_status_low_current)); + } + + if( + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST08) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST16) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST24) + ) + { + if(!(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST08)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_RX_LOST08\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_RX_LOST08_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_low_current,0,status); + + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST16)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT16\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_RX_LOST16_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_low_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST24)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT24\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_RX_LOST24_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_low_current,16,status); + } + DEB2(printk("irq_rx_lost_status_low_next = %08x irq_rx_lost_status_low_current = %08x \n",irq_rx_lost_status_low_next,irq_rx_lost_status_low_current)); + } + + if( + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST08) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST16) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST24) + ) + { + if(!(data_16 & CPLD_SLAVE1_INTERRUPT_TX_FAULT08)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_TX_FAULT08\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_TX_FAULT08_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_low_current,0,status); + + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_TX_FAULT16)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_TX_FAULT16\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_TX_FAULT16_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_low_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_TX_FAULT24)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_TX_FAULT24\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_TX_FAULT24_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_low_current,16,status); + } + DEB2(printk("irq_tx_fault_status_low_next = %08x irq_tx_fault_status_low_current = %08x \n",irq_tx_fault_status_low_next,irq_tx_fault_status_low_current)); + + } + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_CPLD2)) + { + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_INTERRUPT_STATUS_H_REG,&data_high8); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_INTERRUPT_STATUS_L_REG,&data_low8); + data_16 = data_low8 | data_high8 << 8; + if( + !(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT32) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT40) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT48) + ) + { + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT32)) + { + DEB2(printk("CPLD_SLAVE2_PRESENT32_REG\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_PRESENT32_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_high_current,0,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT40)) + { + DEB2(printk("CPLD_SLAVE2_PRESENT40_REG\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_PRESENT40_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_high_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT48)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT48\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_PRESENT48_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_high_current,16,status); + } + } + + if( + !(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST32) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST40) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST48) + ) + { + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST32)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_RX_LOST32\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_RX_LOST32_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_high_current,0,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST40)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT40\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_RX_LOST40_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_high_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST48)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT48\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_RX_LOST48_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_high_current,16,status); + } + + } + + if( + !(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT32) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT40) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT48) + ) + { + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT32)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_RX_LOST32\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_TX_FAULT32_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_high_current,0,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT40)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT40\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_TX_FAULT40_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_high_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT48)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT48\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_TX_FAULT48_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_high_current,16,status); + } + } + + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT56)) + { + DEB2(printk("CPLD_SLAVE2_PRESENT56_REG\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_PRESENT56_REG,&status); + irq_present_qsfp_current = status; + } + + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_QSFP_CR56)) + { + DEB2(printk("CPLD_SLAVE2_QSFP_CR56_REG\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_QSFP_CR56_REG,&status); + irq_interrupt_qsfp_current = status; + } + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_LSW)) + { + DEB2(printk("CPLD_MASTER_INTERRUPT_LSW\r\n")); + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_PSU1)) + { + DEB2(printk("CPLD_MASTER_INTERRUPT_PSU1\r\n")); + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_PSU2)) + { + DEB2(printk("CPLD_MASTER_INTERRUPT_PSU2\r\n")); + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_6320)) + { + DEB2(printk("CPLD_MASTER_INTERRUPT_6320\r\n")); + } + cig_cpld_write_slave_cpld_register(CPLD_SLAVE1_INTERRUPT_MASK_REG,0x0); + cig_cpld_write_slave_cpld_register(CPLD_SLAVE2_INTERRUPT_MASK_REG,0x0); + + memset(tmp,0xff,sizeof(tmp)); + + for(i = 0;i < 24;i++) + { + if(!(irq_present_status_low_current & (0x1 << i)) && (irq_present_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d is present\r\n",i+1)); + tmp[0] = 1; + } + else if((irq_present_status_low_current & (0x1 << i)) && !(irq_present_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d is absent\r\n",i+1)); + tmp[0] = 0; + } + + if(!(irq_tx_fault_status_low_current & (0x1 << i)) && (irq_tx_fault_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d transmission is right\r\n",i+1)); + tmp[1] = 1; + } + else if((irq_tx_fault_status_low_current & (0x1 << i)) && !(irq_tx_fault_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d transmission is fault\r\n",i+1)); + tmp[1] = 0; + } + + if(!(irq_rx_lost_status_low_current & (0x1 << i)) && (irq_rx_lost_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d optical is meet\r\n",i+1)); + tmp[2] = 1; + } + else if((irq_rx_lost_status_low_current & (0x1 << i)) && !(irq_rx_lost_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d optical is lost\r\n",i+1)); + tmp[2] = 0; + } + + if((tmp[0] != 0xff) || (tmp[1] != 0xff) || (tmp[2] != 0xff)) + { + memset(kmsg,0xff,sizeof(kmsg)); + snprintf(kmsg,sizeof(kmsg),"sfp%02d:%1d:%1d:%1d ",i+1,(tmp[0] == 0xff) ? 0:tmp[0],(tmp[1] == 0xff) ? 0:tmp[1],(tmp[2] == 0xff) ? 0:tmp[2]); + break; + } + } + + memset(tmp,0xff,sizeof(tmp)); + for(i = 0;i < 24;i++) + { + if(!(irq_present_status_high_current & (0x1 << i)) && (irq_present_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d is present\r\n",i+25)); + tmp[0] = 1; + } + else if((irq_present_status_high_current & (0x1 << i)) && !(irq_present_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d is absent\r\n",i+25)); + tmp[0] = 0; + + } + + if(!(irq_rx_lost_status_high_current & (0x1 << i)) && (irq_rx_lost_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d optical is meet\r\n",i+25)); + tmp[1] = 1; + } + else if((irq_rx_lost_status_high_current & (0x1 << i)) && !(irq_rx_lost_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d optical is lost\r\n",i+25)); + tmp[1] = 0; + } + + if(!(irq_tx_fault_status_high_current & (0x1 << i)) && (irq_tx_fault_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d transmission is right\r\n",i+25)); + tmp[2] = 1; + } + else if((irq_tx_fault_status_high_current & (0x1 << i)) && !(irq_tx_fault_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d transmission is fault\r\n",i+25)); + tmp[2] = 0; + } + + if((tmp[0] != 0xff) || (tmp[1] != 0xff) || (tmp[2] != 0xff)) + { + memset(kmsg,0xff,sizeof(kmsg)); + snprintf(kmsg,sizeof(kmsg),"sfp%02d:%1d:%1d:%1d ",i+25,(tmp[0] == 0xff) ? 0:tmp[0],(tmp[1] == 0xff) ? 0:tmp[1],(tmp[2] == 0xff) ? 0:tmp[2]); + break; + } + } + + memset(tmp,0xff,sizeof(tmp)); + for(i = 0 ; i < 8; i++) + { + if(!(irq_present_qsfp_current & (0x1 << i)) && (irq_present_qsfp_next & (0x1 << i))) + { + DEB2(printk("SFP%d is present\r\n",i+49)); + tmp[0] = 1; + } + else if((irq_present_qsfp_current & (0x1 << i)) && !(irq_present_qsfp_next & (0x1 << i))) + { + DEB2(printk("SFP%d is absent\r\n",i+49)); + tmp[0] = 0; + } + + if(!(irq_interrupt_qsfp_current & (0x1 << i)) && (irq_interrupt_qsfp_next & (0x1 << i))) + { + DEB2(printk("SFP%d interrupt is occured \r\n",i+49)); + tmp[1] = 1; + } + else if((irq_interrupt_qsfp_current & (0x1 << i)) && !(irq_interrupt_qsfp_next & (0x1 << i))) + { + DEB2(printk("SFP%d interrupt is cleaned\r\n",i+49)); + tmp[1] = 0; + } + + if((tmp[0] != 0xff) || (tmp[1] != 0xff)) + { + memset(kmsg,0xff,sizeof(kmsg)); + snprintf(kmsg,sizeof(kmsg),"qsfp%02d:%1d:%1d:%1d ",i+49,(tmp[0] == 0xff) ? 0:tmp[0],(tmp[1] == 0xff) ? 0:tmp[1],0); + break; + } + } + + + irq_present_status_low_next = irq_present_status_low_current; + irq_rx_lost_status_low_next = irq_rx_lost_status_low_current; + irq_tx_fault_status_low_next = irq_tx_fault_status_low_current; + irq_present_status_high_next = irq_present_status_high_current; + irq_rx_lost_status_high_next = irq_rx_lost_status_high_current; + irq_tx_fault_status_high_next = irq_tx_fault_status_high_current; + irq_present_qsfp_next = irq_present_qsfp_current; + irq_interrupt_qsfp_next = irq_interrupt_qsfp_current; + + send_usrmsg(kmsg, strlen(kmsg)); +} + +static void disableIrq(unsigned short maskReg, unsigned short mask) +{ + u8 data = 0; + + data = lpc_iic_getbyte(NULL,maskReg); + data |= mask; + lpc_iic_setbyte(NULL,maskReg, data); +} + +static void enableIrq(unsigned short maskReg, unsigned short mask) +{ + unsigned short data; + + data = lpc_iic_getbyte(NULL,maskReg); + data &= ~mask; + lpc_iic_setbyte(NULL,maskReg, data); +} + + +static irqreturn_t irq_inter_isr(int irq, void *handle) +{ + + /* + * use keventd context to read the event fifo registers + * Schedule readout at least 25ms after notification for + * REVID < 4 + */ + + schedule_delayed_work(&irq_inter_work, irq_inter_delay); + + return IRQ_HANDLED; +} + + +#define CIG_CPLD_CHR_NAME "cpld" + + +static int __init cpld_init(void) +{ + int rval,rc=0; + dev_t dev; + u8 s_data; + + DEB2(printk("cpld_init\n");) + +/**************************************************************************************/ + + LPC_INDEX_REG = lpc_base_addr; + LPC_DATA_REG = lpc_base_addr + 1; + + cpld_device = kzalloc(sizeof(struct cpld_dev_type), GFP_KERNEL); + if (!cpld_device) + goto error3; + cpld_device->io_resource = request_region(lpc_base_addr, + lpc_io_space_size, "lpc-i2c"); + if (!cpld_device->io_resource) { + printk("lpc: claim I/O resource fail\n"); + goto error2; + } + sema_init(&cpld_device->sem, 1); + + if (cpld_major) { + dev = MKDEV(cpld_major, cpld_minor); + rc = register_chrdev_region(dev, 1, CIG_CPLD_CHR_NAME); + } else { + rc = alloc_chrdev_region(&dev, cpld_major, 1, CIG_CPLD_CHR_NAME); + cpld_major = MAJOR(dev); + } + + cpld_setup_cdev(cpld_device); + + cpld_class = class_create(THIS_MODULE,CIG_CPLD_CHR_NAME); + if (!cpld_class) { + DEB2(printk("failed to create class\n");) + goto error1; + } + + cpld_class->p->subsys.kobj.ktype= &cpld_kobj_type; + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "read"); + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "write"); + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "reads"); + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "writes"); + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "version"); + + cpld_dev = device_create(cpld_class, NULL, dev, NULL, CIG_CPLD_CHR_NAME); + +/**************************************************************************************/ + + rval = lpc_bus_init(); + rval = lpc_register_driver(&i2c_lpc_driver, 1); + +/**************************************************************************************/ + return 0; +error1: + cdev_del(&cpld_device->cdev); + unregister_chrdev_region(dev, 1); +error2: + release_resource(cpld_device->io_resource); +error3: + kfree(cpld_device); + + return rc; +} + +static void __exit cpld_exit(void) +{ + DEB2(printk("cpld_exit\n")); + + lpc_unregister_driver(&i2c_lpc_driver); + lpc_bus_exit(); + dev_t devno = MKDEV(cpld_major, cpld_minor); + + cdev_del(&cpld_device->cdev); + if (cpld_class) { + device_destroy(cpld_class, devno); + class_destroy(cpld_class); + } + + if (cpld_device) { + if (cpld_device->io_resource) + release_resource(cpld_device->io_resource); + + kfree(cpld_device); + } + unregister_chrdev_region(devno, 1); + + +} + +module_param(cpld_major, int, S_IRUGO); +module_param(cpld_minor, int, S_IRUGO); +module_param(i2c_debug, int, S_IRUGO); +module_param(board_id, int, S_IRUGO); + +module_init(cpld_init); +module_exit(cpld_exit); + +MODULE_AUTHOR("Zhang Peng "); +MODULE_DESCRIPTION("cs6436-54p-cpld driver"); +MODULE_LICENSE("GPL"); + + +/********************************************** End ********************************************************/ + + + diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-fan.c b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-fan.c new file mode 100644 index 000000000000..881cb7304b06 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-fan.c @@ -0,0 +1,521 @@ +/* + * A hwmon driver for the CIG cs6436-54p fan + * + * Copyright (C) 2018 Cambridge, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 + + + +#define FAN_SPEED_DUTY_TO_CPLD_STEP 10 + +static struct cs6436_54p_fan_data *cs6436_54p_fan_update_device(struct device *dev); +static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); +static ssize_t set_fan_direction(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); + + +extern int cig_cpld_write_register(u8 reg_off, u8 val); +extern int cig_cpld_read_register(u8 reg_off, u8 *val); + +/* fan related data, the index should match sysfs_fan_attributes + */ +static const u8 fan_reg[] = { + 0x41, /* fan enable/disable */ + 0x40, /* fan PWM(for all fan) */ + 0x42, /* front fan 1 speed(rpm) */ + 0x44, /* front fan 2 speed(rpm) */ + 0x46, /* front fan 3 speed(rpm) */ + 0x48, /* front fan 4 speed(rpm) */ + 0x4a, /* front fan 5 speed(rpm) */ + 0x43, /* rear fan 1 speed(rpm) */ + 0x45, /* rear fan 2 speed(rpm) */ + 0x47, /* rear fan 3 speed(rpm) */ + 0x49, /* rear fan 4 speed(rpm) */ + 0x4b, /* rear fan 5 speed(rpm) */ + 0x4c, /* fan direction rear to front or front to rear */ +}; + + +/* Each client has this additional data */ +struct cs6436_54p_fan_data { + struct platform_device *pdev; + struct device *hwmon_dev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 reg_val[ARRAY_SIZE(fan_reg)]; /* Register value */ +}; + +static struct cs6436_54p_fan_data *fan_data = NULL; + +enum fan_id { + FAN1_ID, + FAN2_ID, + FAN3_ID, + FAN4_ID, + FAN5_ID, +}; + +enum sysfs_fan_attributes { + FAN_STATE_REG, + FAN_DUTY_CYCLE_PERCENTAGE, /* Only one CPLD register to control duty cycle for all fans */ + FAN1_FRONT_SPEED_RPM, + FAN2_FRONT_SPEED_RPM, + FAN3_FRONT_SPEED_RPM, + FAN4_FRONT_SPEED_RPM, + FAN5_FRONT_SPEED_RPM, + FAN1_REAR_SPEED_RPM, + FAN2_REAR_SPEED_RPM, + FAN3_REAR_SPEED_RPM, + FAN4_REAR_SPEED_RPM, + FAN5_REAR_SPEED_RPM, + FAN_DIRECTION, + FAN1_STATE, + FAN2_STATE, + FAN3_STATE, + FAN4_STATE, + FAN5_STATE, + FAN1_FAULT, + FAN2_FAULT, + FAN3_FAULT, + FAN4_FAULT, + FAN5_FAULT, + FAN1_DIRECTION, + FAN2_DIRECTION, + FAN3_DIRECTION, + FAN4_DIRECTION, + FAN5_DIRECTION, +}; + +/* Define attributes + */ +#define DECLARE_FAN_STATE_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_state, S_IRUGO, fan_show_value, NULL, FAN##index##_STATE) +#define DECLARE_FAN_STATE_ATTR(index) &sensor_dev_attr_fan##index##_state.dev_attr.attr + +#define DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_fault, S_IRUGO, fan_show_value, NULL, FAN##index##_FAULT) +#define DECLARE_FAN_FAULT_ATTR(index) &sensor_dev_attr_fan##index##_fault.dev_attr.attr + +#define DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_duty_cycle_percentage, S_IWUSR | S_IRUGO, fan_show_value, set_duty_cycle, FAN##index##_DUTY_CYCLE_PERCENTAGE) +#define DECLARE_FAN_DUTY_CYCLE_ATTR(index) &sensor_dev_attr_fan##index##_duty_cycle_percentage.dev_attr.attr + +#define DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_front_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##index##_FRONT_SPEED_RPM);\ + static SENSOR_DEVICE_ATTR(fan##index##_rear_speed_rpm, S_IRUGO, fan_show_value, NULL, FAN##index##_REAR_SPEED_RPM) +#define DECLARE_FAN_SPEED_RPM_ATTR(index) &sensor_dev_attr_fan##index##_front_speed_rpm.dev_attr.attr, \ + &sensor_dev_attr_fan##index##_rear_speed_rpm.dev_attr.attr + +#define DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_direction, S_IWUSR | S_IRUGO, fan_show_value, set_fan_direction, FAN##index##_DIRECTION) +#define DECLARE_FAN_DIRECTION_ATTR(index) &sensor_dev_attr_fan##index##_direction.dev_attr.attr + + +/* 5 fan state attributes in this platform */ +DECLARE_FAN_STATE_SENSOR_DEV_ATTR(1); +DECLARE_FAN_STATE_SENSOR_DEV_ATTR(2); +DECLARE_FAN_STATE_SENSOR_DEV_ATTR(3); +DECLARE_FAN_STATE_SENSOR_DEV_ATTR(4); +DECLARE_FAN_STATE_SENSOR_DEV_ATTR(5); + + +/* 5 fan fault attributes in this platform */ +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(1); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(2); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(3); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(4); +DECLARE_FAN_FAULT_SENSOR_DEV_ATTR(5); + +/* 5 fan speed(rpm) attributes in this platform */ +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(1); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(2); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(3); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(4); +DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(5); + +/* 1 fan duty cycle attribute in this platform */ +DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(); + +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(1); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(2); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(3); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(4); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(5); + + +static struct attribute *cs6436_54p_fan_attributes[] = { + /* fan related attributes */ + DECLARE_FAN_STATE_ATTR(1), + DECLARE_FAN_STATE_ATTR(2), + DECLARE_FAN_STATE_ATTR(3), + DECLARE_FAN_STATE_ATTR(4), + DECLARE_FAN_STATE_ATTR(5), + DECLARE_FAN_FAULT_ATTR(1), + DECLARE_FAN_FAULT_ATTR(2), + DECLARE_FAN_FAULT_ATTR(3), + DECLARE_FAN_FAULT_ATTR(4), + DECLARE_FAN_FAULT_ATTR(5), + DECLARE_FAN_SPEED_RPM_ATTR(1), + DECLARE_FAN_SPEED_RPM_ATTR(2), + DECLARE_FAN_SPEED_RPM_ATTR(3), + DECLARE_FAN_SPEED_RPM_ATTR(4), + DECLARE_FAN_SPEED_RPM_ATTR(5), + DECLARE_FAN_DUTY_CYCLE_ATTR(), + DECLARE_FAN_DIRECTION_ATTR(1), + DECLARE_FAN_DIRECTION_ATTR(2), + DECLARE_FAN_DIRECTION_ATTR(3), + DECLARE_FAN_DIRECTION_ATTR(4), + DECLARE_FAN_DIRECTION_ATTR(5), + NULL +}; + +#define FAN_MAX_DUTY_CYCLE 100 +#define FAN_REG_VAL_TO_SPEED_RPM_STEP 100 + +/* fan utility functions + */ +static u32 reg_val_to_duty_cycle(u8 reg_val) +{ + if (reg_val +== 0xFF) { + return 100; + } + return ((u32)(reg_val) * 100)/ 255; +} + +static u8 duty_cycle_to_reg_val(u8 duty_cycle) +{ + if (duty_cycle >= FAN_MAX_DUTY_CYCLE) { + return 0xFF; + } + + return 255 / 10 * (duty_cycle / 10); +} + +static u32 reg_val_to_speed_rpm(u8 reg_val) +{ + return (u32)reg_val * FAN_REG_VAL_TO_SPEED_RPM_STEP; +} + +static u8 reg_val_to_is_state(u8 reg_val, enum fan_id id) +{ + u8 mask = (1 << id); + + reg_val &= mask; + + return reg_val ? 0 : 1; +} + +static u8 is_fan_fault(struct cs6436_54p_fan_data *data, enum fan_id id) +{ + u8 ret = 1; + int front_fan_index = FAN1_FRONT_SPEED_RPM + id; + int rear_fan_index = FAN1_REAR_SPEED_RPM + id; + + /* Check if the speed of front or rear fan is ZERO, + */ + if (reg_val_to_speed_rpm(data->reg_val[front_fan_index]) && + reg_val_to_speed_rpm(data->reg_val[rear_fan_index])) { + ret = 0; + } + + return ret; +} + + +static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int error, value; + + error = kstrtoint(buf, 10, &value); + if (error) + return error; + + if (value <= 0 || value > FAN_MAX_DUTY_CYCLE) + return -EINVAL; + + cig_cpld_write_register(fan_reg[FAN_DUTY_CYCLE_PERCENTAGE], duty_cycle_to_reg_val(value)); + + return count; +} + +static ssize_t set_fan_direction(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int error, value,fan_index; + u8 mask,reg_val; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + fan_index = attr->index - FAN1_DIRECTION; + error = kstrtoint(buf, 10, &value); + if (error) + return error; + + if (!(value == 0 || value == 1)) + return -EINVAL; + + + cig_cpld_read_register(fan_reg[FAN_DIRECTION],®_val); + + if(value == 1) + { + reg_val |= (1 << fan_index); + } + else + { + reg_val &= ~(1 << fan_index); + } + + cig_cpld_write_register(fan_reg[FAN_DIRECTION], reg_val); + + return count; +} + + + + + +static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + + cs6436_54p_fan_update_device(dev); + + struct cs6436_54p_fan_data *data = fan_data; + + ssize_t ret = 0; + + if (data->valid) { + switch (attr->index) { + + case FAN1_STATE: + case FAN2_STATE: + case FAN3_STATE: + case FAN4_STATE: + case FAN5_STATE: + //printk("FAN_STATE_REG: 0x%x\n", data->reg_val[FAN_STATE_REG]); + //printk("index: %d\n", attr->index); + ret = sprintf(buf, "%d\n", + reg_val_to_is_state(data->reg_val[FAN_STATE_REG], + attr->index - FAN1_STATE)); + break; + case FAN_DUTY_CYCLE_PERCENTAGE: + { + u32 duty_cycle = reg_val_to_duty_cycle(data->reg_val[FAN_DUTY_CYCLE_PERCENTAGE]); + ret = sprintf(buf, "%u\n", duty_cycle); + break; + } + case FAN1_FRONT_SPEED_RPM: + case FAN2_FRONT_SPEED_RPM: + case FAN3_FRONT_SPEED_RPM: + case FAN4_FRONT_SPEED_RPM: + case FAN5_FRONT_SPEED_RPM: + case FAN1_REAR_SPEED_RPM: + case FAN2_REAR_SPEED_RPM: + case FAN3_REAR_SPEED_RPM: + case FAN4_REAR_SPEED_RPM: + case FAN5_REAR_SPEED_RPM: +// printk("FAN_seed_REG: 0x%x\n", data->reg_val[attr->index]); +// printk("index: %d\n", attr->index); + ret = sprintf(buf, "%u\n", reg_val_to_speed_rpm(data->reg_val[attr->index])); + break; + + case FAN1_FAULT: + case FAN2_FAULT: + case FAN3_FAULT: + case FAN4_FAULT: + case FAN5_FAULT: + ret = sprintf(buf, "%d\n", is_fan_fault(data, attr->index - FAN1_FAULT)); + break; + case FAN1_DIRECTION: + case FAN2_DIRECTION: + case FAN3_DIRECTION: + case FAN4_DIRECTION: + case FAN5_DIRECTION: + ret = sprintf(buf, "%d\n",reg_val_to_is_state(data->reg_val[FAN_DIRECTION],attr->index - FAN1_DIRECTION)); + break; + default: + break; + } + } + + return ret; +} + +static const struct attribute_group cs6436_54p_fan_group = { + .attrs = cs6436_54p_fan_attributes, +}; + +static struct cs6436_54p_fan_data *cs6436_54p_fan_update_device(struct device *dev) +{ + struct cs6436_54p_fan_data *data = fan_data; + + mutex_lock(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || + !data->valid) { + int i; + + data->valid = 0; + + /* Update fan data + */ + for (i = 0; i < ARRAY_SIZE(data->reg_val); i++) { + u8 status; + (void)cig_cpld_read_register(fan_reg[i], &status); + + if (status < 0) { + data->valid = 0; + mutex_unlock(&data->update_lock); + return data; + } + else { + data->reg_val[i] = status; + } + } + + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->update_lock); + + return data; +} + +static int cs6436_54p_fan_probe(struct platform_device *pdev) +{ + int status = -1; + /* Register sysfs hooks */ + status = sysfs_create_group(&pdev->dev.kobj, &cs6436_54p_fan_group); + if (status) { + goto exit; + + } + + fan_data->hwmon_dev = hwmon_device_register(&pdev->dev); + if (IS_ERR(fan_data->hwmon_dev)) { + status = PTR_ERR(fan_data->hwmon_dev); + goto exit_remove; + } + + dev_info(&pdev->dev, "cs6436_54p_fan\n"); + + return 0; + +exit_remove: + sysfs_remove_group(&pdev->dev.kobj, &cs6436_54p_fan_group); +exit: + return status; +} + +static int cs6436_54p_fan_remove(struct platform_device *pdev) +{ + hwmon_device_unregister(fan_data->hwmon_dev); + sysfs_remove_group(&fan_data->pdev->dev.kobj, &cs6436_54p_fan_group); + + return 0; +} + +#define DRVNAME "cs6436_54p_fan" + +static struct platform_driver cs6436_54p_fan_driver = { + .probe = cs6436_54p_fan_probe, + .remove = cs6436_54p_fan_remove, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, +}; + + + + + +static int __init cs6436_54p_fan_init(void) +{ + int ret; + + cig_cpld_write_register(0x40, duty_cycle_to_reg_val(50)); + + ret = platform_driver_register(&cs6436_54p_fan_driver); + if (ret < 0) { + goto exit; + } + + fan_data = kzalloc(sizeof(struct cs6436_54p_fan_data), GFP_KERNEL); + if (!fan_data) { + ret = -ENOMEM; + platform_driver_unregister(&cs6436_54p_fan_driver); + goto exit; + } + + mutex_init(&fan_data->update_lock); + fan_data->valid = 0; + + fan_data->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(fan_data->pdev)) { + ret = PTR_ERR(fan_data->pdev); + platform_driver_unregister(&cs6436_54p_fan_driver); + kfree(fan_data); + goto exit; + } + +exit: + return ret; +} + +static void __exit cs6436_54p_fan_exit(void) +{ + platform_device_unregister(fan_data->pdev); + platform_driver_unregister(&cs6436_54p_fan_driver); + kfree(fan_data); +} + +MODULE_AUTHOR("CIG"); +MODULE_DESCRIPTION("cs6436_54p_fan driver"); +MODULE_LICENSE("GPL"); + +module_init(cs6436_54p_fan_init); +module_exit(cs6436_54p_fan_exit); + +MODULE_AUTHOR("Zhang Peng "); +MODULE_DESCRIPTION("cs6436_54p_fan driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-led.c b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-led.c new file mode 100644 index 000000000000..74c8b6d0b10e --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-led.c @@ -0,0 +1,594 @@ +/* + * A hwmon driver for the CIG cs6436-54P LED + * + * Copyright (C) 2018 Cambridge, Inc. + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/*#define DEBUG*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +extern int cig_cpld_write_register(u8 reg_off, u8 val); + +extern int cig_cpld_read_register(u8 reg_off, u8 *val); + +extern void led_classdev_unregister(struct led_classdev *led_cdev); +extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev); +extern void led_classdev_resume(struct led_classdev *led_cdev); +extern void led_classdev_suspend(struct led_classdev *led_cdev); + +#define DRVNAME "cs6436_54p_led" + +struct cs6436_54p_led_data { + struct platform_device *pdev; + struct mutex update_lock; + char valid; /* != 0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 reg_val[6]; /* 0: system & location + 1: PSU1 &PSU12 + 2: fan & management + 3: console & ToD + 4-5 : fan1-fan5*/ +}; + +static struct cs6436_54p_led_data *ledctl = NULL; + +/* LED related data + */ +#define LED_TYPE_PSU1_REG_MASK 0x0C +#define LED_MODE_PSU1_GREEN_MASK 0x08 +#define LED_MODE_PSU1_RED_MASK 0x04 +#define LED_MODE_PSU1_AMBER_MASK 0x0C +#define LED_MODE_PSU1_OFF_MASK 0x00 + +#define LED_TYPE_PSU2_REG_MASK 0x30 +#define LED_MODE_PSU2_GREEN_MASK 0x20 +#define LED_MODE_PSU2_RED_MASK 0x10 +#define LED_MODE_PSU2_AMBER_MASK 0x30 +#define LED_MODE_PSU2_OFF_MASK 0x00 + +#define LED_TYPE_SYS_REG_MASK 0xF0 +#define LED_MODE_SYS_GREEN_MASK 0x40 +#define LED_MODE_SYS_RED_MASK 0x20 +#define LED_MODE_SYS_AMBER_MASK 0x60 +#define LED_MODE_SYS_AMBER_FLASHING_MASK 0x70 +#define LED_MODE_SYS_OFF_MASK 0x00 + +#define LED_TYPE_RES_REG_MASK 0x0F +#define LED_MODE_RES_GREEN_MASK 0x04 +#define LED_MODE_RES_RED_MASK 0x02 +#define LED_MODE_RES_AMBER_MASK 0x06 +#define LED_MODE_RES_AMBER_FLASHING_MASK 0x07 +#define LED_MODE_RES_OFF_MASK 0x00 + +#define LED_TYPE_FAN_REG_MASK 0x03 +#define LED_MODE_FAN_GREEN_MASK 0x02 +#define LED_MODE_FAN_RED_MASK 0x01 +#define LED_MODE_FAN_AMBER_MASK 0x03 +#define LED_MODE_FAN_OFF_MASK 0x00 + +#define LED_TYPE_FAN1_REG_MASK 0x03 +#define LED_TYPE_FAN2_REG_MASK 0x0C +#define LED_TYPE_FAN3_REG_MASK 0x30 +#define LED_TYPE_FAN4_REG_MASK 0xC0 +#define LED_TYPE_FAN5_REG_MASK 0x03 + +#define LED_MODE_FANX_GREEN_MASK 0x02 +#define LED_MODE_FANX_RED_MASK 0x01 +#define LED_MODE_FANX_AMBER_MASK 0x03 +#define LED_MODE_FANX_OFF_MASK 0x00 + +enum led_type { + LED_TYPE_SYS, + LED_TYPE_PSU2, + LED_TYPE_PSU1, + LED_TYPE_FAN, + LED_TYPE_FAN1, + LED_TYPE_FAN2, + LED_TYPE_FAN3, + LED_TYPE_FAN4, + LED_TYPE_FAN5, +}; + +static const u8 led_reg[] = { + 0x30, /* system & reserved*/ + 0x31, /* fan & PSU1 & PSU2 */ + 0x32, /* FAN5 LED */ + 0x33, /* FAN1-4 LED */ +}; + + +enum led_light_mode { + LED_MODE_OFF = 0, + LED_MODE_GREEN, + LED_MODE_AMBER, + LED_MODE_RED, + LED_MODE_GREEN_BLINK, + LED_MODE_AMBER_BLINK, + LED_MODE_RED_BLINK, + LED_MODE_GREEN_FLASHING, + LED_MODE_AMBER_FLASHING, + LED_MODE_RED_FLASHING, + LED_MODE_AUTO, + LED_MODE_UNKNOWN +}; + +struct led_type_mode { + enum led_type type; + int type_mask; + enum led_light_mode mode; + int mode_mask; +}; + +static struct led_type_mode led_type_mode_data[] = { +{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_GREEN, LED_MODE_PSU1_GREEN_MASK}, +{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_AMBER, LED_MODE_PSU1_AMBER_MASK}, +{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_RED, LED_MODE_PSU1_RED_MASK}, +{LED_TYPE_PSU1, LED_TYPE_PSU1_REG_MASK, LED_MODE_OFF, LED_MODE_PSU1_OFF_MASK}, + +{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_GREEN, LED_MODE_PSU2_GREEN_MASK}, +{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_AMBER, LED_MODE_PSU2_AMBER_MASK}, +{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_RED, LED_MODE_PSU2_RED_MASK}, +{LED_TYPE_PSU2, LED_TYPE_PSU2_REG_MASK, LED_MODE_OFF, LED_MODE_PSU2_OFF_MASK}, + +{LED_TYPE_SYS, LED_TYPE_SYS_REG_MASK, LED_MODE_GREEN, LED_MODE_SYS_GREEN_MASK}, +{LED_TYPE_SYS, LED_TYPE_SYS_REG_MASK, LED_MODE_AMBER, LED_MODE_SYS_AMBER_MASK}, +{LED_TYPE_SYS, LED_TYPE_SYS_REG_MASK, LED_MODE_RED, LED_MODE_SYS_RED_MASK}, +{LED_TYPE_SYS, LED_TYPE_SYS_REG_MASK, LED_MODE_AMBER_FLASHING, LED_MODE_SYS_AMBER_FLASHING_MASK}, +{LED_TYPE_SYS, LED_TYPE_SYS_REG_MASK, LED_MODE_OFF, LED_MODE_SYS_OFF_MASK}, + +{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_GREEN, LED_MODE_FAN_GREEN_MASK}, +{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_AMBER, LED_MODE_FAN_AMBER_MASK}, +{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_RED, LED_MODE_FAN_RED_MASK}, +{LED_TYPE_FAN, LED_TYPE_FAN_REG_MASK, LED_MODE_OFF, LED_MODE_FAN_OFF_MASK}, + +{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 0}, +{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 0}, +{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_AMBER, LED_MODE_FANX_AMBER_MASK << 0}, +{LED_TYPE_FAN1, LED_TYPE_FAN1_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 0}, +{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 2}, +{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 2}, +{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_AMBER, LED_MODE_FANX_AMBER_MASK << 2}, +{LED_TYPE_FAN2, LED_TYPE_FAN2_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 2}, +{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 4}, +{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 4}, +{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_AMBER, LED_MODE_FANX_AMBER_MASK << 4}, +{LED_TYPE_FAN3, LED_TYPE_FAN3_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 4}, +{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 6}, +{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 6}, +{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_AMBER, LED_MODE_FANX_AMBER_MASK << 6}, +{LED_TYPE_FAN4, LED_TYPE_FAN4_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 6}, +{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_GREEN, LED_MODE_FANX_GREEN_MASK << 0}, +{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_RED, LED_MODE_FANX_RED_MASK << 0}, +{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_AMBER, LED_MODE_FANX_AMBER_MASK << 0}, +{LED_TYPE_FAN5, LED_TYPE_FAN5_REG_MASK, LED_MODE_OFF, LED_MODE_FANX_OFF_MASK << 0}, +}; + +struct fanx_info_s { + u8 cname; /* device name */ + enum led_type type; + u8 reg_id; /* map to led_reg & reg_val */ +}; + +static struct fanx_info_s fanx_info[] = { + {'1', LED_TYPE_FAN1, 3}, + {'2', LED_TYPE_FAN2, 3}, + {'3', LED_TYPE_FAN3, 3}, + {'4', LED_TYPE_FAN4, 3}, + {'5', LED_TYPE_FAN5, 2}, +}; + + +static int led_reg_val_to_light_mode(enum led_type type, u8 reg_val) { + int i; + + for (i = 0; i < ARRAY_SIZE(led_type_mode_data); i++) { + + if (type != led_type_mode_data[i].type) + continue; + + if ((led_type_mode_data[i].type_mask & reg_val) == + led_type_mode_data[i].mode_mask) + { + return led_type_mode_data[i].mode; + } + } + + return 0; +} + +static u8 led_light_mode_to_reg_val(enum led_type type, + enum led_light_mode mode, u8 reg_val) { + int i; + + for (i = 0; i < ARRAY_SIZE(led_type_mode_data); i++) { + if (type != led_type_mode_data[i].type) + continue; + + if (mode != led_type_mode_data[i].mode) + continue; + + reg_val = led_type_mode_data[i].mode_mask | + (reg_val & (~led_type_mode_data[i].type_mask)); + break; + } + + return reg_val; +} + +static void cs6436_54p_led_update(void) +{ + mutex_lock(&ledctl->update_lock); + + if (time_after(jiffies, ledctl->last_updated + HZ + HZ / 2) + || !ledctl->valid) { + int i; + + dev_dbg(&ledctl->pdev->dev, "Starting cs6436_54p_led update\n"); + + /* Update LED data + */ + for (i = 0; i < ARRAY_SIZE(ledctl->reg_val); i++) { + u8 status; + cig_cpld_read_register(led_reg[i], &status); + + if (status < 0) { + ledctl->valid = 0; + dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", led_reg[i], status); + goto exit; + } + else + { + ledctl->reg_val[i] = status; + } + } + + ledctl->last_updated = jiffies; + ledctl->valid = 1; + } + +exit: + mutex_unlock(&ledctl->update_lock); +} + +static void cs6436_54p_led_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode, + u8 reg, enum led_type type) +{ + u8 reg_val; + mutex_lock(&ledctl->update_lock); + + cig_cpld_read_register(reg, ®_val); + if (reg_val < 0) { + dev_dbg(&ledctl->pdev->dev, "reg %d, err %d\n", reg, reg_val); + goto exit; + } + + reg_val = led_light_mode_to_reg_val(type, led_light_mode, reg_val); + + cig_cpld_write_register(reg, reg_val); + + /* to prevent the slow-update issue */ + ledctl->valid = 0; + +exit: + mutex_unlock(&ledctl->update_lock); +} + +static void cs6436_54p_led_fanx_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + enum led_type led_type1; + int reg_id; + int i, nsize; + int ncount = sizeof(fanx_info)/sizeof(struct fanx_info_s); + + for(i=0;iname); + + if (led_cdev->name[nsize-1] == fanx_info[i].cname) + { + led_type1 = fanx_info[i].type; + reg_id = fanx_info[i].reg_id; + + cs6436_54p_led_set(led_cdev, led_light_mode, led_reg[reg_id], led_type1); + return; + } + } +} + + +static enum led_brightness cs6436_54p_led_fanx_get(struct led_classdev *cdev) +{ + enum led_type led_type1; + int reg_id; + int i, nsize; + int ncount = sizeof(fanx_info)/sizeof(struct fanx_info_s); + + for(i=0;iname); + + if (cdev->name[nsize-1] == fanx_info[i].cname) + { + led_type1 = fanx_info[i].type; + reg_id = fanx_info[i].reg_id; + cs6436_54p_led_update(); + return led_reg_val_to_light_mode(led_type1, ledctl->reg_val[reg_id]); + } + } + + return led_reg_val_to_light_mode(LED_TYPE_FAN1, ledctl->reg_val[5]); +} + + +static void cs6436_54p_led_psu1_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + cs6436_54p_led_set(led_cdev, led_light_mode, led_reg[1], LED_TYPE_PSU1); +} + +static enum led_brightness cs6436_54p_led_psu1_get(struct led_classdev *cdev) +{ + cs6436_54p_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_PSU1, ledctl->reg_val[1]); +} + +static void cs6436_54p_led_psu2_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + cs6436_54p_led_set(led_cdev, led_light_mode, led_reg[1], LED_TYPE_PSU2); +} + +static enum led_brightness cs6436_54p_led_psu2_get(struct led_classdev *cdev) +{ + cs6436_54p_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_PSU2, ledctl->reg_val[1]); +} + +static void cs6436_54p_led_sys_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + cs6436_54p_led_set(led_cdev, led_light_mode,led_reg[0], LED_TYPE_SYS); +} + +static enum led_brightness cs6436_54p_led_sys_get(struct led_classdev *cdev) +{ + cs6436_54p_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_SYS, ledctl->reg_val[0]); +} + + +static enum led_brightness cs6436_54p_led_fan_get(struct led_classdev *cdev) +{ + cs6436_54p_led_update(); + return led_reg_val_to_light_mode(LED_TYPE_FAN, ledctl->reg_val[1]); +} + +static void cs6436_54p_led_fan_set(struct led_classdev *led_cdev, + enum led_brightness led_light_mode) +{ + cs6436_54p_led_set(led_cdev, led_light_mode, led_reg[1], LED_TYPE_FAN); +} + + +static struct led_classdev cs6436_54p_leds[] = { + [LED_TYPE_SYS] = { + .name = "cs6436_54p_led::sys", + .default_trigger = "unused", + .brightness_set = cs6436_54p_led_sys_set, + .brightness_get = cs6436_54p_led_sys_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN] = { + .name = "cs6436_54p_led::fan", + .default_trigger = "unused", + .brightness_set = cs6436_54p_led_fan_set, + .brightness_get = cs6436_54p_led_fan_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + + [LED_TYPE_PSU1] = { + .name = "cs6436_54p_led::psu1", + .default_trigger = "unused", + .brightness_set = cs6436_54p_led_psu1_set, + .brightness_get = cs6436_54p_led_psu1_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_PSU2] = { + .name = "cs6436_54p_led::psu2", + .default_trigger = "unused", + .brightness_set = cs6436_54p_led_psu2_set, + .brightness_get = cs6436_54p_led_psu2_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + + [LED_TYPE_FAN1] = { + .name = "cs6436_54p_led::fan1", + .default_trigger = "unused", + .brightness_set = cs6436_54p_led_fanx_set, + .brightness_get = cs6436_54p_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN2] = { + .name = "cs6436_54p_led::fan2", + .default_trigger = "unused", + .brightness_set = cs6436_54p_led_fanx_set, + .brightness_get = cs6436_54p_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN3] = { + .name = "cs6436_54p_led::fan3", + .default_trigger = "unused", + .brightness_set = cs6436_54p_led_fanx_set, + .brightness_get = cs6436_54p_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN4] = { + .name = "cs6436_54p_led::fan4", + .default_trigger = "unused", + .brightness_set = cs6436_54p_led_fanx_set, + .brightness_get = cs6436_54p_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + }, + [LED_TYPE_FAN5] = { + .name = "cs6436_54p_led::fan5", + .default_trigger = "unused", + .brightness_set = cs6436_54p_led_fanx_set, + .brightness_get = cs6436_54p_led_fanx_get, + .flags = LED_CORE_SUSPENDRESUME, + .max_brightness = LED_MODE_AUTO, + } +}; + +static int cs6436_54p_led_suspend(struct platform_device *dev, + pm_message_t state) +{ + int i = 0; + + for (i = 0; i < ARRAY_SIZE(cs6436_54p_leds); i++) { + led_classdev_suspend(&cs6436_54p_leds[i]); + } + + return 0; +} + +static int cs6436_54p_led_resume(struct platform_device *dev) +{ + int i = 0; + + for (i = 0; i < ARRAY_SIZE(cs6436_54p_leds); i++) { + led_classdev_resume(&cs6436_54p_leds[i]); + } + + return 0; +} + +static int cs6436_54p_led_probe(struct platform_device *pdev) +{ + int ret, i; + + for (i = 0; i < ARRAY_SIZE(cs6436_54p_leds); i++) { + ret = led_classdev_register(&pdev->dev, &cs6436_54p_leds[i]); + + if (ret < 0) + break; + } + + /* Check if all LEDs were successfully registered */ + if (i != ARRAY_SIZE(cs6436_54p_leds)) { + int j; + + /* only unregister the LEDs that were successfully registered */ + for (j = 0; j < i; j++) { + led_classdev_unregister(&cs6436_54p_leds[i]); + } + } + + return ret; +} + +static int cs6436_54p_led_remove(struct platform_device *pdev) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(cs6436_54p_leds); i++) { + led_classdev_unregister(&cs6436_54p_leds[i]); + } + + return 0; +} + +static struct platform_driver cs6436_54p_led_driver = { + .probe = cs6436_54p_led_probe, + .remove = cs6436_54p_led_remove, + .suspend = cs6436_54p_led_suspend, + .resume = cs6436_54p_led_resume, + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, +}; + +static int cs6436_54p_led_default(void) +{ + cig_cpld_write_register(0x30, 0x40);// system green led solid on +} + +static int __init cs6436_54p_led_init(void) +{ + int ret; + + ret = platform_driver_register(&cs6436_54p_led_driver); + if (ret < 0) { + goto exit; + } + + ledctl = kzalloc(sizeof(struct cs6436_54p_led_data), GFP_KERNEL); + if (!ledctl) { + ret = -ENOMEM; + platform_driver_unregister(&cs6436_54p_led_driver); + goto exit; + } + + mutex_init(&ledctl->update_lock); + + ledctl->pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0); + if (IS_ERR(ledctl->pdev)) { + ret = PTR_ERR(ledctl->pdev); + platform_driver_unregister(&cs6436_54p_led_driver); + kfree(ledctl); + goto exit; + } + + cs6436_54p_led_default(); + +exit: + return ret; +} + +static void __exit cs6436_54p_led_exit(void) +{ + platform_device_unregister(ledctl->pdev); + platform_driver_unregister(&cs6436_54p_led_driver); + kfree(ledctl); +} + +module_init(cs6436_54p_led_init); +module_exit(cs6436_54p_led_exit); + +MODULE_AUTHOR("Zhang Peng "); +MODULE_DESCRIPTION("cs6436_54p_led driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-psu.c b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-psu.c new file mode 100644 index 000000000000..e8fc896ea13a --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-psu.c @@ -0,0 +1,943 @@ +/* + * A hwmon driver for the CIG cs6436-54P Power Module + * + * Copyright (C) 2018 Cambridge, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 "i2c-algo-lpc.h" + + + +#define MAX_FAN_DUTY_CYCLE 100 + +/* Address scanned */ +static const unsigned short normal_i2c[] = {I2C_CLIENT_END }; + +/* This is additional data */ +struct cs6436_54p_psu_data { + struct device *hwmon_dev; + struct mutex update_lock; + char valid; + unsigned long last_updated; /* In jiffies */ + + /* Registers value */ + u8 vout_mode; + u16 v_in; + u16 v_out; + u16 i_in; + u16 i_out; + u16 p_in; + u16 p_out; + u16 temp_input[3]; + u8 temp_fault; + u8 fan_fault; + u16 fan_duty_cycle[2]; + u16 fan_speed[2]; + u8 mfr_id[8]; + u8 mfr_model[20]; + u8 mfr_serial[20]; + u8 psu_is_present; + u8 psu_is_good; + struct i2c_client *client; + struct bin_attribute *bin; /* eeprom data */ +}; + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask); +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *dev_attr, const char *buf, size_t count); +static ssize_t for_linear_data(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_fan_fault(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_fan_warning(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_temp_fault(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_temp_warning(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_vout_data(struct device *dev, struct device_attribute *dev_attr, char *buf); +static int cs6436_54p_psu_read_byte(struct i2c_client *client, u8 reg); +static int cs6436_54p_psu_read_word(struct i2c_client *client, u8 reg); +static int cs6436_54p_psu_write_word(struct i2c_client *client, u8 reg, u16 value); +static int cs6436_54p_psu_read_block(struct i2c_client *client, u8 command, u8 *data, int data_len); +static struct cs6436_54p_psu_data *cs6436_54p_psu_update_device(struct device *dev); +static ssize_t for_ascii(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_status(struct device *dev, struct device_attribute *dev_attr, char *buf); + +enum cs6436_54p_psu_sysfs_attributes { + PSU_V_IN, + PSU_V_OUT, + PSU_I_IN, + PSU_I_OUT, + PSU_P_IN, + PSU_P_OUT, + PSU_TEMP1_INPUT, + PSU_TEMP2_INPUT, + PSU_TEMP3_INPUT, + PSU_TEMP_FAULT, + PSU_TEMP_WARN, + PSU_FAN1_FAULT, + PSU_FAN1_WARN, + PSU_FAN1_DUTY_CYCLE, + PSU_FAN1_SPEED, + PSU_MFR_ID, + PSU_MFR_MODEL, + PSU_MFR_SERIAL, + PSU_PRESENT, + PSU_P_GOOD, +}; + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask) +{ + u16 valid_data = data & mask; + + bool is_negative = valid_data >> (valid_bit - 1); + return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; +} + +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute \ + *dev_attr, const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct i2c_client *client = to_i2c_client(dev); + struct cs6436_54p_psu_data *data = i2c_get_clientdata(client); + int nr = (attr->index == PSU_FAN1_DUTY_CYCLE) ? 0 : 1; + long speed; + int error; + + if (data->valid != 1) + { + return -ENODEV; + } + + error = kstrtol(buf, 10, &speed); + if (error) + return error; + + if (speed < 0 || speed > MAX_FAN_DUTY_CYCLE) + return -EINVAL; + + + mutex_lock(&data->update_lock); + data->fan_duty_cycle[nr] = speed; + cs6436_54p_psu_write_word(client, 0x3B + nr, data->fan_duty_cycle[nr]); + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t for_linear_data(struct device *dev, struct device_attribute *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs6436_54p_psu_data *data = cs6436_54p_psu_update_device(dev); + + u16 value = 0; + int exponent, mantissa; + int multiplier = 1000; + + if (data->valid != 1) + { + return -ENODEV; + } + + switch (attr->index) { + case PSU_V_IN: + value = data->v_in; + break; + case PSU_I_IN: + value = data->i_in; + break; + case PSU_I_OUT: + value = data->i_out; + break; + case PSU_P_IN: + value = data->p_in; + break; + case PSU_P_OUT: + value = data->p_out; + break; + case PSU_TEMP1_INPUT: + value = data->temp_input[0]; + break; + case PSU_TEMP2_INPUT: + value = data->temp_input[1]; + break; + case PSU_TEMP3_INPUT: + value = data->temp_input[2]; + break; + case PSU_FAN1_DUTY_CYCLE: + multiplier = 1; + value = data->fan_duty_cycle[0]; + break; + case PSU_FAN1_SPEED: + multiplier = 1; + value = data->fan_speed[0]; + break; + default: + break; + } + + exponent = two_complement_to_int(value >> 11, 5, 0x1f); + mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); + + return (exponent >= 0) ? sprintf(buf, "%d\n", \ + (mantissa << exponent) * multiplier) : \ + sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); +} + +static ssize_t for_fan_fault(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs6436_54p_psu_data *data = cs6436_54p_psu_update_device(dev); + + if (data->valid != 1) + { + return -ENODEV; + } + + u8 shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6; + + return sprintf(buf, "%d\n", data->fan_fault >> shift); +} + +static ssize_t for_fan_warning(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs6436_54p_psu_data *data = cs6436_54p_psu_update_device(dev); + + if (data->valid != 1) + { + return -ENODEV; + } + + u8 shift = (attr->index == PSU_FAN1_WARN) ? 5 : 4; + + return sprintf(buf, "%d\n", data->fan_fault >> shift); +} + +static ssize_t for_temp_fault(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs6436_54p_psu_data *data = cs6436_54p_psu_update_device(dev); + + if (data->valid != 1) + { + return -ENODEV; + } + + + + return sprintf(buf, "%d\n", data->temp_fault >> 7); +} + +static ssize_t for_temp_warning(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs6436_54p_psu_data *data = cs6436_54p_psu_update_device(dev); + if (data->valid != 1) + { + return -ENODEV; + } + + + return sprintf(buf, "%d\n", data->temp_fault >> 6); +} +static ssize_t for_vout_data(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct cs6436_54p_psu_data *data = cs6436_54p_psu_update_device(dev); + int exponent, mantissa; + int multiplier = 1000; + if (data->valid != 1) + { + return -ENODEV; + } + + + exponent = two_complement_to_int(data->vout_mode, 5, 0x1f); + mantissa = data->v_out; + + return (exponent > 0) ? sprintf(buf, "%d\n", \ + (mantissa << exponent) * multiplier) : \ + sprintf(buf, "%d\n", ((mantissa * multiplier) >> (-exponent))); +} + +static ssize_t for_ascii(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs6436_54p_psu_data *data = cs6436_54p_psu_update_device(dev); + u8 *ptr = NULL; + + if (data->valid != 1) + { + return -ENODEV; + } + + switch (attr->index) { + case PSU_MFR_ID: + ptr = data->mfr_id + 1; + break; + case PSU_MFR_MODEL: + ptr = data->mfr_model + 1; + break; + case PSU_MFR_SERIAL: + ptr = data->mfr_serial + 1; + break; + default: + return 0; + } + return sprintf(buf, "%s\n", ptr); +} + + +static ssize_t for_status(struct device *dev, struct device_attribute *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs6436_54p_psu_data *data = cs6436_54p_psu_update_device(dev); + u8 *ptr = NULL; + + u8 status = 0; + + if (attr->index == PSU_PRESENT) { + status = data->psu_is_present; + } + else { /* PSU_POWER_GOOD */ + if (!data->valid) { + return -ENODEV; + } + + status = data->psu_is_good; + } + + return sprintf(buf, "%d\n", status); +} + + +static int cs6436_54p_psu_read_byte(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_byte_data(client, reg); +} + +static int cs6436_54p_psu_read_word(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_word_data(client, reg); +} + +static int cs6436_54p_psu_write_word(struct i2c_client *client, u8 reg, \ + u16 value) +{ + union i2c_smbus_data data; + data.word = value; + return i2c_smbus_xfer(client->adapter, client->addr, + client->flags |= I2C_CLIENT_PEC, + I2C_SMBUS_WRITE, reg, + I2C_SMBUS_WORD_DATA, &data); + +} + +static int cs6436_54p_psu_read_block(struct i2c_client *client, u8 command, \ + u8 *data, int data_len) +{ + int result = i2c_smbus_read_i2c_block_data(client, command, data_len, + data); + if (unlikely(result < 0)) + goto abort; + if (unlikely(result != data_len)) { + result = -EIO; + goto abort; + } + + result = 0; +abort: + return result; + +} + +struct reg_data_byte { + u8 reg; + u8 *value; +}; + +struct reg_data_word { + u8 reg; + u16 *value; +}; + + + +#define EEPROM_NAME "psu_eeprom" +#define EEPROM_SIZE 256 /* 256 byte eeprom */ + +/* Platform dependent --- */ +static ssize_t psu_eeprom_write(struct i2c_client *client, u8 command, const char *data, + int data_len) +{ + int status, retry = 3; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + status = i2c_smbus_write_i2c_block_data(client, command, data_len, data); + if (unlikely(status < 0)) { + msleep(100); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + return status; + } + + return data_len; + +} + + +static ssize_t psu_page_write(struct i2c_client *client,const char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + return count; + } + + /* + * Write data to chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + + + while (count) { + ssize_t status; + + status = psu_eeprom_write(client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + buf += status; + off += status; + count -= status; + retval += status; + } + + + return retval; +} + + + +static ssize_t psu_bin_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + int present; + struct cs6436_54p_psu_data *data; + ssize_t retval = 0; + struct i2c_client *client; + + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + client = to_i2c_client(container_of(kobj, struct device, kobj)); + + mutex_lock(&data->update_lock); + retval = psu_page_write(client, buf, off, count); + mutex_unlock(&data->update_lock); + return retval; +} + + +static ssize_t psu_eeprom_read(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ + int status, retry = 3; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + status = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + if (unlikely(status < 0)) { + msleep(100); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + goto abort; + } + if (unlikely(status != data_len)) { + status = -EIO; + goto abort; + } + +abort: + return status; +} + + + +static ssize_t psu_page_read(struct i2c_client *client,char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + printk("Count = 0, return"); + return count; + } + /* + * Read data from chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + + + while (count) { + ssize_t status; + + status = psu_eeprom_read(client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + + buf += status; + off += status; + count -= status; + retval += status; + } + + + return retval; + +} + + +static ssize_t psu_bin_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + int present; + struct cs6436_54p_psu_data *data; + struct i2c_client *client; + ssize_t retval = 0; + + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + client = to_i2c_client(container_of(kobj, struct device, kobj)); + mutex_lock(&data->update_lock); + retval = psu_page_read(client, buf, off, count); + mutex_unlock(&data->update_lock); + + return retval; +} + + + +static int psu_sysfs_eeprom_init(struct kobject *kobj, struct bin_attribute *eeprom) +{ + int err; + + sysfs_bin_attr_init(eeprom); + eeprom->attr.name = EEPROM_NAME; + eeprom->attr.mode = S_IWUSR | S_IRUGO; + eeprom->read = psu_bin_read; + eeprom->write = psu_bin_write; + eeprom->size = EEPROM_SIZE; + + /* Create eeprom file */ + err = sysfs_create_bin_file(kobj, eeprom); + if (err) { + return err; + } + + return 0; +} + + +static int psu_sysfs_eeprom_cleanup(struct kobject *kobj, struct bin_attribute *eeprom) +{ + sysfs_remove_bin_file(kobj, eeprom); + return 0; +} + + +static int psu_i2c_check_functionality(struct i2c_client *client) +{ + return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_I2C_BLOCK); +} + + + +static int psu_eeprom_probe(struct i2c_client *client, const struct i2c_device_id *dev_id) +{ + int status; + + struct cs6436_54p_psu_data *data; + + if (!psu_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + mutex_init(&data->update_lock); + + data->bin = kzalloc(sizeof(struct bin_attribute), GFP_KERNEL); + if (!data->bin) { + status = -ENOMEM; + goto eeprom_bin_error; + } + + /* init eeprom */ + status = psu_sysfs_eeprom_init(&client->dev.kobj, data->bin); + if (status) { + status = -ENOMEM; + goto sys_init_error; + } + + dev_info(&client->dev, "psu eeprom '%s'\n", client->name); + + return 0; + + sys_init_error: + kfree(data->bin); + + eeprom_bin_error: + kfree(data); + + exit: + return status; +} + + + + +static struct cs6436_54p_psu_data *cs6436_54p_psu_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cs6436_54p_psu_data *data = i2c_get_clientdata(client); + + + mutex_lock(&data->update_lock); + + + if (time_after(jiffies, data->last_updated)) { + int i, status; + u8 command; + struct reg_data_byte regs_byte[] = { + {0x20, &data->vout_mode}, + {0x81, &data->fan_fault}, + {0x7d, &data->temp_fault}, + }; + struct reg_data_word regs_word[] = { + {0x88, &data->v_in}, + {0x8b, &data->v_out}, + {0x89, &data->i_in}, + {0x8c, &data->i_out}, + {0x96, &data->p_out}, + {0x97, &data->p_in}, + {0x8d, &(data->temp_input[0])}, + {0x8e, &(data->temp_input[1])}, + {0x3b, &(data->fan_duty_cycle[0])}, + {0x90, &(data->fan_speed[0])}, + }; + data->valid = 1; + + dev_dbg(&client->dev, "start data update\n"); + + /* one milliseconds from now */ + data->last_updated = jiffies + HZ / 1000; + + for (i = 0; i < ARRAY_SIZE(regs_byte); i++) { + status = cs6436_54p_psu_read_byte(client, + regs_byte[i].reg); + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_byte[i].reg, status); + *(regs_byte[i].value) = 0; + data->valid = 0; + } else { + *(regs_byte[i].value) = status; + } + } + + for (i = 0; i < ARRAY_SIZE(regs_word); i++) { + status = cs6436_54p_psu_read_word(client, + regs_word[i].reg); + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_word[i].reg, status); + *(regs_word[i].value) = 0; + data->valid = 0; + } else { + *(regs_word[i].value) = status; + } + } + + command = 0x99; /* PSU mfr_id */ + status = cs6436_54p_psu_read_block(client, command, + data->mfr_id, ARRAY_SIZE(data->mfr_id) - 1); + data->mfr_id[ARRAY_SIZE(data->mfr_id) - 1] = '\0'; + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + memset(data->mfr_id, 0, sizeof(data->mfr_id)); + data->valid = 0; + } + + command = 0x9a; /* PSU mfr_model */ + status = cs6436_54p_psu_read_block(client, command, + data->mfr_model, ARRAY_SIZE(data->mfr_model) - 1); + data->mfr_model[ARRAY_SIZE(data->mfr_model) - 1] = '\0'; + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + memset(data->mfr_model, 0, sizeof(data->mfr_id)); + data->valid = 0; + } + + command = 0x9e; /* PSU mfr_serial */ + status = cs6436_54p_psu_read_block(client, command, + data->mfr_serial, ARRAY_SIZE(data->mfr_serial) - 1); + data->mfr_serial[ARRAY_SIZE(data->mfr_serial) - 1] = '\0'; + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + memset(data->mfr_serial, 0, sizeof(data->mfr_id)); + data->valid = 0; + } + + data->psu_is_present = strlen(data->mfr_id) > 1 ? 1:0; + if(data->psu_is_present) + { + data->psu_is_good = ((data->fan_fault) || (data->temp_fault))? 0:1; + } + else + { + data->valid = 0; + data->psu_is_good = 0; + } + } + + mutex_unlock(&data->update_lock); + + return data; + +} + +/* sysfs attributes for hwmon */ +static SENSOR_DEVICE_ATTR(psu_v_in, S_IRUGO, for_linear_data, NULL, PSU_V_IN); +static SENSOR_DEVICE_ATTR(psu_v_out, S_IRUGO, for_vout_data, NULL, PSU_V_OUT); +static SENSOR_DEVICE_ATTR(psu_i_in, S_IRUGO, for_linear_data, NULL, PSU_I_IN); +static SENSOR_DEVICE_ATTR(psu_i_out, S_IRUGO, for_linear_data, NULL, PSU_I_OUT); +static SENSOR_DEVICE_ATTR(psu_p_in, S_IRUGO, for_linear_data, NULL, PSU_P_IN); +static SENSOR_DEVICE_ATTR(psu_p_out, S_IRUGO, for_linear_data, NULL, PSU_P_OUT); +static SENSOR_DEVICE_ATTR(psu_temp1_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP1_INPUT); +static SENSOR_DEVICE_ATTR(psu_temp2_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP2_INPUT); +static SENSOR_DEVICE_ATTR(psu_temp3_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP3_INPUT); +static SENSOR_DEVICE_ATTR(psu_temp_fault, S_IRUGO, for_temp_fault, NULL, PSU_TEMP_FAULT); +static SENSOR_DEVICE_ATTR(psu_temp_warning, S_IRUGO, for_temp_warning, NULL, PSU_TEMP_WARN); +static SENSOR_DEVICE_ATTR(psu_fan1_fault, S_IRUGO, for_fan_fault, NULL, PSU_FAN1_FAULT); +static SENSOR_DEVICE_ATTR(psu_fan1_warning, S_IRUGO, for_fan_warning, NULL, PSU_FAN1_WARN); +static SENSOR_DEVICE_ATTR(psu_fan1_duty_cycle_percentage, S_IWUSR | S_IRUGO, for_linear_data, set_fan_duty_cycle, PSU_FAN1_DUTY_CYCLE); +static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm, S_IRUGO, for_linear_data, NULL, PSU_FAN1_SPEED); +static SENSOR_DEVICE_ATTR(psu_mfr_id, S_IRUGO, for_ascii, NULL, PSU_MFR_ID); +static SENSOR_DEVICE_ATTR(psu_mfr_model, S_IRUGO, for_ascii, NULL, PSU_MFR_MODEL); +static SENSOR_DEVICE_ATTR(psu_mfr_serial, S_IRUGO, for_ascii, NULL, PSU_MFR_SERIAL); +static SENSOR_DEVICE_ATTR(psu_present, S_IRUGO, for_status, NULL, PSU_PRESENT); +static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, for_status, NULL, PSU_P_GOOD); + + + +static struct attribute *cs6436_54p_psu_attributes[] = { + &sensor_dev_attr_psu_v_in.dev_attr.attr, + &sensor_dev_attr_psu_v_out.dev_attr.attr, + &sensor_dev_attr_psu_i_in.dev_attr.attr, + &sensor_dev_attr_psu_i_out.dev_attr.attr, + &sensor_dev_attr_psu_p_in.dev_attr.attr, + &sensor_dev_attr_psu_p_out.dev_attr.attr, + &sensor_dev_attr_psu_temp1_input.dev_attr.attr, + &sensor_dev_attr_psu_temp2_input.dev_attr.attr, + &sensor_dev_attr_psu_temp3_input.dev_attr.attr, + &sensor_dev_attr_psu_temp_fault.dev_attr.attr, + &sensor_dev_attr_psu_temp_warning.dev_attr.attr, + &sensor_dev_attr_psu_fan1_fault.dev_attr.attr, + &sensor_dev_attr_psu_fan1_warning.dev_attr.attr, + &sensor_dev_attr_psu_fan1_duty_cycle_percentage.dev_attr.attr, + &sensor_dev_attr_psu_fan1_speed_rpm.dev_attr.attr, + &sensor_dev_attr_psu_mfr_id.dev_attr.attr, + &sensor_dev_attr_psu_mfr_model.dev_attr.attr, + &sensor_dev_attr_psu_mfr_serial.dev_attr.attr, + &sensor_dev_attr_psu_present.dev_attr.attr, + &sensor_dev_attr_psu_power_good.dev_attr.attr, + NULL +}; + +static const struct attribute_group cs6436_54p_psu_group = { + .attrs = cs6436_54p_psu_attributes, +}; + + +static int psu_register_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int status; + + + struct cs6436_54p_psu_data *data; + + if (!psu_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + mutex_init(&data->update_lock); + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &cs6436_54p_psu_group); + if (status) + goto exit_sysfs_create_group; + + cs6436_54p_sysfs_add_client(client); + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_hwmon_device_register; + } + + /* init eeprom */ + + return 0; + + exit_hwmon_device_register: + sysfs_remove_group(&client->dev.kobj, &cs6436_54p_psu_group); + exit_sysfs_create_group: + kfree(data); + exit: + return status; + +} + + +static int cs6436_54p_psu_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int status; + + if((client->addr == 0x52) ||(client->addr == 0x53)) + { + status = psu_eeprom_probe(client, id); + } + else if((client->addr == 0x5a) ||(client->addr == 0x5b)) + { + status = psu_register_probe(client, id); + } + return status; +} + +static int cs6436_54p_psu_remove(struct i2c_client *client) +{ + cs6436_54p_sysfs_remove_client(client); + + if((client->addr == 0x52) ||(client->addr == 0x53)) + { + struct cs6436_54p_psu_data *data; + data = i2c_get_clientdata(client); + psu_sysfs_eeprom_cleanup(&client->dev.kobj,data->bin); + kfree(data); + } + else if((client->addr == 0x5a) ||(client->addr == 0x5b)) + { + struct cs6436_54p_psu_data *data; + data = i2c_get_clientdata(client); + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &cs6436_54p_psu_group); + kfree(data); + } + + return 0; +} + +enum psu_index +{ + cs6436_54p_psu1, + cs6436_54p_psu2 +}; + +static const struct i2c_device_id cs6436_54p_psu_id[] = { + { "cs6436_54p_psu1", cs6436_54p_psu1 }, + { "cs6436_54p_psu2", cs6436_54p_psu2 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, cs6436_54p_psu_id); + +static struct i2c_driver cs6436_54p_psu_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "cs6436_54p_psu", + }, + .probe = cs6436_54p_psu_probe, + .remove = cs6436_54p_psu_remove, + .id_table = cs6436_54p_psu_id, + .address_list = normal_i2c, +}; + +module_i2c_driver(cs6436_54p_psu_driver); + +MODULE_AUTHOR("Zhang Peng "); +MODULE_DESCRIPTION("cs6436_54p_psu driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-sfp.c b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-sfp.c new file mode 100644 index 000000000000..5d02bd849a5f --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-sfp.c @@ -0,0 +1,1713 @@ +/* + * A hwmon driver for the CIG cs6436-54P SFP Module + * + * Copyright (C) 2018 Cambridge, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 "i2c-algo-lpc.h" + +#define DRIVER_NAME "cs6436_54p_sfp" /* Platform dependent */ + +#define DEBUG_MODE 0 + +#if (DEBUG_MODE == 1) + #define DEBUG_PRINT(fmt, args...) \ + printk (KERN_INFO "%s:%s[%d]: " fmt "\r\n", __FILE__, __FUNCTION__, __LINE__, ##args) +#else + #define DEBUG_PRINT(fmt, args...) +#endif + +#define EEPROM_NAME "sfp_eeprom" +#define EEPROM_SIZE 256 /* 256 byte eeprom */ +#define BIT_INDEX(i) (1ULL << (i)) +#define USE_I2C_BLOCK_READ 1 /* Platform dependent */ +#define I2C_RW_RETRY_COUNT 3 +#define I2C_RW_RETRY_INTERVAL 100 /* ms */ + +#define SFP_EEPROM_A0_I2C_ADDR (0xA0 >> 1) +#define SFP_EEPROM_A2_I2C_ADDR (0xA2 >> 1) + +#define SFF8024_PHYSICAL_DEVICE_ID_ADDR 0x0 +#define SFF8024_DEVICE_ID_SFP 0x3 +#define SFF8024_DEVICE_ID_QSFP 0xC +#define SFF8024_DEVICE_ID_QSFP_PLUS 0xD +#define SFF8024_DEVICE_ID_QSFP28 0x11 + +#define SFF8472_DIAG_MON_TYPE_ADDR 92 +#define SFF8472_DIAG_MON_TYPE_DDM_MASK 0x40 +#define SFF8472_10G_ETH_COMPLIANCE_ADDR 0x3 +#define SFF8472_10G_BASE_MASK 0xF0 + +#define SFF8436_RX_LOS_ADDR 3 +#define SFF8436_TX_FAULT_ADDR 4 +#define SFF8436_TX_DISABLE_ADDR 86 +#define QSFP_RESET_ADDR 0x1b +#define QSFP_INTER_ADDR 0x1a +#define QSFP_LPMODE_ADDR 0x1c + +static ssize_t show_port_number(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_port_type(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t show_present(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t sfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t sfp_set_tx_disable(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t qsfp_set_tx_disable(struct device *dev, struct device_attribute *da, const char *buf, size_t count);; +static ssize_t sfp_show_ddm_implemented(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t sfp_eeprom_read(struct i2c_client *, u8, u8 *,int); +static ssize_t sfp_eeprom_write(struct i2c_client *, u8 , const char *,int); +extern int cig_cpld_read_register(u8 reg_off, u8 *val); +extern int cig_cpld_write_register(u8 reg_off, u8 val); + +static ssize_t qsfp_reset_read(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_reset_write(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t qsfp_inter_read(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_lpmode_read(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_lpmode_write(struct device *dev, struct device_attribute *da, const char *buf, size_t count); + +enum sfp_sysfs_attributes { + PRESENT, + PRESENT_ALL, + PORT_NUMBER, + PORT_TYPE, + DDM_IMPLEMENTED, + TX_FAULT, + TX_FAULT1, + TX_FAULT2, + TX_FAULT3, + TX_FAULT4, + TX_DISABLE, + TX_DISABLE1, + TX_DISABLE2, + TX_DISABLE3, + TX_DISABLE4, + RX_LOS, + RX_LOS1, + RX_LOS2, + RX_LOS3, + RX_LOS4, + RX_LOS_ALL, + QSFPRESET, + QSFPINT, + QSFPLPMODE +}; + +/* SFP/QSFP common attributes for sysfs */ +static SENSOR_DEVICE_ATTR(sfp_port_number, S_IRUGO, show_port_number, NULL, PORT_NUMBER); +static SENSOR_DEVICE_ATTR(sfp_port_type, S_IRUGO, show_port_type, NULL, PORT_TYPE); +static SENSOR_DEVICE_ATTR(sfp_is_present, S_IRUGO, show_present, NULL, PRESENT); +static SENSOR_DEVICE_ATTR(sfp_is_present_all, S_IRUGO, show_present, NULL, PRESENT_ALL); +static SENSOR_DEVICE_ATTR(sfp_rx_los, S_IRUGO, sfp_show_tx_rx_status, NULL, RX_LOS); +static SENSOR_DEVICE_ATTR(sfp_tx_disable, S_IWUSR | S_IRUGO, sfp_show_tx_rx_status, sfp_set_tx_disable, TX_DISABLE); +static SENSOR_DEVICE_ATTR(sfp_tx_fault, S_IRUGO, sfp_show_tx_rx_status, NULL, TX_FAULT); + +/* QSFP attributes for sysfs */ +static SENSOR_DEVICE_ATTR(sfp_rx_los1, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS1); +static SENSOR_DEVICE_ATTR(sfp_rx_los2, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS2); +static SENSOR_DEVICE_ATTR(sfp_rx_los3, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS3); +static SENSOR_DEVICE_ATTR(sfp_rx_los4, S_IRUGO, qsfp_show_tx_rx_status, NULL, RX_LOS4); +static SENSOR_DEVICE_ATTR(sfp_tx_disable1, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE1); +static SENSOR_DEVICE_ATTR(sfp_tx_disable2, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE2); +static SENSOR_DEVICE_ATTR(sfp_tx_disable3, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE3); +static SENSOR_DEVICE_ATTR(sfp_tx_disable4, S_IWUSR | S_IRUGO, qsfp_show_tx_rx_status, qsfp_set_tx_disable, TX_DISABLE4); +static SENSOR_DEVICE_ATTR(sfp_tx_fault1, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT1); +static SENSOR_DEVICE_ATTR(sfp_tx_fault2, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT2); +static SENSOR_DEVICE_ATTR(sfp_tx_fault3, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT3); +static SENSOR_DEVICE_ATTR(sfp_tx_fault4, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT4); +static SENSOR_DEVICE_ATTR(sfp_reset, S_IWUSR | S_IRUGO, qsfp_reset_read, qsfp_reset_write, QSFPRESET); +static SENSOR_DEVICE_ATTR(sfp_inter, S_IRUGO, qsfp_inter_read, NULL, QSFPINT); +static SENSOR_DEVICE_ATTR(sfp_lpmode, S_IWUSR | S_IRUGO, qsfp_lpmode_read, qsfp_lpmode_write, QSFPLPMODE); +static struct attribute *qsfp_attributes[] = { + &sensor_dev_attr_sfp_port_number.dev_attr.attr, + &sensor_dev_attr_sfp_port_type.dev_attr.attr, + &sensor_dev_attr_sfp_is_present.dev_attr.attr, + &sensor_dev_attr_sfp_is_present_all.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los1.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los2.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los3.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los4.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable1.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable2.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable3.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable4.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault1.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault2.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault3.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault4.dev_attr.attr, + &sensor_dev_attr_sfp_reset.dev_attr.attr, + &sensor_dev_attr_sfp_inter.dev_attr.attr, + &sensor_dev_attr_sfp_lpmode.dev_attr.attr, + NULL +}; + +/* SFP msa attributes for sysfs */ +static SENSOR_DEVICE_ATTR(sfp_ddm_implemented, S_IRUGO, sfp_show_ddm_implemented, NULL, DDM_IMPLEMENTED); +static SENSOR_DEVICE_ATTR(sfp_rx_los_all, S_IRUGO, sfp_show_tx_rx_status, NULL, RX_LOS_ALL); +static struct attribute *sfp_msa_attributes[] = { + &sensor_dev_attr_sfp_port_number.dev_attr.attr, + &sensor_dev_attr_sfp_port_type.dev_attr.attr, + &sensor_dev_attr_sfp_is_present.dev_attr.attr, + &sensor_dev_attr_sfp_is_present_all.dev_attr.attr, + &sensor_dev_attr_sfp_ddm_implemented.dev_attr.attr, + &sensor_dev_attr_sfp_tx_fault.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los.dev_attr.attr, + &sensor_dev_attr_sfp_rx_los_all.dev_attr.attr, + &sensor_dev_attr_sfp_tx_disable.dev_attr.attr, + NULL +}; + +/* SFP ddm attributes for sysfs */ +static struct attribute *sfp_ddm_attributes[] = { + NULL +}; + +/* Platform dependent +++ */ +#define CPLD_PORT_TO_FRONT_PORT(port) (port+1) + +enum port_numbers { +cs6436_54p_sfp1, cs6436_54p_sfp2, cs6436_54p_sfp3, cs6436_54p_sfp4, +cs6436_54p_sfp5, cs6436_54p_sfp6, cs6436_54p_sfp7, cs6436_54p_sfp8, +cs6436_54p_sfp9, cs6436_54p_sfp10, cs6436_54p_sfp11, cs6436_54p_sfp12, +cs6436_54p_sfp13, cs6436_54p_sfp14, cs6436_54p_sfp15, cs6436_54p_sfp16, +cs6436_54p_sfp17, cs6436_54p_sfp18, cs6436_54p_sfp19, cs6436_54p_sfp20, +cs6436_54p_sfp21, cs6436_54p_sfp22, cs6436_54p_sfp23, cs6436_54p_sfp24, +cs6436_54p_sfp25, cs6436_54p_sfp26, cs6436_54p_sfp27, cs6436_54p_sfp28, +cs6436_54p_sfp29, cs6436_54p_sfp30, cs6436_54p_sfp31, cs6436_54p_sfp32, +cs6436_54p_sfp33, cs6436_54p_sfp34, cs6436_54p_sfp35, cs6436_54p_sfp36, +cs6436_54p_sfp37, cs6436_54p_sfp38, cs6436_54p_sfp39, cs6436_54p_sfp40, +cs6436_54p_sfp41, cs6436_54p_sfp42, cs6436_54p_sfp43, cs6436_54p_sfp44, +cs6436_54p_sfp45, cs6436_54p_sfp46, cs6436_54p_sfp47, cs6436_54p_sfp48, +cs6436_54p_sfp49, cs6436_54p_sfp50, cs6436_54p_sfp51, cs6436_54p_sfp52, +cs6436_54p_sfp53, cs6436_54p_sfp54, cs6436_54p_sfp55, cs6436_54p_sfp56 +}; + +#define I2C_DEV_ID(x) { #x, x} + +static const struct i2c_device_id sfp_device_id[] = { +I2C_DEV_ID(cs6436_54p_sfp1), +I2C_DEV_ID(cs6436_54p_sfp2), +I2C_DEV_ID(cs6436_54p_sfp3), +I2C_DEV_ID(cs6436_54p_sfp4), +I2C_DEV_ID(cs6436_54p_sfp5), +I2C_DEV_ID(cs6436_54p_sfp6), +I2C_DEV_ID(cs6436_54p_sfp7), +I2C_DEV_ID(cs6436_54p_sfp8), +I2C_DEV_ID(cs6436_54p_sfp9), +I2C_DEV_ID(cs6436_54p_sfp10), +I2C_DEV_ID(cs6436_54p_sfp11), +I2C_DEV_ID(cs6436_54p_sfp12), +I2C_DEV_ID(cs6436_54p_sfp13), +I2C_DEV_ID(cs6436_54p_sfp14), +I2C_DEV_ID(cs6436_54p_sfp15), +I2C_DEV_ID(cs6436_54p_sfp16), +I2C_DEV_ID(cs6436_54p_sfp17), +I2C_DEV_ID(cs6436_54p_sfp18), +I2C_DEV_ID(cs6436_54p_sfp19), +I2C_DEV_ID(cs6436_54p_sfp20), +I2C_DEV_ID(cs6436_54p_sfp21), +I2C_DEV_ID(cs6436_54p_sfp22), +I2C_DEV_ID(cs6436_54p_sfp23), +I2C_DEV_ID(cs6436_54p_sfp24), +I2C_DEV_ID(cs6436_54p_sfp25), +I2C_DEV_ID(cs6436_54p_sfp26), +I2C_DEV_ID(cs6436_54p_sfp27), +I2C_DEV_ID(cs6436_54p_sfp28), +I2C_DEV_ID(cs6436_54p_sfp29), +I2C_DEV_ID(cs6436_54p_sfp30), +I2C_DEV_ID(cs6436_54p_sfp31), +I2C_DEV_ID(cs6436_54p_sfp32), +I2C_DEV_ID(cs6436_54p_sfp33), +I2C_DEV_ID(cs6436_54p_sfp34), +I2C_DEV_ID(cs6436_54p_sfp35), +I2C_DEV_ID(cs6436_54p_sfp36), +I2C_DEV_ID(cs6436_54p_sfp37), +I2C_DEV_ID(cs6436_54p_sfp38), +I2C_DEV_ID(cs6436_54p_sfp39), +I2C_DEV_ID(cs6436_54p_sfp40), +I2C_DEV_ID(cs6436_54p_sfp41), +I2C_DEV_ID(cs6436_54p_sfp42), +I2C_DEV_ID(cs6436_54p_sfp43), +I2C_DEV_ID(cs6436_54p_sfp44), +I2C_DEV_ID(cs6436_54p_sfp45), +I2C_DEV_ID(cs6436_54p_sfp46), +I2C_DEV_ID(cs6436_54p_sfp47), +I2C_DEV_ID(cs6436_54p_sfp48), +I2C_DEV_ID(cs6436_54p_sfp49), +I2C_DEV_ID(cs6436_54p_sfp50), +I2C_DEV_ID(cs6436_54p_sfp51), +I2C_DEV_ID(cs6436_54p_sfp52), +I2C_DEV_ID(cs6436_54p_sfp53), +I2C_DEV_ID(cs6436_54p_sfp54), +I2C_DEV_ID(cs6436_54p_sfp55), +I2C_DEV_ID(cs6436_54p_sfp56), +{ /* LIST END */ } +}; +MODULE_DEVICE_TABLE(i2c, sfp_device_id); + +/* + * list of valid port types + * note OOM_PORT_TYPE_NOT_PRESENT to indicate no + * module is present in this port + */ +typedef enum oom_driver_port_type_e { + OOM_DRIVER_PORT_TYPE_INVALID, + OOM_DRIVER_PORT_TYPE_NOT_PRESENT, + OOM_DRIVER_PORT_TYPE_SFP, + OOM_DRIVER_PORT_TYPE_SFP_PLUS, + OOM_DRIVER_PORT_TYPE_QSFP, + OOM_DRIVER_PORT_TYPE_QSFP_PLUS, + OOM_DRIVER_PORT_TYPE_QSFP28 +} oom_driver_port_type_t; + +enum driver_type_e { + DRIVER_TYPE_SFP_MSA, + DRIVER_TYPE_SFP_DDM, + DRIVER_TYPE_QSFP +}; + +/* Each client has this additional data + */ +struct eeprom_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + struct bin_attribute bin; /* eeprom data */ +}; + +struct sfp_msa_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u64 status[6]; /* bit0:port0, bit1:port1 and so on */ + /* index 0 => tx_fail + 1 => tx_disable + 2 => rx_loss + 3 => device id + 4 => 10G Ethernet Compliance Codes + to distinguish SFP or SFP+ + 5 => DIAGNOSTIC MONITORING TYPE */ + struct eeprom_data eeprom; +}; + +struct sfp_ddm_data { + struct eeprom_data eeprom; +}; + +struct qsfp_data { + char valid; /* !=0 if registers are valid */ + unsigned long last_updated; /* In jiffies */ + u8 status[3]; /* bit0:port0, bit1:port1 and so on */ + /* index 0 => tx_fail + 1 => tx_disable + 2 => rx_loss */ + + u8 device_id; + struct eeprom_data eeprom; +}; + +struct sfp_port_data { + struct mutex update_lock; + enum driver_type_e driver_type; + int port; /* CPLD port index */ + oom_driver_port_type_t port_type; + u64 present; /* present status, bit0:port0, bit1:port1 and so on */ + + struct sfp_msa_data *msa; + struct sfp_ddm_data *ddm; + struct qsfp_data *qsfp; + + struct i2c_client *client; +}; + +static ssize_t show_port_number(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + return sprintf(buf, "%d\n", CPLD_PORT_TO_FRONT_PORT(data->port)); +} + + + +static int cig_cpld_write_sfp_register(u8 sfp_reg_addr, u8 sfp_write_reg_data) +{ + u8 sfp_read_status = 0; + u8 wait_time_out = WAIT_TIME_OUT_COUNT; + + cig_cpld_write_register(ADDR_REG_SFP_STATUS_ADDR, sfp_reg_addr << 1); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_TX, sfp_write_reg_data); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_COMMAND, 0x80); + do{ + cig_cpld_read_register(ADDR_REG_SFP_STATUS_STATUS, &sfp_read_status); + udelay(60); + wait_time_out--; + if(wait_time_out == 0) + break; + }while(sfp_read_status != 0x02); + + if(wait_time_out == 0) + return -1; + + return 1; +} + + +static int cig_cpld_read_sfp_register(u8 sfp_reg_addr, u8 *sfp_read_reg_data) +{ + u8 sfp_read_status = 0; + u8 wait_time_out = WAIT_TIME_OUT_COUNT; + + cig_cpld_write_register(ADDR_REG_SFP_STATUS_ADDR, sfp_reg_addr << 1 | 1); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_COMMAND, 0x80); + do{ + udelay(60); + cig_cpld_read_register(ADDR_REG_SFP_STATUS_STATUS, &sfp_read_status); + wait_time_out--; + if(wait_time_out == 0) + break; + }while(sfp_read_status != 0x01); + + cig_cpld_read_register(ADDR_REG_SFP_STATUS_RX,sfp_read_reg_data); + + if(wait_time_out == 0) + return -1; + + return 1; +} + + + + + + +/* Platform dependent +++ */ +static struct sfp_port_data *sfp_update_present(struct i2c_client *client) +{ + int i = 0, j = 0, status = -1; + unsigned char cpld_reg_data = 0,cpld_reg_addr = 0; + struct sfp_port_data *data = i2c_get_clientdata(client); + + DEBUG_PRINT("Starting sfp present status update"); + mutex_lock(&data->update_lock); + data->present = 0; + + udelay(6000); + + /* Read present status of port 1~48(SFP port) */ + for (i = 0; i < 6; i++) { + cpld_reg_addr = 1 + i; + + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); + + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status); + goto exit; + } + + data->present |= (u64)cpld_reg_data << (i*8); + + DEBUG_PRINT("Present status = 0x%lx\r\n", data->present); + } + + /* Read present status of port 49-56(QSFP port) */ + cpld_reg_addr = 25; + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status); + goto exit; + } + else { + data->present |= (u64)cpld_reg_data << 48; + } + + DEBUG_PRINT("Present status = 0x%lx", data->present); +exit: + mutex_unlock(&data->update_lock); + return (status < 0) ? ERR_PTR(status) : data; +} + +static struct sfp_port_data *sfp_update_tx_rx_status(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + int i = 0, j = 0; + int status = -1; + unsigned char cpld_reg_data = 0,cpld_reg_addr = 0; + + if (time_before(jiffies, data->msa->last_updated + HZ + HZ / 2) && data->msa->valid) { + return data; + } + + DEBUG_PRINT("Starting cs6436_54p sfp tx rx status update"); + mutex_lock(&data->update_lock); + data->msa->valid = 0; + memset(data->msa->status, 0, sizeof(data->msa->status)); + + udelay(6000); + + /* Read status of port 1~48(SFP port) */ + for (i = 0; i < 6; i++) { + cpld_reg_addr = 13+i; + + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status); + goto exit; + } + + data->msa->status[0] |= (u64)cpld_reg_data << (i * 8); + + DEBUG_PRINT("tx rx status[0] = 0x%lx\r\n", data->msa->status[0]); + } + + + for (i = 0; i < 6; i++) { + cpld_reg_addr = 19+i; + + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status); + goto exit; + } + + data->msa->status[1] |= (u64)cpld_reg_data << (i * 8); + + DEBUG_PRINT("tx rx status[1] = 0x%lx\r\n", data->msa->status[1]); + } + + for (i = 0; i < 6; i++) { + cpld_reg_addr = 7+i; + + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status); + goto exit; + } + + data->msa->status[2] |= (u64)cpld_reg_data << (i * 8); + + DEBUG_PRINT("tx rx status[2] = 0x%lx\r\n", data->msa->status[2]); + } + + data->msa->valid = 1; + data->msa->last_updated = jiffies; + +exit: + mutex_unlock(&data->update_lock); + return (status < 0) ? ERR_PTR(status) : data; +} + +static ssize_t sfp_set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + unsigned char cpld_reg_data = 0,cpld_reg_addr = 0,cpld_reg_bit = 0,cpld_reg_val = 0; + long disable; + int error; + + if (data->driver_type == DRIVER_TYPE_QSFP) { + return qsfp_set_tx_disable(dev, da, buf, count); + } + + error = kstrtol(buf, 10, &disable); + if (error) { + return error; + } + + mutex_lock(&data->update_lock); + + udelay(6000); + + if(data->port <= 48) { + cpld_reg_addr = 19 + data->port / 8; + cpld_reg_bit = 1 << ((data->port) % 8); + } + + /* Read current status */ + error = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); + + /* Update tx_disable status */ + if (disable) { + data->msa->status[1] |= BIT_INDEX(data->port); + cpld_reg_data |= cpld_reg_bit; + } + else { + data->msa->status[1] &= ~ BIT_INDEX(data->port); + cpld_reg_data &= ~cpld_reg_bit; + } + + error = cig_cpld_write_sfp_register(cpld_reg_addr,cpld_reg_data); + + mutex_unlock(&data->update_lock); + return count; +} +/* Platform dependent --- */ + +static int sfp_is_port_present(struct i2c_client *client, int port) +{ + struct sfp_port_data *data = i2c_get_clientdata(client); + + data = sfp_update_present(client); + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + return !(data->present & BIT_INDEX(data->port)); /* Platform dependent */ +} + +/* Platform dependent +++ */ +static ssize_t show_present(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + + if (PRESENT_ALL == attr->index) { + int i; + u8 values[7] = {0}; + struct sfp_port_data *data = sfp_update_present(client); + + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + for (i = 0; i < ARRAY_SIZE(values); i++) { + values[i] = ~(u8)(data->present >> (i * 8)); + } + + /* Return values 1 -> 56 in order */ + return sprintf(buf, "%.2x %.2x %.2x %.2x %.2x %.2x %.2x\n", + values[0], values[1], values[2], + values[3], values[4], values[5], + values[6]); + } + else { + struct sfp_port_data *data = i2c_get_clientdata(client); + int present = sfp_is_port_present(client, data->port); + + if (IS_ERR_VALUE(present)) { + return present; + } + + /* PRESENT */ + return sprintf(buf, "%d\n", present); + } +} +/* Platform dependent --- */ + +static struct sfp_port_data *sfp_update_port_type(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + u8 buf = 0; + int status; + + mutex_lock(&data->update_lock); + + switch (data->driver_type) { + case DRIVER_TYPE_SFP_MSA: + { + status = sfp_eeprom_read(client, SFF8024_PHYSICAL_DEVICE_ID_ADDR, &buf, sizeof(buf)); + if (unlikely(status < 0)) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + if (buf != SFF8024_DEVICE_ID_SFP) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + status = sfp_eeprom_read(client, SFF8472_10G_ETH_COMPLIANCE_ADDR, &buf, sizeof(buf)); + if (unlikely(status < 0)) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + DEBUG_PRINT("sfp port type (0x3) data = (0x%x)", buf); + data->port_type = buf & SFF8472_10G_BASE_MASK ? OOM_DRIVER_PORT_TYPE_SFP_PLUS : OOM_DRIVER_PORT_TYPE_SFP; + break; + } + case DRIVER_TYPE_QSFP: + { + status = sfp_eeprom_read(client, SFF8024_PHYSICAL_DEVICE_ID_ADDR, &buf, sizeof(buf)); + if (unlikely(status < 0)) { + data->port_type = OOM_DRIVER_PORT_TYPE_INVALID; + break; + } + + DEBUG_PRINT("qsfp port type (0x0) buf = (0x%x)", buf); + switch (buf) { + case SFF8024_DEVICE_ID_QSFP: + data->port_type = OOM_DRIVER_PORT_TYPE_QSFP; + break; + case SFF8024_DEVICE_ID_QSFP_PLUS: + data->port_type = OOM_DRIVER_PORT_TYPE_QSFP_PLUS; + break; + case SFF8024_DEVICE_ID_QSFP28: + data->port_type = OOM_DRIVER_PORT_TYPE_QSFP_PLUS; + break; + default: + data->port_type = buf; + break; + } + + break; + } + default: + break; + } + + mutex_unlock(&data->update_lock); + return data; +} + +static ssize_t show_port_type(struct device *dev, struct device_attribute *da, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + int present = sfp_is_port_present(client, data->port); + + if (IS_ERR_VALUE(present)) { + return present; + } + + if (!present) { + /* port is not present */ + return sprintf(buf, "%d\n", OOM_DRIVER_PORT_TYPE_NOT_PRESENT); + } + + sfp_update_port_type(dev); + return sprintf(buf, "%d\n", data->port_type); +} + +static struct sfp_port_data *qsfp_update_tx_rx_status(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + int i, status = -1; + u8 buf = 0; + u8 reg[] = {SFF8436_TX_FAULT_ADDR, SFF8436_TX_DISABLE_ADDR, SFF8436_RX_LOS_ADDR}; + + DEBUG_PRINT(""); + if (time_before(jiffies, data->qsfp->last_updated + HZ + HZ / 2) && data->qsfp->valid) { + return data; + } + + DEBUG_PRINT("Starting sfp tx rx status update"); + mutex_lock(&data->update_lock); + data->qsfp->valid = 0; + memset(data->qsfp->status, 0, sizeof(data->qsfp->status)); + + DEBUG_PRINT(""); + /* Notify device to update tx fault/ tx disable/ rx los status */ + for (i = 0; i < ARRAY_SIZE(reg); i++) { + status = sfp_eeprom_read(client, reg[i], &buf, sizeof(buf)); + if (unlikely(status < 0)) { + DEBUG_PRINT(""); + goto exit; + } + } + msleep(200); + DEBUG_PRINT(""); + + /* Read actual tx fault/ tx disable/ rx los status */ + for (i = 0; i < ARRAY_SIZE(reg); i++) { + status = sfp_eeprom_read(client, reg[i], &buf, sizeof(buf)); + if (unlikely(status < 0)) { + DEBUG_PRINT(""); + goto exit; + } + + DEBUG_PRINT("qsfp reg(0x%x) status = (0x%x)", reg[i], data->qsfp->status[i]); + data->qsfp->status[i] = (buf & 0xF); + } + + DEBUG_PRINT(""); + data->qsfp->valid = 1; + data->qsfp->last_updated = jiffies; + +exit: + DEBUG_PRINT(""); + mutex_unlock(&data->update_lock); + return (status < 0) ? ERR_PTR(status) : data; +} + +static ssize_t qsfp_inter_read(struct device *dev, struct device_attribute *da, char *buf) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_INTER_ADDR, &cpld_reg_data); + index = data->port - 48; + index = 1 << index; + val = (cpld_reg_data & index) > 0 ? 1 : 0; + + printk("inter read:data->port = %d, index = %hhu, cpld_reg_data = %hhu\n", data->port, index, cpld_reg_data); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", val); +} + + +static ssize_t qsfp_reset_read(struct device *dev, struct device_attribute *da, char *buf) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_RESET_ADDR, &cpld_reg_data); + index = data->port - 48; + index = 1 << index; + val = (cpld_reg_data & index) > 0 ? 1 : 0; + + printk("reset read:data->port = %d, index = %hhu, cpld_reg_data = %hhu\n", data->port, index, cpld_reg_data); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", val); +} + +static ssize_t qsfp_reset_write(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + long usrdata; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + ret = kstrtol(buf, 10, &usrdata); + if (ret) { + return ret; + } + + usrdata = usrdata > 0 ? 1 : 0; + index = data->port - 48; + + DEBUG_PRINT("usrdata = %u, index = %hhu\n", usrdata, index); + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_RESET_ADDR, &cpld_reg_data); + if (ret == 1) + { + + DEBUG_PRINT("cpld_reg_data = %x\n", cpld_reg_data); + cpld_reg_data &= ~(1 << index); + cpld_reg_data |= usrdata << index; + + DEBUG_PRINT("cpld_reg_data = %x\n", cpld_reg_data); + ret = cig_cpld_write_sfp_register(QSFP_RESET_ADDR, cpld_reg_data); + if (1 != ret) + { + DEBUG_PRINT("write failed\n"); + } + } + else + { + DEBUG_PRINT("read failed\n"); + } + + mutex_unlock(&data->update_lock); + + if (ret != 1) + return -1; + + return count; +} + + + + +static ssize_t qsfp_lpmode_read(struct device *dev, struct device_attribute *da, char *buf) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_LPMODE_ADDR, &cpld_reg_data); + index = data->port - 48; + index = 1 << index; + val = (cpld_reg_data & index) > 0 ? 1 : 0; + + printk("lpmode read:data->port = %d, index = %hhu, cpld_reg_data = %hhu\n", data->port, index, cpld_reg_data); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", val); +} + +static ssize_t qsfp_lpmode_write(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + long usrdata; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + ret = kstrtol(buf, 10, &usrdata); + if (ret) { + return ret; + } + + usrdata = usrdata > 0 ? 1 : 0; + index = data->port - 48; + + DEBUG_PRINT("usrdata = %u, index = %hhu\n", usrdata, index); + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_LPMODE_ADDR, &cpld_reg_data); + if (ret == 1) + { + + DEBUG_PRINT("cpld_reg_data = %x\n", cpld_reg_data); + cpld_reg_data &= ~(1 << index); + cpld_reg_data |= usrdata << index; + + DEBUG_PRINT("cpld_reg_data = %x\n", cpld_reg_data); + ret = cig_cpld_write_sfp_register(QSFP_LPMODE_ADDR, cpld_reg_data); + if (1 != ret) + { + DEBUG_PRINT("write failed\n"); + } + } + else + { + DEBUG_PRINT("read failed\n"); + } + + mutex_unlock(&data->update_lock); + + if (ret != 1) + return -1; + + return count; +} + + + +static ssize_t qsfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + int present; + u8 val = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + DEBUG_PRINT(""); + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + DEBUG_PRINT(""); + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + DEBUG_PRINT(""); + data = qsfp_update_tx_rx_status(dev); + DEBUG_PRINT(""); + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + DEBUG_PRINT(""); + switch (attr->index) { + case TX_FAULT: + val = !!(data->qsfp->status[2] & 0xF); + break; + case TX_FAULT1: + case TX_FAULT2: + case TX_FAULT3: + case TX_FAULT4: + val = !!(data->qsfp->status[2] & BIT_INDEX(attr->index - TX_FAULT1)); + break; + case TX_DISABLE: + val = data->qsfp->status[1] & 0xF; + break; + case TX_DISABLE1: + case TX_DISABLE2: + case TX_DISABLE3: + case TX_DISABLE4: + val = !!(data->qsfp->status[1] & BIT_INDEX(attr->index - TX_DISABLE1)); + break; + case RX_LOS: + val = !!(data->qsfp->status[0] & 0xF); + break; + case RX_LOS1: + case RX_LOS2: + case RX_LOS3: + case RX_LOS4: + val = !!(data->qsfp->status[0] & BIT_INDEX(attr->index - RX_LOS1)); + break; + default: + break; + } + + DEBUG_PRINT(""); + return sprintf(buf, "%d\n", val); +} + +static ssize_t qsfp_set_tx_disable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + long disable; + int status; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + status = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(status)) { + return status; + } + + if (!status) { + /* port is not present */ + return -ENXIO; + } + + status = kstrtol(buf, 10, &disable); + if (status) { + return status; + } + + data = qsfp_update_tx_rx_status(dev); + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + mutex_lock(&data->update_lock); + + if (attr->index == TX_DISABLE) { + data->qsfp->status[1] = disable & 0xF; + } + else {/* TX_DISABLE1 ~ TX_DISABLE4*/ + if (disable) { + data->qsfp->status[1] |= (1 << (attr->index - TX_DISABLE1)); + } + else { + data->qsfp->status[1] &= ~(1 << (attr->index - TX_DISABLE1)); + } + } + + DEBUG_PRINT("index = (%d), status = (0x%x)", attr->index, data->qsfp->status[1]); + status = sfp_eeprom_write(data->client, SFF8436_TX_DISABLE_ADDR, &data->qsfp->status[1], sizeof(data->qsfp->status[1])); + if (unlikely(status < 0)) { + count = status; + } + + mutex_unlock(&data->update_lock); + return count; +} + +static ssize_t sfp_show_ddm_implemented(struct device *dev, struct device_attribute *da, + char *buf) +{ + int status; + char ddm; + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + status = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(status)) { + return status; + } + + if (status == 0) { + /* port is not present */ + return -ENODEV; + } + + status = sfp_eeprom_read(client, SFF8472_DIAG_MON_TYPE_ADDR, &ddm, sizeof(ddm)); + if (unlikely(status < 0)) { + return status; + } + + return sprintf(buf, "%d\n", !!(ddm & SFF8472_DIAG_MON_TYPE_DDM_MASK)); +} + +/* Platform dependent +++ */ +static ssize_t sfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, + char *buf) +{ + u8 val = 0, index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + DEBUG_PRINT("driver type = (%d)", data->driver_type); + if (data->driver_type == DRIVER_TYPE_QSFP) { + DEBUG_PRINT(""); + return qsfp_show_tx_rx_status(dev, da, buf); + } + + DEBUG_PRINT(""); + data = sfp_update_tx_rx_status(dev); + if (IS_ERR(data)) { + return PTR_ERR(data); + } + + if(attr->index == RX_LOS_ALL) { + int i = 0; + u8 values[6] = {0}; + + for (i = 0; i < ARRAY_SIZE(values); i++) { + values[i] = (u8)(data->msa->status[2] >> (i * 8)); + } + + /** Return values 1 -> 48 in order */ + return sprintf(buf, "%.2x %.2x %.2x %.2x %.2x %.2x\n", + values[0], values[1], values[2], + values[3], values[4], values[5]); + } + + switch (attr->index) { + case TX_FAULT: + index = 0; + break; + case TX_DISABLE: + index = 1; + break; + case RX_LOS: + index = 2; + break; + default: + break; + } + + val = !!(data->msa->status[index] & BIT_INDEX(data->port)); + return sprintf(buf, "%d\n", val); +} +/* Platform dependent --- */ +static ssize_t sfp_eeprom_write(struct i2c_client *client, u8 command, const char *data, + int data_len) +{ +#if USE_I2C_BLOCK_READ + int status, retry = I2C_RW_RETRY_COUNT; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + status = i2c_smbus_write_i2c_block_data(client, command, data_len, data); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + return status; + } + + return data_len; +#else + int status, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_write_byte_data(client, command, *data); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + return status; + } + + return 1; +#endif + + +} + +static ssize_t sfp_port_write(struct sfp_port_data *data, + const char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + return count; + } + + /* + * Write data to chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&data->update_lock); + + while (count) { + ssize_t status; + + status = sfp_eeprom_write(data->client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + buf += status; + off += status; + count -= status; + retval += status; + } + + mutex_unlock(&data->update_lock); + return retval; +} + + +static ssize_t sfp_bin_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + int present; + struct sfp_port_data *data; + DEBUG_PRINT("%s(%d) offset = (%d), count = (%d)", off, count); + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + + present = sfp_is_port_present(data->client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + return sfp_port_write(data, buf, off, count); +} + +static ssize_t sfp_eeprom_read(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ +#if USE_I2C_BLOCK_READ + int status, retry = I2C_RW_RETRY_COUNT; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + status = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + goto abort; + } + if (unlikely(status != data_len)) { + status = -EIO; + goto abort; + } + + //result = data_len; + +abort: + return status; +#else + int status, retry = I2C_RW_RETRY_COUNT; + + while (retry) { + status = i2c_smbus_read_byte_data(client, command); + if (unlikely(status < 0)) { + msleep(I2C_RW_RETRY_INTERVAL); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + dev_dbg(&client->dev, "sfp read byte data failed, command(0x%2x), data(0x%2x)\r\n", command, status); + goto abort; + } + + *data = (u8)status; + status = 1; + +abort: + return status; +#endif +} + +static ssize_t sfp_port_read(struct sfp_port_data *data, + char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + DEBUG_PRINT("Count = 0, return"); + return count; + } + + /* + * Read data from chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&data->update_lock); + + while (count) { + ssize_t status; + + status = sfp_eeprom_read(data->client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + + buf += status; + off += status; + count -= status; + retval += status; + } + + mutex_unlock(&data->update_lock); + return retval; + +} + +static ssize_t sfp_bin_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + int present; + struct sfp_port_data *data; + DEBUG_PRINT("offset = (%d), count = (%d)", off, count); + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + + present = sfp_is_port_present(data->client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + return sfp_port_read(data, buf, off, count); +} + +static int sfp_sysfs_eeprom_init(struct kobject *kobj, struct bin_attribute *eeprom) +{ + int err; + + sysfs_bin_attr_init(eeprom); + eeprom->attr.name = EEPROM_NAME; + eeprom->attr.mode = S_IWUSR | S_IRUGO; + eeprom->read = sfp_bin_read; + eeprom->write = sfp_bin_write; + eeprom->size = EEPROM_SIZE; + + /* Create eeprom file */ + err = sysfs_create_bin_file(kobj, eeprom); + if (err) { + return err; + } + + return 0; +} + +static int sfp_sysfs_eeprom_cleanup(struct kobject *kobj, struct bin_attribute *eeprom) +{ + sysfs_remove_bin_file(kobj, eeprom); + return 0; +} + +static const struct attribute_group sfp_msa_group = { + .attrs = sfp_msa_attributes, +}; + +static int sfp_i2c_check_functionality(struct i2c_client *client) +{ +#if USE_I2C_BLOCK_READ + return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK); +#else + return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA); +#endif +} + +static int sfp_msa_probe(struct i2c_client *client, const struct i2c_device_id *dev_id, + struct sfp_msa_data **data) +{ + int status; + struct sfp_msa_data *msa; + + if (!sfp_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + msa = kzalloc(sizeof(struct sfp_msa_data), GFP_KERNEL); + if (!msa) { + status = -ENOMEM; + goto exit; + } + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &sfp_msa_group); + if (status) { + goto exit_free; + } + + /* init eeprom */ + status = sfp_sysfs_eeprom_init(&client->dev.kobj, &msa->eeprom.bin); + if (status) { + goto exit_remove; + } + + *data = msa; + dev_info(&client->dev, "sfp msa '%s'\n", client->name); + + cs6436_54p_sysfs_add_client(client); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &sfp_msa_group); +exit_free: + kfree(msa); +exit: + + return status; +} + +static const struct attribute_group sfp_ddm_group = { + .attrs = sfp_ddm_attributes, +}; + +static int sfp_ddm_probe(struct i2c_client *client, const struct i2c_device_id *dev_id, + struct sfp_ddm_data **data) +{ + int status; + struct sfp_ddm_data *ddm; + + if (!sfp_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + ddm = kzalloc(sizeof(struct sfp_ddm_data), GFP_KERNEL); + if (!ddm) { + status = -ENOMEM; + goto exit; + } + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &sfp_ddm_group); + if (status) { + goto exit_free; + } + + /* init eeprom */ + status = sfp_sysfs_eeprom_init(&client->dev.kobj, &ddm->eeprom.bin); + if (status) { + goto exit_remove; + } + + *data = ddm; + dev_info(&client->dev, "sfp ddm '%s'\n", client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &sfp_ddm_group); +exit_free: + kfree(ddm); +exit: + + return status; +} + +static const struct attribute_group qsfp_group = { + .attrs = qsfp_attributes, +}; + +static int qsfp_probe(struct i2c_client *client, const struct i2c_device_id *dev_id, + struct qsfp_data **data) +{ + int status; + struct qsfp_data *qsfp; + + if (!sfp_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + qsfp = kzalloc(sizeof(struct qsfp_data), GFP_KERNEL); + if (!qsfp) { + status = -ENOMEM; + goto exit; + } + + /* Register sysfs hooks */ + status = sysfs_create_group(&client->dev.kobj, &qsfp_group); + if (status) { + goto exit_free; + } + + /* init eeprom */ + status = sfp_sysfs_eeprom_init(&client->dev.kobj, &qsfp->eeprom.bin); + if (status) { + goto exit_remove; + } + + /* Bring QSFPs out of reset */ + //cig_lpc_write(0x62, 0x15, 0x3F); + + *data = qsfp; + dev_info(&client->dev, "qsfp '%s'\n", client->name); + + return 0; + +exit_remove: + sysfs_remove_group(&client->dev.kobj, &qsfp_group); +exit_free: + kfree(qsfp); +exit: + + return status; +} + +/* Platform dependent +++ */ +static int sfp_device_probe(struct i2c_client *client, + const struct i2c_device_id *dev_id) +{ + struct sfp_port_data *data = NULL; + + data = kzalloc(sizeof(struct sfp_port_data), GFP_KERNEL); + if (!data) { + return -ENOMEM; + } + + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + data->port = dev_id->driver_data; + data->client = client; + + if (dev_id->driver_data >= cs6436_54p_sfp1 && dev_id->driver_data <= cs6436_54p_sfp48) { + if (client->addr == SFP_EEPROM_A0_I2C_ADDR) { + data->driver_type = DRIVER_TYPE_SFP_MSA; + return sfp_msa_probe(client, dev_id, &data->msa); + } + else if (client->addr == SFP_EEPROM_A2_I2C_ADDR) { + data->driver_type = DRIVER_TYPE_SFP_DDM; + return sfp_ddm_probe(client, dev_id, &data->ddm); + } + } + else { /* cs6436_54p_sfp49 ~ cs6436_54p_sfp56 */ + if (client->addr == SFP_EEPROM_A0_I2C_ADDR) { + data->driver_type = DRIVER_TYPE_QSFP; + return qsfp_probe(client, dev_id, &data->qsfp); + } + } + + return -ENODEV; +} +/* Platform dependent --- */ + +static int sfp_msa_remove(struct i2c_client *client, struct sfp_msa_data *data) +{ + sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin); + sysfs_remove_group(&client->dev.kobj, &sfp_msa_group); + kfree(data); + return 0; +} + +static int sfp_ddm_remove(struct i2c_client *client, struct sfp_ddm_data *data) +{ + sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin); + sysfs_remove_group(&client->dev.kobj, &sfp_ddm_group); + kfree(data); + return 0; +} + +static int qfp_remove(struct i2c_client *client, struct qsfp_data *data) +{ + sfp_sysfs_eeprom_cleanup(&client->dev.kobj, &data->eeprom.bin); + sysfs_remove_group(&client->dev.kobj, &qsfp_group); + kfree(data); + return 0; +} + +static int sfp_device_remove(struct i2c_client *client) +{ + struct sfp_port_data *data = i2c_get_clientdata(client); + + cs6436_54p_sysfs_remove_client(client); + switch (data->driver_type) { + case DRIVER_TYPE_SFP_MSA: + return sfp_msa_remove(client, data->msa); + case DRIVER_TYPE_SFP_DDM: + return sfp_ddm_remove(client, data->ddm); + case DRIVER_TYPE_QSFP: + return qfp_remove(client, data->qsfp); + } + + return 0; +} + +/* Addresses scanned + */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +static struct i2c_driver cs6436_54p_sfp_driver = { + .driver = { + .name = DRIVER_NAME, + }, + .probe = sfp_device_probe, + .remove = sfp_device_remove, + .id_table = sfp_device_id, + .address_list = normal_i2c, +}; + +module_i2c_driver(cs6436_54p_sfp_driver); + + +MODULE_AUTHOR("Zhang Peng "); +MODULE_DESCRIPTION("cs6436_54p_sfp driver"); +MODULE_LICENSE("GPL"); + diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-sysfs.c b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-sysfs.c new file mode 100644 index 000000000000..1383fcfd40f3 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/modules/x86-64-cig-cs6436-54p-sysfs.c @@ -0,0 +1,335 @@ +/* + * A hwmon driver for the CIG cs6436-54P sysfs Module + * + * Copyright (C) 2018 Cambridge, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 +#include +#include + +#include "i2c-algo-lpc.h" + + +static LIST_HEAD(sysfs_client_list); +static struct mutex list_lock; + +struct sysfs_client_node { + struct i2c_client *client; + struct list_head list; +}; + +#define DEVICE_NAME "cigfs" +static int dev_major; +static struct class *dev_class; +static struct cdev *dev_cdev; +static struct device *dev_device; +static struct class *psu_class; +static struct class *sfp_class; + + +void cs6436_54p_sysfs_add_client(struct i2c_client *client) +{ + struct sysfs_client_node *node = kzalloc(sizeof(struct sysfs_client_node), GFP_KERNEL); + + if (!node) { + dev_dbg(&client->dev, "Can't allocate sysfs_client_node (0x%x)\n", client->addr); + return; + } + node->client = client; + + mutex_lock(&list_lock); + list_add(&node->list, &sysfs_client_list); + mutex_unlock(&list_lock); +} + +EXPORT_SYMBOL(cs6436_54p_sysfs_add_client); + +void cs6436_54p_sysfs_remove_client(struct i2c_client *client) +{ + struct list_head *list_node = NULL; + struct sysfs_client_node *sysfs_node = NULL; + int found = 0; + + mutex_lock(&list_lock); + + list_for_each(list_node, &sysfs_client_list) + { + sysfs_node = list_entry(list_node, struct sysfs_client_node, list); + if (IS_ERR(sysfs_node)) + { + break; + } + if (sysfs_node->client == client) { + found = 1; + break; + } + } + if (found) { + list_del(list_node); + kfree(sysfs_node); + } + + mutex_unlock(&list_lock); +} + +EXPORT_SYMBOL(cs6436_54p_sysfs_remove_client); + +struct class * cs6436_54p_sysfs_create_symclass(char *cls_name) +{ + int rc = 0; + struct class *my_class; +/**************************************************************************************/ + my_class = class_create(THIS_MODULE,cls_name); + if (IS_ERR(my_class)) { + pr_err("failed to create my class\n"); + } + return my_class; + +/**************************************************************************************/ +} + +void cs6436_54p_sysfs_delete_symclass(struct class *my_class) +{ +/**************************************************************************************/ + + if (IS_ERR(my_class)) { + pr_err("Pointer is invaild\n"); + } + class_destroy(my_class); + +/**************************************************************************************/ +} + + + + + +int cs6436_54p_sysfs_create_symlink(struct class *my_class,char * driver_name,char *device_name) +{ + struct list_head *list_node = NULL; + struct sysfs_client_node *sysfs_node = NULL; + int ret = -EPERM; + int rc = 0; + + mutex_lock(&list_lock); + list_for_each(list_node, &sysfs_client_list) + { + sysfs_node = list_entry(list_node, struct sysfs_client_node, list); + if (!strcmp(sysfs_node->client->name,driver_name)) { + rc = sysfs_create_link(&my_class->p->subsys.kobj, &sysfs_node->client->dev.kobj,device_name); + if(rc) + { + pr_err("failed to create symlink %d\n",rc); + } + break; + } + } + mutex_unlock(&list_lock); + return ret; +} + + +int cs6436_54p_sysfs_delete_symlink(struct class *my_class,char * driver_name,char *device_name) +{ + struct list_head *list_node = NULL; + struct sysfs_client_node *sysfs_node = NULL; + int ret = -EPERM; + int rc = 0; + + mutex_lock(&list_lock); + list_for_each(list_node, &sysfs_client_list) + { + sysfs_node = list_entry(list_node, struct sysfs_client_node, list); + if (!strcmp(sysfs_node->client->name,driver_name)) { + sysfs_remove_link(&my_class->p->subsys.kobj,device_name); + break; + } + } + mutex_unlock(&list_lock); + return ret; +} + + +static int cs6436_54p_sysfs_open(struct inode *inode, struct file *file) +{ + return 0; +} + + + +static ssize_t cs6436_54p_sysfs_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos) +{ + char str[10],name[18],port[8]; + int ret; + int i; + memset(str, 0, sizeof(str)); + ret = copy_from_user(str, buf, count); + if (ret) + { + printk(KERN_ERR "copy_from_user fail\n"); + return -EINVAL; + } + + if(!strncmp(str,"start",5)) + { + psu_class = cs6436_54p_sysfs_create_symclass("psu"); + cs6436_54p_sysfs_create_symlink(psu_class,"cs6436_54p_psu1","psu1"); + cs6436_54p_sysfs_create_symlink(psu_class,"cs6436_54p_psu2","psu2"); + sfp_class = cs6436_54p_sysfs_create_symclass("swps"); + for(i = 1; i <= 48;i++) + { + memset(name,0xff,sizeof(name)); + memset(port,0xff,sizeof(port)); + snprintf(name,sizeof(name),"cs6436_54p_sfp%d",i); + snprintf(port,sizeof(port),"port%d",i); + cs6436_54p_sysfs_create_symlink(sfp_class,name,port); + } + } + else if(!strncmp(str,"stop",4)) + { + cs6436_54p_sysfs_delete_symlink(psu_class,"cs6436_54p_psu1","psu1"); + cs6436_54p_sysfs_delete_symlink(psu_class,"cs6436_54p_psu2","psu2"); + cs6436_54p_sysfs_delete_symclass(psu_class); + + for(i = 1; i <= 48;i++) + { + memset(name,0xff,sizeof(name)); + memset(port,0xff,sizeof(port)); + snprintf(name,sizeof(name),"cs6436_54p_sfp%d",i); + snprintf(port,sizeof(port),"port%d",i); + cs6436_54p_sysfs_delete_symlink(sfp_class,name,port); + } + cs6436_54p_sysfs_delete_symclass(sfp_class); + } + return count; +} + + +static struct file_operations cs6436_54p_sysfs_fops = { + .owner = THIS_MODULE, + .open = cs6436_54p_sysfs_open, + .write = cs6436_54p_sysfs_write, +}; + + +static int __init cs6436_54p_sysfs_init(void) +{ + int result = 0; + int err = 0; + dev_t dev = MKDEV(dev_major, 0); + + if (dev_major) + result = register_chrdev_region(dev, 1, DEVICE_NAME); + else { + result = alloc_chrdev_region(&dev, 0, 1, DEVICE_NAME); + dev_major = MAJOR(dev); + } + if (result < 0) + { + printk("unable to get major %d\n", dev_major); + err= -EINVAL; + } + printk("get major is %d\n", dev_major); + if (dev_major == 0) + dev_major = result; + + dev_cdev= kmalloc(sizeof(struct cdev), GFP_KERNEL); + if(IS_ERR(dev_cdev)) { + err= -ENOMEM; + } + + cdev_init(dev_cdev, &cs6436_54p_sysfs_fops); + dev_cdev->owner = THIS_MODULE; + dev_cdev->ops = &cs6436_54p_sysfs_fops; + err = cdev_add(dev_cdev, dev, 1); + if (err) + { + printk("error %d add fpga ", err); + goto err_malloc; + } + + dev_class = class_create(THIS_MODULE, DEVICE_NAME); + if (IS_ERR(dev_class)) + { + printk("Err:failed in creating class.\n"); + goto err_cdev_add; + } + + dev_device = device_create(dev_class, NULL, MKDEV(dev_major, 0), NULL, DEVICE_NAME); + if (IS_ERR(dev_device)) + { + printk("Err:failed in creating device.\n"); + goto err_class_crt; + } + + mutex_init(&list_lock); + + return err; + + err_class_crt: + cdev_del(dev_cdev); + err_cdev_add: + kfree(dev_cdev); + err_malloc: + unregister_chrdev_region(MKDEV(dev_major,0), 1); + + return err; + +} + +static void __exit cs6436_54p_sysfs_exit(void) +{ + cdev_del(dev_cdev); + printk("cdev_del ok\n"); + device_destroy(dev_class, MKDEV(dev_major, 0)); + + class_destroy(dev_class); + + if(dev_cdev != NULL) + kfree(dev_cdev); + + unregister_chrdev_region(MKDEV(dev_major, 0), 1); + printk("cs6436_54p_sysfs_exit...\r\n"); +} + + +MODULE_AUTHOR("Zhang Peng "); +MODULE_DESCRIPTION("cs6436-54p-sysfs driver"); +MODULE_LICENSE("GPL"); + +module_init(cs6436_54p_sysfs_init); +module_exit(cs6436_54p_sysfs_exit); + + diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/service/cs6436-platform-init.service b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/service/cs6436-platform-init.service new file mode 100644 index 000000000000..ad18c2c2703a --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/service/cs6436-platform-init.service @@ -0,0 +1,13 @@ +[Unit] +Description=Cig CS6436-54P Platform initialization service +Before=pmon.service +DefaultDependencies=no + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/cig_cs6436_util.py install +ExecStop=/usr/local/bin/cig_cs6436_util.py clean +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/service/cs6436-platform-misc.service b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/service/cs6436-platform-misc.service new file mode 100644 index 000000000000..33f99935cd95 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/service/cs6436-platform-misc.service @@ -0,0 +1,15 @@ +[Unit] +Description=Cig CS6436-54P Platform miscellaneous service +After=cs6436-platform-init.service +DefaultDependencies=no + +[Service] +ExecStart=/usr/local/bin/cig_cs6436_misc.py +KillSignal=SIGKILL +SuccessExitStatus=SIGKILL + +# Resource Limitations +LimitCORE=infinity + +[Install] +WantedBy=multi-user.target diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/setup.py b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/setup.py new file mode 100755 index 000000000000..05ee2c6e36ac --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/setup.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +import os +import sys +from setuptools import setup +os.listdir + +setup( + name='cs6436-54p', + version='1.0.0', + description='Module to initialize Cig CS6436-54P platforms', + + packages=['cs6436-54p'], + package_dir={'cs6436-54p': 'cs6436-54p/classes'}, + ) diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/utils/cig_cs6436_misc.py b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/utils/cig_cs6436_misc.py new file mode 100755 index 000000000000..c186676cbf3f --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/utils/cig_cs6436_misc.py @@ -0,0 +1,574 @@ +#!/usr/bin/env python +# +# Copyright (C) 2018 Cambridge, Inc. +# +# This program is free software: you can 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 commands +import sys, getopt +import logging +import re +import time +import datetime +from collections import namedtuple +from threading import Thread + +DEBUG = False +i2c_prefix = '/sys/bus/i2c/devices/' +leds_prefix = '/sys/devices/platform/cs6436_54p_led/leds/' +fans_prefix = '/sys/devices/platform/cs6436_54p_fan/' +fansdir_prefix = fans_prefix + 'fan{}_direction' + +ageing_controlfile = '/etc/sonic/agcontrol' +AGFlag = 0 + + +platform_misc_log = '/var/log/platform_misc.log' +misclogger = logging.getLogger('platform_misc') +misclogger.setLevel(logging.INFO) +miscformatter = logging.Formatter('%(asctime)s-%(levelname)s-%(message)s') + +if not os.path.isfile(platform_misc_log): + try: + os.mknod(platform_misc_log) + except: + print 'Failed to creat platform_misc.log' + +fileHandler = logging.FileHandler(platform_misc_log) +fileHandler.setLevel(logging.INFO) +fileHandler.setFormatter(miscformatter) +misclogger.addHandler(fileHandler) + + +starttime = datetime.datetime.now() +IsGetlswt = 0 +coretemp_prefix = '/sys/class/hwmon/hwmon1/' +coretemp_ps = [] +psu1_p = '/sys/bus/i2c/devices/5-005a/psu_present' +psu2_p = '/sys/bus/i2c/devices/5-005b/psu_present' +psu1_d = '/sys/bus/i2c/devices/5-0052/psu_eeprom' +psu2_d = '/sys/bus/i2c/devices/5-0053/psu_eeprom' +psu1led_d = leds_prefix + 'cs6436_54p_led::psu1/brightness' +psu2led_d = leds_prefix + 'cs6436_54p_led::psu2/brightness' +cs6436_ledpath = {'fan':leds_prefix + 'cs6436_54p_led::fan/brightness', + 'fan1':leds_prefix + 'cs6436_54p_led::fan1/brightness', + 'fan2':leds_prefix + 'cs6436_54p_led::fan2/brightness', + 'fan3':leds_prefix + 'cs6436_54p_led::fan3/brightness', + 'fan4':leds_prefix + 'cs6436_54p_led::fan4/brightness', + 'fan5':leds_prefix + 'cs6436_54p_led::fan5/brightness', + 'psu1':leds_prefix + 'cs6436_54p_led::psu1/brightness', + 'psu2':leds_prefix + 'cs6436_54p_led::psu2/brightness', + 'sys':leds_prefix + 'cs6436_54p_led::sys/brightness'} + + +def system_read_filestr(node): + with open(node, 'r') as f: + try: + str = f.read() + except IOError as e: + misclogger.error('Failed to get node, str={}'.format(node)) + return "0" + return str + + +def system_bright_leds(dev, colour): + global AGFlag + + if AGFlag == 1: + return + + cmd = 'echo {} > {}'.format(colour, dev) + log_os_system(cmd, 1) + return + +''' +1: front in tail out +0: front out tail in +''' +def system_getpsu_direction(dev): + try: + with open(dev) as f: + f.seek(0x30) + str = f.read(2) + except IOError as e: + misclogger.error('Failed to get psu eep') + return 1 + if str == 'AA': ## front in tail out + return 1 + elif str == 'RA':## tail in front out + return 0 + else: + misclogger.error('Failed to get psu eep, str={}'.format(str)) + return -1 + + +def system_get_cputype(): + cmdretfd = os.popen("lscpu | grep 'Model name'") + retstring = cmdretfd.read() + endindex = retstring.find('@') - 1 + startindex = retstring[:endindex].rfind(' ') + 1 + cputype = retstring[startindex:endindex] + + return cputype + + +def system_init_coretemppath(): + global coretemp_ps + + cmdstr = "ls {} | grep 'input'".format(coretemp_prefix) + cmdretfd = os.popen(cmdstr) + + coretemppss = cmdretfd.read().splitlines() + if len(coretemppss) < 3: + cputype = system_get_cputype() + misclogger.error('Failed to init core temperature path.' + ' cpu type = {}, num thermal = {}'.format(cputype, len(coretemp_ps))) + return 1 + + for i in range(0,3): + coretemp_ps.append(coretemp_prefix + coretemppss[i]) + + print coretemp_ps + + return 0 + + +class cs6436_fanattr: + def __init__(self, name): + self.name = name + self.direction = 0 + self.direction_p = '' + self.rear = 0 + self.rear_p = '' + self.front = 0 + self.front_p = '' + self.fault = 0 + self.fault_p = '' + self.status = 0 + self.setpath() + self.updatedevice() + + return + + def setpath(self): + self.direction_p = fans_prefix + '{}_direction'.format(self.name) + self.rear_p = fans_prefix + '{}_rear_speed_rpm'.format(self.name) + self.front_p = fans_prefix + '{}_front_speed_rpm'.format(self.name) + self.fault_p = fans_prefix + '{}_fault'.format(self.name) + + return + + def updatedevice(self): + self.direction = int(system_read_filestr(self.direction_p)) + self.rear = int(system_read_filestr(self.rear_p)) + self.front = int(system_read_filestr(self.front_p)) + self.fault = int(system_read_filestr(self.fault_p)) + + return + + def checkspeedrpm(self, speedrpm): + frontrpmexp = speedrpm * 21000 / 100 + rearrpmexp = speedrpm * 19000 / 100 + deviationfront = abs(frontrpmexp - self.front) / float(frontrpmexp) + deviationrear = abs(rearrpmexp - self.rear) / float(rearrpmexp) + + if deviationfront < 0.3 and deviationrear < 0.3: + return 0 + else: + misclogger.error(':{} speed wrong. frontexp is {}, but rpm is {}.rearexp is {}, but rpm is {}'.format(self.name, frontrpmexp, self.front, rearrpmexp, self.rear)) + return 1 + + def checkstatus(self, speedrpm, totaldirct): + speedstatus = self.checkspeedrpm(speedrpm) + if self.direction != totaldirct: + self.status = 1 + misclogger.error(':{} direction = {}.fan direction is not ok.'.format(self.name, self.direction)) + elif speedstatus != 0: + self.status = 1 + elif self.fault != 0: + misclogger.error(':{} fault.'.format(self.name)) + self.status = 1 + else: + self.status = 0 + + if self.status == 1: + system_bright_leds(cs6436_ledpath[self.name], 3) + else: + system_bright_leds(cs6436_ledpath[self.name], 1) + + return self.status + +cs6436_fanattrnodes = [] + + +class cs6436_psuattr: + def __init__(self, name): + self.name = name + self.direction = 0 + self.direction_p = '' + self.present = 0 + self.present_p = '' + self.status = 0 + + self.setpath() + self.updatepresent() + self.updatedirection() + + return + + def setpath(self): + if self.name == 'psu1': + self.present_p = psu1_p + self.direction_p = psu1_d + if self.name == 'psu2': + self.present_p = psu2_p + self.direction_p = psu2_d + + return + + def updatepresent(self): + self.present = int(system_read_filestr(self.present_p)) + + return + + def updatedirection(self): + if self.present == 1: + self.direction = system_getpsu_direction(self.direction_p) + else: + self.direction = 2 + + return + + def checkstatus(self, totaldirct): + if self.present != 1: + self.status = 1 + misclogger.error(':{} not present.'.format(self.name)) + elif self.direction == 2: + self.status = 0 + misclogger.info(':{} direction need to be update.'.format(self.name)) + elif self.direction != totaldirct: + self.status = 1 + misclogger.info(':{} direction is wrong.'.format(self.name)) + else: + self.status = 0 + + if self.status == 1: + system_bright_leds(cs6436_ledpath[self.name], 3) + else: + system_bright_leds(cs6436_ledpath[self.name], 1) + + return self.status + +cs6436_psuattrnodes = [] + + + +def my_log(txt): + if DEBUG == True: + print "[ROY]"+txt + return + +def device_exist(): + ret1, log = log_os_system("ls "+i2c_prefix+"5-005a", 0) + ret2, log = log_os_system("ls "+i2c_prefix+"5-005b", 0) + ret3, log = log_os_system("ls "+leds_prefix+"cs6436_54p_led*", 0) + return not(ret1 or ret2 or ret3) + + +def log_os_system(cmd, show): + logging.info('Run :'+cmd) + status, output = commands.getstatusoutput(cmd) + my_log (cmd +"with result:" + str(status)) + my_log (" output:"+output) + if status: + logging.info('Failed :'+cmd) + if show: + print('Failed :'+cmd) + return status, output + + +def system_get_coretemp(): + temp1 = system_read_filestr(coretemp_ps[0]).strip() + temp2 = system_read_filestr(coretemp_ps[1]).strip() + temp3 = system_read_filestr(coretemp_ps[2]).strip() + + return int(temp1), int(temp2), int(temp3) + +def system_get_boardtemp(): + for i in range(0,16): + temp1path = "/sys/bus/i2c/devices/5-004a/hwmon/hwmon%d/temp1_input" % i + if os.access(temp1path, os.F_OK): + break + for i in range(0,16): + temp2path = "/sys/bus/i2c/devices/5-004b/hwmon/hwmon%d/temp1_input" % i + if os.access(temp2path, os.F_OK): + break + temp1 = system_read_filestr(temp1path).strip() + temp2 = system_read_filestr(temp2path).strip() + + return int(temp1), int(temp2) + + +def system_get_lswtemp(): + global IsGetlswt + global starttime + if IsGetlswt == 0: + now = datetime.datetime.now() + misclogger.info("time wait.") + misclogger.info("start = {}, now = {}.".format(starttime, now)) + if (now - starttime).seconds > 150: + misclogger.info("time = ".format((now - starttime).seconds)) + IsGetlswt = 1 + + return 25 + +# chp = subprocess.Popen("docker ps --filter name=syncd", shell=True, stdout=subprocess.PIPE) +# if chp.poll() == None: +# misclogger.info("No subp.") +# chp.kill() +# +# return 25 + +# retstring = chp.stdout.read() +# chp.kill() +# if 'Up' not in retstring: +# misclogger.info("lsw not up.") +# +# return 25 + + status, output = log_os_system('npx_diag swc show temperature', 1) + if status: + misclogger.error('failed to show lsw temperature') + + return 25 + + output = output.strip() + if output.find("it 0, temperature ") > 0: + startindex = output.find('temperature') + len('temperature') + 1 + endindex = output[startindex:].find(" ") + endindex = startindex + endindex + temp = output[startindex:endindex] + b = temp.find('.') + if b > 0: + temp=temp[:b] + temp = int(temp) + else: + misclogger.error("Failed to get temperature.") + temp = 0 + + return int(temp) + +def system_monitor_temperature(): + + ctemp1, ctemp2, ctemp3 = system_get_coretemp() + btemp1, btemp2 = system_get_boardtemp() + ltemp = system_get_lswtemp() + fan_speed_str = system_cs6436_getfanexspeed() + fan_speed = int(fan_speed_str) + policy = 'stay' + pos = 0 + #speed c1 c2 c3 b1 b2 lsw + fan_policy_up = ([30, 40000, 40000, 40000, 42000, 35000, 95], + [40, 44000, 44000, 44000, 44000, 39000, 96], + [50, 49000, 49000, 49000, 47000, 44000, 91], + [60, 52000, 52000, 52000, 51500, 47500, 92], + [70, 53000, 53000, 53000, 52000, 49000, 93], + [100,999999,999999,999999,999999,999999,999]) + + fan_policy_down=([30, 0, 0, 0, 0, 0, 0], + [40, 34000, 34000, 34000, 34000, 30000, 80], + [50, 38000, 38000, 38000, 37000, 33000, 81], + [60, 44000, 44000, 44000, 43000, 39000, 84], + [70, 44000, 44000, 44000, 43000, 40000, 84], + [100, 48000, 48000, 48000, 46000, 42000, 85],) + + for policytable in fan_policy_up: + if fan_speed <= policytable[0]: + break + pos = pos + 1 + fan_speed = policytable[0] + if (ctemp1 < policytable[1]) and (ctemp2 < policytable[2]) and (ctemp3 < policytable[3]) and (btemp1 < policytable[4]) and (btemp2 < policytable[5]) and (ltemp < policytable[6]): + policy = 'stay' + policytable = fan_policy_down[pos] + if (ctemp1 < policytable[1]) and (ctemp2 < policytable[2]) and (ctemp3 < policytable[3]) and (btemp1 < policytable[4]) and (btemp2 < policytable[5]) and (ltemp < policytable[6]): + policy = 'down' + else: + policy = 'up' + + if policy == 'up': + misclogger.info("speed = %d." % fan_speed) + misclogger.info("core1 = %d, core2 = %d, core3 = %d." % (ctemp1, ctemp2, ctemp3)) + misclogger.info("board1 = %d, board2 = %d." % (btemp1, btemp2)) + misclogger.info("lsw = %d" % ltemp) + fan_speed = fan_policy_down[pos + 1][0] + misclogger.info("fan policy: up. speedexp = {}".format(fan_speed)) + + if policy == 'stay': + fan_speed = fan_policy_down[pos] + return + + if policy == 'down': + misclogger.info("speed = %d." % fan_speed) + misclogger.info("core1 = %d, core2 = %d, core3 = %d." % (ctemp1, ctemp2, ctemp3)) + misclogger.info("board1 = %d, board2 = %d." % (btemp1, btemp2)) + misclogger.info("lsw = %d" % ltemp) + fan_speed = fan_policy_down[pos - 1][0] + misclogger.info("fan policy: down.speedexp = {}".format(fan_speed)) + + cmd = "echo {} > /sys/devices/platform/cs6436_54p_fan/fan_duty_cycle_percentage".format(fan_speed) + status, output = log_os_system(cmd, 1) + if status: + misclogger.error("set fan speed fault") + + return + + +def system_cs6436_setfanexspeed(num): + fanspeednode = fans_prefix + 'fan_duty_cycle_percentage' + numstr = str(num) + with open(fanspeednode, 'w') as f: + f.write(numstr) + + +def system_cs6436_getfanexspeed(): + fanspeednode = fans_prefix + 'fan_duty_cycle_percentage' + fanspeedstr = system_read_filestr(fanspeednode) + fanspeedexp = int(fanspeedstr) + + return fanspeedexp + + +def system_cs6436_getdirection(): + global cs6436_fanattrnodes + direction = 0 + + for fan in cs6436_fanattrnodes: + direction = direction + fan.direction + + if direction > 2: + direction = 1 + else: + direction = 0 + + return direction + + +def system_check_psusdirection(): + global cs6436_psuattrnodes + cs6436totaldirct = system_cs6436_getdirection() + psutatus = 0 + + for psu in cs6436_psuattrnodes: + psu.updatedirection() + psu.checkstatus(cs6436totaldirct) + psutatus = psu.status + psutatus + + return (psutatus != 0) + + +def system_check_psuspresent(): + global cs6436_psuattrnodes + cs6436totaldirct = system_cs6436_getdirection() + psutatus = 0 + + for psu in cs6436_psuattrnodes: + psu.updatepresent() + psu.checkstatus(cs6436totaldirct) + psutatus = psu.status + psutatus + + return (psutatus != 0) + + +def system_check_fansstate(): + global cs6436_fanattrnodes + global cs6436_ledpath + cs6436totaldirct = system_cs6436_getdirection() + fanstatus = 0 + fanexspeed = 0 + + fanexspeed = system_cs6436_getfanexspeed() + + for fan in cs6436_fanattrnodes: + fan.updatedevice() + fan.checkstatus(fanexspeed, cs6436totaldirct) + fanstatus = fanstatus + fan.status + + if fanstatus > 0: + misclogger.error(':fan error.set fans speed 100.') + system_cs6436_setfanexspeed(100) + system_bright_leds(cs6436_ledpath['fan'], 3) + else: + system_bright_leds(cs6436_ledpath['fan'], 1) + + return (fanstatus != 0) + + +def system_misc_polling(threadName,delay): + for count in range(1,5): + if device_exist() == False: + time.sleep(delay+3) + print "%s: %s, count=%d" % ( threadName, time.ctime(time.time()), count) + else: + break + + if count == 4: + return + + status, output = log_os_system("echo 1 > /sys/devices/platform/cs6436_54p_led/leds/cs6436_54p_led::sys/brightness", 1) + status, output = log_os_system("hwconfig -cfp 1", 1) + + global AGFlag + if os.access(ageing_controlfile, os.F_OK): + AGFlag = 1 + else: + AGFlag = 0 + + os.system('csw_daemon &') + + + global cs6436_fanattrnodes + global cs6436_psuattrnodes + + for num in range(1,6): + name = 'fan{}'.format(num) + fannode = cs6436_fanattr(name) + cs6436_fanattrnodes.append(fannode) + for num in range(1,3): + name = 'psu{}'.format(num) + psunode = cs6436_psuattr(name) + cs6436_psuattrnodes.append(psunode) + + tempcontrol = system_init_coretemppath() + + misclogger.info("%s: %s misc start." % ( threadName, time.ctime(time.time()))) + count = 0 + while 1: + count = count + 1 + ret = system_check_psuspresent() + ret = system_check_fansstate() + + if count % 10 == 0: + misclogger.info(": adjust fans and check psu direction.") + system_check_psusdirection() + if tempcontrol == 0: + system_monitor_temperature() + count = 0 + time.sleep(delay) + + return + +if __name__ == '__main__': + target=system_misc_polling("Thread-misc",10) + diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-54p/utils/cig_cs6436_util.py b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/utils/cig_cs6436_util.py new file mode 100755 index 000000000000..81e6bb7c0b6b --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-54p/utils/cig_cs6436_util.py @@ -0,0 +1,565 @@ +#!/usr/bin/env python +# +# Copyright (C) 2018 Cambridge, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +""" +Usage: %(scriptName)s [options] command object + +options: + -h | --help : this help message + -d | --debug : run with debug mode + -f | --force : ignore error during installation or clean +command: + install : install drivers and generate related sysfs nodes + clean : uninstall drivers and remove related sysfs nodes + show : show all systen status + sff : dump SFP eeprom + set : change board setting with fan|led|sfp +""" + +import os +import commands +import sys, getopt +import logging +import re +import time +from collections import namedtuple + + + + +PROJECT_NAME = 'cs6436_54p' +version = '0.1.1' +verbose = False +DEBUG = False +args = [] +ALL_DEVICE = {} +DEVICE_NO = {'led':9, 'fan':5, 'thermal':4, 'psu':2, 'sfp':54} +FORCE = 0 +CPU_TYPE = 'C3308' + + +if DEBUG == True: + print sys.argv[0] + print 'ARGV :', sys.argv[1:] + + +def main(): + global DEBUG + global args + global FORCE + + if len(sys.argv)<2: + show_help() + + options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help', + 'debug', + 'force', + ]) + if DEBUG == True: + print options + print args + print len(sys.argv) + + for opt, arg in options: + if opt in ('-h', '--help'): + show_help() + elif opt in ('-d', '--debug'): + DEBUG = True + logging.basicConfig(level=logging.INFO) + elif opt in ('-f', '--force'): + FORCE = 1 + else: + logging.info('no option') + for arg in args: + if arg == 'install': + do_install() + elif arg == 'clean': + do_uninstall() + elif arg == 'show': + device_traversal() + elif arg == 'sff': + if len(args)!=2: + show_eeprom_help() + elif int(args[1]) ==0 or int(args[1]) > DEVICE_NO['sfp']: + show_eeprom_help() + else: + show_eeprom(args[1]) + return + elif arg == 'set': + if len(args)<3: + show_set_help() + else: + set_device(args[1:]) + return + else: + show_help() + + + return 0 + +def show_help(): + print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]} + sys.exit(0) + +def show_set_help(): + cmd = sys.argv[0].split("/")[-1]+ " " + args[0] + print cmd +" [led|sfp|fan]" + print " use \""+ cmd + " led 0-4 \" to set led color" + print " use \""+ cmd + " fan 0-100\" to set fan duty percetage" + print " use \""+ cmd + " sfp 1-54 {0|1}\" to set sfp# tx_disable" + sys.exit(0) + +def show_eeprom_help(): + cmd = sys.argv[0].split("/")[-1]+ " " + args[0] + print " use \""+ cmd + " 1-54 \" to dump sfp# eeprom" + sys.exit(0) + +def my_log(txt): + if DEBUG == True: + print "[ROY]"+txt + return + +def log_os_system(cmd, show): + logging.info('Run :'+cmd) + status, output = commands.getstatusoutput(cmd) + my_log (cmd +"with result:" + str(status)) + my_log (" output:"+output) + if status: + logging.info('Failed :'+cmd) + if show: + print('Failed :'+cmd) + return status, output + +def driver_check(): + for count in range(1,5): + time.sleep(1) + ret, lsmod = log_os_system("lsmod| grep i2c_i801", 0) + if len(lsmod) > 2: + log_os_system("rmmod i2c_i801", 0) + break + + ret, lsmod = log_os_system("lsmod| grep i2c_designware_platform", 0) + if len(lsmod) > 2: + log_os_system("rmmod i2c_designware_platform", 0) + log_os_system("modprobe i2c-designware-platform", 0) + + ret, lsmod = log_os_system("lsmod| grep cig", 0) + logging.info('mods:'+lsmod) + if len(lsmod) ==0: + return False + return True + + + +kos = [ + 'depmod', + 'modprobe i2c_dev', + 'modprobe i2c_mux_pca954x force_deselect_on_exit=1', + 'modprobe x86-64-cig-cs6436-54p-sysfs ' , + 'modprobe x86-64-cig-cs6436-54p-cpld ' , + 'modprobe x86-64-cig-cs6436-54p-fan' , + 'modprobe x86-64-cig-cs6436-54p-psu' , + 'modprobe x86-64-cig-cs6436-54p-sfp' , + 'modprobe x86-64-cig-cs6436-54p-led' ] + +def driver_install(): + global FORCE + + for i in range(0,len(kos)): + if i == 4: + ret, CPU_TYPE = log_os_system("cat /proc/cpuinfo | grep \"model name\" | cut -b 32-39 | head -n 1", 0) + if CPU_TYPE=='i3-6100U': + kos[i] =kos[i] + 'board_id=1' + ret, CPU_TYPE = log_os_system("cat /proc/cpuinfo | grep \"model name\" | cut -b 36-40 | head -n 1", 0) + if CPU_TYPE=='C3758' or CPU_TYPE=='C3308': + kos[i] =kos[i] + 'board_id=2' + + status, output = log_os_system(kos[i], 1) + if status: + if FORCE == 0: + return status + return 0 + +def driver_uninstall(): + global FORCE + for i in range(0,len(kos)): + rm = kos[-(i+1)].replace("modprobe", "modprobe -rq") + rm = rm.replace("insmod", "rmmod") + status, output = log_os_system(rm, 1) + if status: + if FORCE == 0: + return status + return 0 + +led_prefix ='/sys/class/leds/'+PROJECT_NAME+'_led::' +hwmon_types = {'led': ['sys','fan','fan1','fan2','fan3','fan4','fan5','psu1','psu2']} +hwmon_nodes = {'led': ['brightness'] } +hwmon_prefix ={'led': led_prefix} + +i2c_prefix = '/sys/bus/i2c/devices/' +i2c_bus = {'thermal': ['4-0048','4-0049', '5-004a', '5-004b'] , + 'psu': ['5-005a','5-005b'], + 'sfp': ['-0050']} +i2c_nodes = {'thermal': ['hwmon/hwmon*/temp1_input'] , + 'psu': ['psu_present ', 'psu_power_good'] , + 'sfp': ['sfp_is_present ', 'sfp_tx_disable']} + +fan_prefix ='/sys/bus/platform/devices/'+PROJECT_NAME+'_fan' +fan_types = {'fan': ['fan1','fan2', 'fan3', 'fan4', 'fan5']} +fan_nodes = {'fan': ['state', 'front_speed_rpm', 'rear_speed_rpm', 'fault']} + + +sfp_map = [8,9,10,11,12,13,14,15,16, + 17,18,19,20,21,22,23,24,25,26, + 27,28,29,30,31,32,33,34,35,36, + 37,38,39,40,41,42,43,44,45,46, + 47,48,49,50,51,52,53,54,55,56, + 57,60,61,62,63] + +mknod =[ + 'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-2/new_device', + 'echo pca9548 0x72 > /sys/bus/i2c/devices/i2c-2/new_device', + 'echo pca9548 0x73 > /sys/bus/i2c/devices/i2c-2/new_device', + 'echo pca9548 0x74 > /sys/bus/i2c/devices/i2c-2/new_device', + 'echo pca9548 0x75 > /sys/bus/i2c/devices/i2c-3/new_device', + 'echo pca9548 0x76 > /sys/bus/i2c/devices/i2c-3/new_device', + 'echo pca9548 0x77 > /sys/bus/i2c/devices/i2c-3/new_device', + 'echo lm75 0x48 > /sys/bus/i2c/devices/i2c-4/new_device', + 'echo lm75 0x49 > /sys/bus/i2c/devices/i2c-4/new_device', + 'echo lm75 0x4a > /sys/bus/i2c/devices/i2c-5/new_device', + 'echo lm75 0x4b > /sys/bus/i2c/devices/i2c-5/new_device', + 'echo cs6436_54p_psu1 0x5a > /sys/bus/i2c/devices/i2c-5/new_device', + 'echo cs6436_54p_psu2 0x5b > /sys/bus/i2c/devices/i2c-5/new_device', + 'echo cs6436_54p_psu1 0x52 > /sys/bus/i2c/devices/i2c-5/new_device', + 'echo cs6436_54p_psu2 0x53 > /sys/bus/i2c/devices/i2c-5/new_device', + 'echo 24c128 0x57 > /sys/bus/i2c/devices/i2c-7/new_device'] + +port = 0 + +def device_install(): + global FORCE + global port + + for i in range(0,len(mknod)): + #all nodes need times to built new i2c buses + time.sleep(1) + + status, output = log_os_system(mknod[i], 1) + if status: + print output + if FORCE == 0: + return status + + for i in range(0,len(sfp_map)): + if (i == 50): + port = port + 3 + else: + port = port + 1 + + + status, output =log_os_system("echo cs6436_54p_sfp"+str(port)+" 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status + + if port <= 48: + status, output =log_os_system("echo cs6436_54p_sfp"+str(port)+" 0x51 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) + if status: + print output + if FORCE == 0: + return status + + return + +def device_uninstall(): + global FORCE + + for i in range(0,len(sfp_map)): + target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/delete_device" + status, output =log_os_system("echo 0x50 > "+ target, 1) + if status: + print output + if FORCE == 0: + return status + + nodelist = mknod + + for i in range(len(nodelist)): + target = nodelist[-(i+1)] + temp = target.split() + del temp[1] + temp[-1] = temp[-1].replace('new_device', 'delete_device') + status, output = log_os_system(" ".join(temp), 1) + if status: + print output + if FORCE == 0: + return status + + return + +def system_ready(): + if driver_check() == False: + return False + if not device_exist(): + return False + return True + +def do_install(): + print "Checking system...." + if driver_check() == False: + print "No driver, installing...." + status = driver_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper()+" drivers detected...." + if not device_exist(): + print "No device, installing...." + status = device_install() + if status: + if FORCE == 0: + return status + else: + print PROJECT_NAME.upper()+" devices detected...." + return + +def do_uninstall(): + print "Checking system...." + if not device_exist(): + print PROJECT_NAME.upper() +" has no device installed...." + else: + print "Removing device...." + status = device_uninstall() + if status: + if FORCE == 0: + return status + + if driver_check()== False : + print PROJECT_NAME.upper() +" has no driver installed...." + else: + print "Removing installed driver...." + status = driver_uninstall() + if status: + if FORCE == 0: + return status + + return + +def devices_info(): + global DEVICE_NO + global ALL_DEVICE + global i2c_bus, hwmon_types, fan_types + for key in DEVICE_NO: + ALL_DEVICE[key]= {} + for i in range(0,DEVICE_NO[key]): + ALL_DEVICE[key][key+str(i+1)] = [] + + for key in i2c_bus: + buses = i2c_bus[key] + nodes = i2c_nodes[key] + for i in range(0,len(buses)): + for j in range(0,len(nodes)): + if 'sfp' == key: + for k in range(0,DEVICE_NO[key]): + node = key+str(k+1) + path = i2c_prefix+ str(sfp_map[k])+ buses[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + else: + node = key+str(i+1) + path = i2c_prefix+ buses[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][node].append(path) + + for key in hwmon_types: + itypes = hwmon_types[key] + nodes = hwmon_nodes[key] + for i in range(0,len(itypes)): + for j in range(0,len(nodes)): + node = key+"_"+itypes[i] + path = hwmon_prefix[key]+ itypes[i]+"/"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][ key+str(i+1)].append(path) + + for key in fan_types: + itypes = fan_types[key] + nodes = fan_nodes[key] + for i in range(0,len(itypes)): + for j in range(0,len(nodes)): + node = key+"_"+itypes[i] + path = fan_prefix+"/"+ itypes[i]+"_"+ nodes[j] + my_log(node+": "+ path) + ALL_DEVICE[key][ key+str(i+1)].append(path) + + #show dict all in the order + if DEBUG == True: + for i in sorted(ALL_DEVICE.keys()): + print(i+": ") + for j in sorted(ALL_DEVICE[i].keys()): + print(" "+j) + for k in (ALL_DEVICE[i][j]): + print(" "+" "+k) + return + +def show_eeprom(index): + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + node = ALL_DEVICE['sfp'] ['sfp'+str(index)][0] + node = node.replace(node.split("/")[-1], 'sfp_eeprom') + # check if got hexdump command in current environment + ret, log = log_os_system("which hexdump", 0) + ret, log2 = log_os_system("which busybox hexdump", 0) + if len(log): + hex_cmd = 'hexdump' + elif len(log2): + hex_cmd = ' busybox hexdump' + else: + log = 'Failed : no hexdump cmd!!' + logging.info(log) + print log + return 1 + + print node + ":" + ret, log = log_os_system("cat "+node+"| "+hex_cmd+" -C", 1) + if ret==0: + print log + else: + print "**********device no found**********" + return + +def set_device(args): + global DEVICE_NO + global ALL_DEVICE + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + + if args[0]=='led': + if int(args[1])>4: + show_set_help() + return + #print ALL_DEVICE['led'] + for i in range(0,len(ALL_DEVICE['led'])): + for k in (ALL_DEVICE['led']['led'+str(i+1)]): + ret, log = log_os_system("echo "+args[1]+" >"+k, 1) + if ret: + return ret + elif args[0]=='fan': + if int(args[1])>100: + show_set_help() + return + #print ALL_DEVICE['fan'] + #fan1~6 is all fine, all fan share same setting + node = ALL_DEVICE['fan'] ['fan1'][0] + node = node.replace(node.split("/")[-1], 'fan_duty_cycle_percentage') + ret, log = log_os_system("cat "+ node, 1) + if ret==0: + print ("Previous fan duty: " + log.strip() +"%") + ret, log = log_os_system("echo "+args[1]+" >"+node, 1) + if ret==0: + print ("Current fan duty: " + args[1] +"%") + return ret + elif args[0]=='sfp': + if int(args[1])> DEVICE_NO[args[0]] or int(args[1])==0: + show_set_help() + return + if len(args)<2: + show_set_help() + return + + if int(args[2])>1: + show_set_help() + return + + #print ALL_DEVICE[args[0]] + for i in range(0,len(ALL_DEVICE[args[0]])): + for j in ALL_DEVICE[args[0]][args[0]+str(args[1])]: + if j.find('tx_disable')!= -1: + ret, log = log_os_system("echo "+args[2]+" >"+ j, 1) + if ret: + return ret + + return + +def get_value(input): + digit = re.findall('\d+', input) + return int(digit[0]) + + +def get_ledname(ledx): + name_table={'led1':'SYS','led2':'FSTUS','led3':'FAN1','led4':'FAN2','led5':'FAN3','led6':'FAN4','led7':'FAN5','led8':'PSU1','led9':'PSU2'} + if name_table.has_key(ledx): + name = name_table[ledx] + else: + name = ledx + return name + + +def device_traversal(): + if system_ready()==False: + print("System's not ready.") + print("Please install first!") + return + + if len(ALL_DEVICE)==0: + devices_info() + for i in sorted(ALL_DEVICE.keys()): + print("============================================") + print(i.upper()+": ") + print("============================================") + + for j in sorted(ALL_DEVICE[i].keys(), key=get_value): + nwnamex = get_ledname(j) + if nwnamex == j: + print " "+j+":", + else: + print " "+nwnamex+":", + for k in (ALL_DEVICE[i][j]): + ret, log = log_os_system("cat "+k, 0) + func = k.split("/")[-1].strip() + func = re.sub(j+'_','',func,1) + func = re.sub(i.lower()+'_','',func,1) + if ret==0: + print func+"="+log+" ", + else: + print func+"="+"X"+" ", + print + print("----------------------------------------------------------------") + + + print + return + +def device_exist(): + ret1, log = log_os_system("ls "+i2c_prefix+"*0077", 0) + ret2, log = log_os_system("ls "+i2c_prefix+"i2c-3", 0) + return not(ret1 or ret2) + + +if __name__ == "__main__": + main() diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/Makefile b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/Makefile old mode 100755 new mode 100644 index cdb114aad510..b0b4f1f7df06 --- a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/Makefile +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/Makefile @@ -1,4 +1,5 @@ -obj-m := x86-64-cig-cs6436-56p-cpld.o \ +obj-m :=x86-64-cig-cs6436-56p-sysfs.o \ + x86-64-cig-cs6436-56p-cpld.o \ x86-64-cig-cs6436-56p-fan.o \ x86-64-cig-cs6436-56p-led.o \ x86-64-cig-cs6436-56p-psu.o \ diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/i2c-algo-lpc.h b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/i2c-algo-lpc.h old mode 100755 new mode 100644 index 7ce6ae378596..9f1acd52ea68 --- a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/i2c-algo-lpc.h +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/i2c-algo-lpc.h @@ -65,7 +65,7 @@ #define I2C_LPC_CLK3 0x00 #define I2C_LPC_CLK443 0x10 #define I2C_LPC_CLK6 0x14 -#define I2C_LPC_CLK 0x18 +#define I2C_LPC_CLK 0x18 #define I2C_LPC_CLK12 0x1c /* ----- transmission frequencies ------------------------------------- */ @@ -94,4 +94,129 @@ #define I2C_LPC_REG_DATA_TX3 0x8c #define I2C_LPC_REG_DATA_TX4 0x8d -#endif /* I2C_LPC_H */ + +#define ADDR_REG_SFP_STATUS_ADDR 0X62 //reg addr +R/W# //1031 +#define ADDR_REG_SFP_STATUS_TX 0X63 // write data +#define ADDR_REG_SFP_STATUS_RX 0X64 //read data +#define ADDR_REG_SFP_STATUS_COMMAND 0X65 //cmd bit7=1,go +#define ADDR_REG_SFP_STATUS_STATUS 0X66 //status + +#define CPLD_MASTER_INTERRUPT_STATUS_REG 0x20 +#define CPLD_MASTER_INTERRUPT_MASK_REG 0x21 +#define CPLD_MASTER_INTERRUPT_ALL 0x3f +#define CPLD_MASTER_INTERRUPT_CPLD2 0x20 +#define CPLD_MASTER_INTERRUPT_CPLD1 0x10 +#define CPLD_MASTER_INTERRUPT_PSU2 0x08 +#define CPLD_MASTER_INTERRUPT_PSU1 0x04 +#define CPLD_MASTER_INTERRUPT_6320 0x02 +#define CPLD_MASTER_INTERRUPT_LSW 0x01 + + + +#define CPLD_SLAVE1_INTERRUPT_STATUS_L_REG 0x20 +#define CPLD_SLAVE1_INTERRUPT_STATUS_H_REG 0x21 +#define CPLD_SLAVE2_INTERRUPT_STATUS_L_REG 0x22 +#define CPLD_SLAVE2_INTERRUPT_STATUS_H_REG 0x23 +#define CPLD_SLAVE1_INTERRUPT_MASK_REG 0x24 +#define CPLD_SLAVE2_INTERRUPT_MASK_REG 0x25 + + +#define CPLD_SLAVE1_PRESENT08_REG 0x01 +#define CPLD_SLAVE1_PRESENT16_REG 0x02 +#define CPLD_SLAVE1_PRESENT24_REG 0x03 +#define CPLD_SLAVE2_PRESENT32_REG 0x04 +#define CPLD_SLAVE2_PRESENT40_REG 0x05 +#define CPLD_SLAVE2_PRESENT48_REG 0x06 + +#define CPLD_SLAVE1_RX_LOST08_REG 0x07 +#define CPLD_SLAVE1_RX_LOST16_REG 0x08 +#define CPLD_SLAVE1_RX_LOST24_REG 0x09 +#define CPLD_SLAVE2_RX_LOST32_REG 0x0a +#define CPLD_SLAVE2_RX_LOST40_REG 0x0b +#define CPLD_SLAVE2_RX_LOST48_REG 0x0c + +#define CPLD_SLAVE1_TX_FAULT08_REG 0x0d +#define CPLD_SLAVE1_TX_FAULT16_REG 0x0e +#define CPLD_SLAVE1_TX_FAULT24_REG 0x0f +#define CPLD_SLAVE2_TX_FAULT32_REG 0x10 +#define CPLD_SLAVE2_TX_FAULT40_REG 0x11 +#define CPLD_SLAVE2_TX_FAULT48_REG 0x12 + +#define CPLD_SLAVE2_PRESENT56_REG 0x19 +#define CPLD_SLAVE2_QSFP_CR56_REG 0x1a + + +#define CPLD_SLAVE1_INTERRUPT_PRESENT08 0x0001 +#define CPLD_SLAVE1_INTERRUPT_PRESENT16 0x0002 +#define CPLD_SLAVE1_INTERRUPT_PRESENT24 0x0004 +#define CPLD_SLAVE2_INTERRUPT_PRESENT32 0x0001 +#define CPLD_SLAVE2_INTERRUPT_PRESENT40 0x0002 +#define CPLD_SLAVE2_INTERRUPT_PRESENT48 0x0004 + +#define CPLD_SLAVE2_INTERRUPT_QSFP_CR56 0x0200 +#define CPLD_SLAVE2_INTERRUPT_PRESENT56 0x0400 + +#define CPLD_SLAVE1_INTERRUPT_RX_LOST08 0x0008 +#define CPLD_SLAVE1_INTERRUPT_RX_LOST16 0x0010 +#define CPLD_SLAVE1_INTERRUPT_RX_LOST24 0x0020 +#define CPLD_SLAVE2_INTERRUPT_RX_LOST32 0x0008 +#define CPLD_SLAVE2_INTERRUPT_RX_LOST40 0x0010 +#define CPLD_SLAVE2_INTERRUPT_RX_LOST48 0x0020 + +#define CPLD_SLAVE1_INTERRUPT_TX_FAULT08 0x0040 +#define CPLD_SLAVE1_INTERRUPT_TX_FAULT16 0x0080 +#define CPLD_SLAVE1_INTERRUPT_TX_FAULT24 0x0100 +#define CPLD_SLAVE2_INTERRUPT_TX_FAULT32 0x0040 +#define CPLD_SLAVE2_INTERRUPT_TX_FAULT40 0x0080 +#define CPLD_SLAVE2_INTERRUPT_TX_FAULT48 0x0100 + + + + + + + +#define WAIT_TIME_OUT_COUNT 100 + + +struct i2c_algo_lpc_data { + void *data; /* private data for lolevel routines */ + void (*setlpc) (void *data, int ctl, int val); + int (*getlpc) (void *data, int ctl); + int (*getown) (void *data); + int (*getclock) (void *data); + void (*waitforpin) (void *data); + + int (*xfer_begin) (void *data); + int (*xfer_end) (void *data); + + /* Multi-master lost arbitration back-off delay (msecs) + * This should be set by the bus adapter or knowledgable client + * if bus is multi-mastered, else zero + */ + unsigned long lab_mdelay; +}; + + +struct subsys_private { + struct kset subsys; + struct kset *devices_kset; + struct list_head interfaces; + struct mutex mutex; + + struct kset *drivers_kset; + struct klist klist_devices; + struct klist klist_drivers; + struct blocking_notifier_head bus_notifier; + unsigned int drivers_autoprobe:1; + struct bus_type *bus; + + struct kset glue_dirs; + struct class *class; +}; + +void cs6436_56p_sysfs_add_client(struct i2c_client *client); +void cs6436_56p_sysfs_remove_client(struct i2c_client *client); + + +#endif /* I2C_LPC8584_H */ diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/i2c-algo-lpc2iic.h b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/i2c-algo-lpc2iic.h old mode 100755 new mode 100644 diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-cpld.c b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-cpld.c old mode 100755 new mode 100644 index a3c6e2db54eb..dcff94085f09 --- a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-cpld.c +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-cpld.c @@ -17,8 +17,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - - #include #include #include @@ -32,7 +30,6 @@ #include #include #include "i2c-algo-lpc.h" -#include "i2c-algo-lpc2iic.h" #include #include #include @@ -41,11 +38,9 @@ #include #include #include -#include #include #include #include -#include #include #include #include @@ -56,6 +51,20 @@ # include #endif +#include +#include +#include +#include +#include +#include +#include + + + + + +/********************************************** Start ********************************************************/ + /* * ISA bus. */ @@ -65,7 +74,7 @@ static void platform_isa_bus_release(struct device * dev) return ; } - + static struct device isa_bus = { .init_name = "lpc-isa", .release = platform_isa_bus_release, @@ -76,9 +85,9 @@ struct isa_dev { struct device *next; unsigned int id; }; - -#define to_isa_dev(x) container_of((x), struct isa_dev, dev) - + +#define to_isa_dev(x) container_of((x), struct isa_dev, dev) + static int isa_bus_match(struct device *dev, struct device_driver *driver) { struct isa_driver *isa_driver = to_isa_driver(driver); @@ -223,7 +232,7 @@ int lpc_register_driver(struct isa_driver *isa_driver, unsigned int ndev) return error; } - + int lpc_bus_init(void) { int error; @@ -246,28 +255,36 @@ void lpc_bus_exit(void) } +/********************************************** End ********************************************************/ + + + + + + +/********************************************** Start ********************************************************/ /* * module parameters: */ static int i2c_debug = 0; static struct mutex lpc_lock; - -#define DEB2(x) if (i2c_debug >= 2) x -#define DEB3(x) if (i2c_debug >= 3) x + +#define DEB2(x) if (i2c_debug == 2) x +#define DEB3(x) if (i2c_debug == 3) x /* print several statistical values */ -#define DEBPROTO(x) if (i2c_debug >= 9) x; - /* debug the protocol by showing transferred bits */ +#define DEBPROTO(x) if (i2c_debug == 9) x; + /* debug the protocol by showing transferred bits */ #define DEF_TIMEOUT 160 - - - -/* setting states on the bus with the right timing: */ - + + + +/* setting states on the bus with the right timing: */ + #define set_lpc(adap, ctl, val) adap->setlpc(adap->data, ctl, val) #define get_lpc(adap, ctl) adap->getlpc(adap->data, ctl) -#define get_own(adap) adap->getown(adap->data) -#define get_clock(adap) adap->getclock(adap->data) +#define get_own(adap) adap->getown(adap->data) +#define get_clock(adap) adap->getclock(adap->data) #define i2c_outaddr(adap, val) adap->setlpc(adap->data, I2C_LPC_REG_DEVICE_ADDR, val) #define i2c_outbyte1(adap, val) adap->setlpc(adap->data, I2C_LPC_REG_DATA_TX1, val) @@ -278,54 +295,52 @@ static struct mutex lpc_lock; #define i2c_inbyte2(adap) adap->getlpc(adap->data, I2C_LPC_REG_DATA_RX2) #define i2c_inbyte3(adap) adap->getlpc(adap->data, I2C_LPC_REG_DATA_RX3) #define i2c_inbyte4(adap) adap->getlpc(adap->data, I2C_LPC_REG_DATA_RX4) - + #define LPC_FPRINTF_LOG_PATH "/tmp/file.log" struct file *lpc_fprintf_file = NULL; - static int lpc_fprintf_debug(const char *fmt, ...) { char lpc_fprintf_buf[256]={0}; - struct va_format vaf; va_list args; int r; - unsigned int file_size = 0; mm_segment_t old_fs; struct timeval tv; + struct rtc_time tm; + do_gettimeofday(&tv); + rtc_time_to_tm(tv.tv_sec,&tm); + va_start(args, fmt); vaf.fmt = fmt; vaf.va = &args; - r=snprintf(lpc_fprintf_buf,"[%012d.%012d] %pV\n",sizeof(lpc_fprintf_buf),tv.tv_sec, tv.tv_usec, &vaf); + r=snprintf(lpc_fprintf_buf,sizeof(lpc_fprintf_buf),"[%04d.%08d] %pV\n",tm.tm_sec, (int)tv.tv_usec, &vaf); va_end(args); - old_fs = get_fs(); set_fs(KERNEL_DS); - lpc_fprintf_file->f_op->write(lpc_fprintf_file, (char *)lpc_fprintf_buf, strlen(lpc_fprintf_buf), &lpc_fprintf_file->f_pos); + vfs_write(lpc_fprintf_file, (char *)&lpc_fprintf_buf, strlen(lpc_fprintf_buf), &lpc_fprintf_file->f_pos); set_fs(old_fs); - memset(lpc_fprintf_buf,0x0,sizeof(lpc_fprintf_buf)); return r; } + static int lpc_fprintf_init(void) { - mm_segment_t old_fs; - - DEB2(printk("lpc_fprintf_init.\n");) - + printk("lpc_fprintf_init.\n"); if(lpc_fprintf_file == NULL) lpc_fprintf_file = filp_open(LPC_FPRINTF_LOG_PATH, O_RDWR | O_APPEND | O_CREAT, 0644); + if (IS_ERR(lpc_fprintf_file)) { - DEB2(printk("error occured while opening file %s, exiting...\n", LPC_FPRINTF_LOG_PATH);) - return 0; + printk("Error occured while opening file %s, exiting...\n", LPC_FPRINTF_LOG_PATH); + return -1; } return 0; @@ -333,10 +348,11 @@ static int lpc_fprintf_init(void) static int lpc_fprintf_exit(void) { - DEB2(printk("lpc_fprintf_exit.\n");) + printk("lpc_fprintf_exit.\n"); if(lpc_fprintf_file != NULL) filp_close(lpc_fprintf_file, NULL); + return 0; } @@ -366,14 +382,13 @@ void print_reg(struct i2c_algo_lpc_data *adap) static void i2c_repstart(struct i2c_algo_lpc_data *adap) { - DEBPROTO(lpc_fprintf_debug(" Sr\n")); + DEBPROTO(lpc_fprintf_debug("%s :\n",__func__);) set_lpc(adap, I2C_LPC_REG_COMMAND, I2C_LPC_REPSTART); } static void i2c_stop(struct i2c_algo_lpc_data *adap) { DEBPROTO(lpc_fprintf_debug("%s :\n",__func__);) - set_lpc(adap, I2C_LPC_REG_COMMAND, I2C_LPC_STOP); udelay(60); set_lpc(adap, I2C_LPC_REG_COMMAND, 0x00); @@ -384,60 +399,56 @@ static void i2c_stop(struct i2c_algo_lpc_data *adap) static void i2c_start(struct i2c_algo_lpc_data *adap) { - unsigned char status; - int timeout = DEF_TIMEOUT; - print_reg(adap); set_lpc(adap, I2C_LPC_REG_COMMAND, I2C_LPC_START); print_reg(adap); - } static int wait_for_bb(struct i2c_algo_lpc_data *adap) -{ - - int timeout = DEF_TIMEOUT; - int status; - +{ + + int timeout = DEF_TIMEOUT; + int status; + while (--timeout) { status = get_lpc(adap, I2C_LPC_REG_STATUS); - + DEBPROTO(lpc_fprintf_debug("%s : Waiting for bus free status : %x\n",__func__,status);) - + if(status == I2C_LPC_TD) { DEBPROTO(lpc_fprintf_debug("%s : Bus is free status : %x\n",__func__,status);) break; } - } - - if (timeout == 0) { + } + + if (timeout == 0) { DEBPROTO(lpc_fprintf_debug("%s : Timeout for free busy status : %x\n",__func__,status);) - return -ETIMEDOUT; - } + return -ETIMEDOUT; + } + - - - return 0; + + return 0; } static int wait_for_be(int mode,struct i2c_algo_lpc_data *adap) -{ - - int timeout = DEF_TIMEOUT; - unsigned char status; - +{ + + int timeout = DEF_TIMEOUT; + unsigned char status; + while (--timeout) { - + status = get_lpc(adap, I2C_LPC_REG_STATUS); - + DEBPROTO(lpc_fprintf_debug("%s : Waiting for bus empty status : %x\n",__func__,status);) if(mode == 1) @@ -446,42 +457,42 @@ static int wait_for_be(int mode,struct i2c_algo_lpc_data *adap) { DEBPROTO(lpc_fprintf_debug("%s : Bus is empty status : %x\n",__func__,status);) break; - } + } } else - { + { if(status & I2C_LPC_TD) { DEBPROTO(lpc_fprintf_debug("%s : Bus is empty status : %x\n",__func__,status);) break; } } - + status = get_lpc(adap, I2C_LPC_REG_TEST); - + DEBPROTO(lpc_fprintf_debug("%s : The test register data : %x\n",__func__,status);) udelay(1); /* wait for 100 us */ } - if (timeout == 0) { + if (timeout == 0) { DEBPROTO(lpc_fprintf_debug("%s : Timeout waiting for Bus Empty\n",__func__);) - return -ETIMEDOUT; - } - - return 0; + return -ETIMEDOUT; + } + + return 0; } static int wait_for_bf(struct i2c_algo_lpc_data *adap) -{ - - int timeout = DEF_TIMEOUT; - int status; - +{ + + int timeout = DEF_TIMEOUT; + int status; + while (--timeout) { status = get_lpc(adap, I2C_LPC_REG_STATUS); - + DEBPROTO(lpc_fprintf_debug("%s : Waiting for bus full status : %x\n",__func__,status);) if(status & I2C_LPC_RBF) @@ -491,29 +502,29 @@ static int wait_for_bf(struct i2c_algo_lpc_data *adap) } status = get_lpc(adap, I2C_LPC_REG_TEST); - + DEBPROTO(lpc_fprintf_debug("%s : The test register data : %x\n",__func__,status);) udelay(1); /* wait for 100 us */ } - - if (timeout == 0) { + + if (timeout == 0) { DEBPROTO(lpc_fprintf_debug("%s : Timeout waiting for Bus Full\n",__func__);) - return -ETIMEDOUT; - } - - return 0; + return -ETIMEDOUT; + } + + return 0; } static int wait_for_td(struct i2c_algo_lpc_data *adap) -{ - - int timeout = DEF_TIMEOUT; - int status=0; - +{ + + int timeout = DEF_TIMEOUT; + int status=0; + while (--timeout) { - udelay(4); + udelay(4); status = get_lpc(adap, I2C_LPC_REG_STATUS); - + DEBPROTO(lpc_fprintf_debug("%s : Waiting for bus done status : %x\n",__func__,status);) if(status == I2C_LPC_TD) @@ -521,18 +532,18 @@ static int wait_for_td(struct i2c_algo_lpc_data *adap) DEBPROTO(lpc_fprintf_debug("%s : Bus is done status : %x\n",__func__,status);) break; } - } - - if (timeout == 0) { + } + + if (timeout == 0) { DEBPROTO(lpc_fprintf_debug("%s : Timeout waiting for Bus Done\n",__func__);) - return -ETIMEDOUT; - } - - return 0; + return -ETIMEDOUT; + } + + return 0; } - + static int wait_for_pin(struct i2c_algo_lpc_data *adap, int *status) { int timeout = DEF_TIMEOUT; @@ -545,7 +556,7 @@ static int wait_for_pin(struct i2c_algo_lpc_data *adap, int *status) if (timeout == 0) return -ETIMEDOUT; - + return 0; } @@ -565,7 +576,7 @@ static int lpc_doAddress(struct i2c_algo_lpc_data *adap,struct i2c_msg *msg) { DEBPROTO(lpc_fprintf_debug("step 2 : write mode then write device address 0x%x\n",addr);) } - + if (flags & I2C_M_REV_DIR_ADDR) { addr ^= 1; @@ -629,33 +640,33 @@ static int lpc_sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) DEBPROTO(lpc_fprintf_debug("step 4 : Send data[%d] = %x\n",i+0,buf[i+0]);) i += 1; } - + /* Send START */ DEBPROTO(lpc_fprintf_debug("step 5-1 : Delay 6mS \n");) - udelay(6000); + udelay(6000); DEBPROTO(lpc_fprintf_debug("step 5-2 : Start to transfrom \n");) i2c_stop(adap); i2c_start(adap); DEBPROTO(lpc_fprintf_debug("step 5-3 : Start done\n");) - udelay(400); + udelay(400); DEBPROTO(lpc_fprintf_debug("step 6 : Waiting for BE\n");) timeout = wait_for_td(adap); if (timeout) { DEBPROTO(lpc_fprintf_debug("step 6 : Timeout waiting for BE \n");) - return -1; + return -EREMOTEIO; } }while (i < count); - + if(i == count) { DEBPROTO(lpc_fprintf_debug("Writen %d bytes successd !\n",count);) return i; } else - { + { DEBPROTO(lpc_fprintf_debug("Writen %d bytes failed \n",count);) - return -1; + return -EIO; } } @@ -663,7 +674,6 @@ static int lpc_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) { int i=0,timeout=0; struct i2c_algo_lpc_data *adap = i2c_adap->algo_data; - int wfp; unsigned int count = msg->len; unsigned char *buf = msg->buf; @@ -675,27 +685,27 @@ static int lpc_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) /* Send START */ DEBPROTO(lpc_fprintf_debug("step 9-1 : Delay 6mS\n");) - udelay(6000); + udelay(6000); DEBPROTO(lpc_fprintf_debug("step 9-2 : Start to receive data\n");) i2c_stop(adap); i2c_start(adap); DEBPROTO(lpc_fprintf_debug("step 9-3 : Start done\n");) - udelay(400); + udelay(400); DEBPROTO(lpc_fprintf_debug("step 10 : Waiting for TD\n");) timeout = wait_for_td(adap); if (timeout) { DEBPROTO(lpc_fprintf_debug("step 10 : Timeout waiting for TD \n");) - return -1; + return -EREMOTEIO; } - + if((count -i) >= 4) { buf[i+0] = 0xff & i2c_inbyte1(adap); buf[i+1] = 0xff & i2c_inbyte2(adap); buf[i+2] = 0xff & i2c_inbyte3(adap); buf[i+3] = 0xff & i2c_inbyte4(adap); - + DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+0,buf[i+0]);) DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+1,buf[i+1]);) DEBPROTO(lpc_fprintf_debug("step 11 : Receive data[%d] = %x\n",i+2,buf[i+2]);) @@ -732,19 +742,17 @@ static int lpc_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) }while(i < count); - + if(i == count) { DEBPROTO(lpc_fprintf_debug("Read %d bytes successd !\n",count);) return i; } else - { + { DEBPROTO(lpc_fprintf_debug("Read %d bytes failed \n",count);) - return -1; + return -EIO; } - - return i; } @@ -768,7 +776,7 @@ static int lpc_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_algo_lpc_data *adap = i2c_adap->algo_data; struct i2c_msg *pmsg; int i; - int ret=0, timeout, status; + int ret=0; mutex_lock(&lpc_lock); @@ -810,11 +818,12 @@ static int lpc_master_xfer(struct i2c_adapter *i2c_adap, if (adap->xfer_end) adap->xfer_end(&i2c_adap->nr); - + mutex_unlock(&lpc_lock); - return i; + DEBPROTO(lpc_fprintf_debug("ret = 0x%x num = 0x%x i = 0x%x.\n",ret,num,i)); + return ret = (ret < 0) ? ret : num; } @@ -831,38 +840,14 @@ static const struct i2c_algorithm lpc_algo = { }; -/* - * registering functions to load algorithms at runtime - */ -int lpc_add_iic_bus(struct i2c_adapter *adap,unsigned int id) -{ - //struct i2c_algo_lpc_data *lpc_adap = adap->3; - int rval,num; +/********************************************** End ********************************************************/ + + - DEB2(dev_dbg(&adap->dev, "hw routines registered.\n")); - /* register new adapter to i2c module... */ - adap->algo = &lpc_algo; - - for(num = 0; num < LPC_I2C_MAX_NCHANS;num++) - { - adap->nr = num; - snprintf(adap->name, sizeof(adap->name), - "i2c-%d-lpc (chan_id %d)", i2c_adapter_id(adap), num); - if(num) - { - rval = i2c_add_numbered_adapter(adap); - } - else - { - rval = i2c_add_adapter(adap); - } - } - return rval; -} -EXPORT_SYMBOL(lpc_add_iic_bus); +/********************************************** Start ********************************************************/ #define DEFAULT_BASE 0x0a00 static int lpc_base= 0x0a00; @@ -905,7 +890,6 @@ struct cpld_dev_type *cpld_device; static void lpc_cpld_setbyte(void *data, int ctl, int val) { - //udelay(2); outb(ctl, LPC_INDEX_REG); mb(); @@ -916,7 +900,7 @@ static void lpc_cpld_setbyte(void *data, int ctl, int val) static int lpc_cpld_getbyte(void *data, int ctl) { u8 val = 0; - //udelay(2); + outb(ctl, LPC_INDEX_REG); mb(); @@ -929,17 +913,23 @@ static int lpc_cpld_getbyte(void *data, int ctl) static void lpc_iic_setbyte(void *data, int ctl, int val) { if (!cpld_device) - return -ENOTTY; + { + return ; + } if (down_interruptible(&cpld_device->sem)) - return -ERESTARTSYS; - + { + return ; + } + + lpc_cpld_setbyte(data,ctl,val); - + up(&cpld_device->sem); - DEB2(printk("%s REG[%x] = %x\n",__func__,ctl,val);) + DEBPROTO(lpc_fprintf_debug("%s REG[%x] = %x\n",__func__,ctl,val);) } + static int lpc_iic_getbyte(void *data, int ctl) { u8 val = 0; @@ -950,9 +940,9 @@ static int lpc_iic_getbyte(void *data, int ctl) return -ERESTARTSYS; val = lpc_cpld_getbyte(data,ctl); - + up(&cpld_device->sem); - DEB2(printk("%s REG[%x] = %x\n",__func__,ctl,val);) + DEBPROTO(lpc_fprintf_debug("%s REG[%x] = %x\n",__func__,ctl,val);) return val; } @@ -964,7 +954,7 @@ int cig_cpld_read_register(u8 reg_off, u8 *val) if (down_interruptible(&cpld_device->sem)) return -ERESTARTSYS; - *val = lpc_cpld_getbyte(cpld_device, reg_off); + *val = lpc_cpld_getbyte(cpld_device, reg_off); up(&cpld_device->sem); @@ -1039,24 +1029,24 @@ static irqreturn_t lpc_iic_handler(int this_irq, void *dev_id) { static int board_id = 0; -static int lpc_select_chan(void *data) +static int lpc_iic_select(void *data) { unsigned int chan_id=0; chan_id = *(unsigned int *)data; - chan_id -= 1; - DEB2(printk("step 1 : selest channel id = %d\n",chan_id);) + chan_id -= 2; + DEBPROTO(lpc_fprintf_debug("step 1 : selest channel id = %d\n",chan_id);) lpc_iic_setbyte(data,I2C_LPC_REG_BUS_SEL,chan_id); return 0; } -static int lpc_deselect_chan(void *data) +static int lpc_iic_deselect(void *data) { unsigned int chan_id=0; chan_id = *(unsigned int *)data; - chan_id -= 1; - DEB2(printk("step last :deselect channel id = %d\n",chan_id);) + chan_id -= 2; + DEBPROTO(lpc_fprintf_debug("step last :deselect channel id = %d\n",chan_id);) return 0; } @@ -1072,8 +1062,8 @@ static struct i2c_algo_lpc_data lpc_iic_data = { .getown = lpc_iic_getown, .getclock = lpc_iic_getclock, .waitforpin = lpc_iic_waitforpin, - .xfer_begin = lpc_select_chan, - .xfer_end = lpc_deselect_chan, + .xfer_begin = lpc_iic_select, + .xfer_end = lpc_iic_deselect, }; #include @@ -1082,12 +1072,12 @@ static struct i2c_adapter lpc_iic_arr_ops[LPC_I2C_MAX_NCHANS] = {0}; static void dummy_setscl(void *data, int state) { - return 1; + return; } static void dummy_setsda(void *data, int state) { - return 1; + return; } @@ -1170,9 +1160,7 @@ static int lpc_iic_probe(struct device *dev, unsigned int id) DEB2(printk("lpc_iic_probe\n");) mutex_init(&lpc_lock); - if(board_id == 1) - i2c_add_adapter(&i2c_dummy); - + for(num = 0; num < LPC_I2C_MAX_NCHANS;num++) { lpc_iic_arr_ops[num].dev.parent = dev; @@ -1181,11 +1169,11 @@ static int lpc_iic_probe(struct device *dev, unsigned int id) lpc_iic_arr_ops[num].algo = &lpc_algo; lpc_iic_arr_ops[num].algo_data = &lpc_iic_data, lpc_iic_arr_ops[num].nr=num; - snprintf(lpc_iic_arr_ops[num].name, sizeof(lpc_iic_arr_ops[num].name), "i2c-%d-lpc", i2c_adapter_id(&lpc_iic_arr_ops[num]), num); + snprintf(lpc_iic_arr_ops[num].name, sizeof(lpc_iic_arr_ops[num].name), "i2c-%d-lpc", i2c_adapter_id(&lpc_iic_arr_ops[num])); rval |= i2c_add_adapter(&lpc_iic_arr_ops[num]); DEB2(printk("%s\n",lpc_iic_arr_ops[num].name);) } - + return 0; } @@ -1198,8 +1186,6 @@ static int lpc_iic_remove(struct device *dev, unsigned int id) for(num = LPC_I2C_MAX_NCHANS - 1; num >= 0 ;num--) i2c_del_adapter(&lpc_iic_arr_ops[num]); - if(board_id == 1) - i2c_del_adapter(&i2c_dummy); return 0; } @@ -1214,8 +1200,15 @@ static struct isa_driver i2c_lpc_driver = { }, }; +/********************************************** End ********************************************************/ + + + + + + +/********************************************** Start ********************************************************/ -struct kset cpld_kset; static int cpld_major = 0; static int cpld_minor = 0; @@ -1227,6 +1220,8 @@ struct cpld_rw_msg { static struct cpld_rw_msg param_read = {-1}; static struct cpld_rw_msg param_write = {-1}; +static struct cpld_rw_msg param_reads = {-1}; +static struct cpld_rw_msg param_writes = {-1}; void cpld_sysfs_kobj_release(struct kobject *kobj) { @@ -1245,28 +1240,57 @@ int cpld_sysfs_add_attr(struct kobject* kobj, char* attr_name) return sysfs_create_file(kobj, attr); } +static int cig_cpld_write_slave_cpld_register(u8 reg_addr, u8 reg_data); +static int cig_cpld_read_slave_cpld_register(u8 reg_addr, u8 *reg_data); + static ssize_t cpld_sysfs_show(struct kobject *kobj, struct attribute *attr, char *buffer) { - u8 val,ret; + u8 val=0,ret=0,year=0,month=0,day=0,cpld_m=0,cpld_1=0,cpld_2=0; if (0 == strcmp(attr->name, "read")) { - val = lpc_iic_getbyte(NULL,param_read.addr); - ret = sprintf(buffer,"read : addr = %x val = %x\n",param_read.addr, val); + val = lpc_iic_getbyte(NULL,param_read.addr); + ret = sprintf(buffer,"read : addr = 0x%x val = 0x%x\n",param_read.addr, val); } else if (0 == strcmp(attr->name, "write")) { lpc_iic_setbyte(NULL, param_write.addr,param_write.data); - ret = sprintf(buffer,"write : addr = %x val = %x\n",param_write.addr, param_write.data); + ret = sprintf(buffer,"write : addr = 0x%x val = 0x%x\n",param_write.addr, param_write.data); } else if (0 == strcmp(attr->name, "version")) { - val = lpc_iic_getbyte(NULL, 0x02); - ret = sprintf(buffer,"CPLD version : V%02x\n",val); + cpld_m = lpc_iic_getbyte(NULL, 0x02); + year = lpc_iic_getbyte(NULL, 0x03); + month = lpc_iic_getbyte(NULL, 0x04); + day = lpc_iic_getbyte(NULL, 0x05); + + cig_cpld_read_slave_cpld_register(0x1d,&cpld_1); + cig_cpld_read_slave_cpld_register(0x1e,&cpld_2); + + ret = sprintf(buffer,"Main CPLD version : V%02x\n"\ + "Main CPLD date : 20%02x-%02x-%02x\n"\ + "Slave 1 CPLD version : V%02x\n"\ + "Slave 2 CPLD version : V%02x\n",cpld_m,year,month,day,cpld_1,cpld_2); + } + if (0 == strcmp(attr->name, "reads")) + { + ret = cig_cpld_read_slave_cpld_register(param_reads.addr,&val); + if (ret < 0) + printk("ERROR:Failed to read slave cpld.\n"); + ret = sprintf(buffer,"reads : addr = 0x%x val = 0x%x\n",param_reads.addr, val); + + } + else if (0 == strcmp(attr->name, "writes")) + { + ret = cig_cpld_write_slave_cpld_register(param_writes.addr,param_writes.data); + if (ret < 0) + printk("ERROR:Failed to read slave cpld.\n"); + ret = sprintf(buffer,"writes : addr = 0x%x val = 0x%x\n",param_writes.addr, param_writes.data); } - + + return ret; } @@ -1274,7 +1298,7 @@ static ssize_t cpld_sysfs_show(struct kobject *kobj, struct attribute *attr, cha static ssize_t cpld_sysfs_store(struct kobject *kobj, struct attribute *attr, const char *buffer, size_t count) { int param[3]; - + if (0 == strcmp(attr->name, "read")) { sscanf(buffer, "0x%02x", ¶m[0]); @@ -1285,19 +1309,30 @@ static ssize_t cpld_sysfs_store(struct kobject *kobj, struct attribute *attr, co sscanf(buffer, "0x%2x 0x%02x", ¶m[0], ¶m[1]); param_write.addr = param[0]; param_write.data = param[1]; + } + if (0 == strcmp(attr->name, "reads")) + { + sscanf(buffer, "0x%02x", ¶m[0]); + param_reads.addr = param[0]; + } + else if (0 == strcmp(attr->name, "writes")) + { + sscanf(buffer, "0x%2x 0x%02x", ¶m[0], ¶m[1]); + param_writes.addr = param[0]; + param_writes.data = param[1]; } return count; } -static struct sysfs_ops cpld_sysfs_ops = -{ +static struct sysfs_ops cpld_sysfs_ops = +{ .show = cpld_sysfs_show, .store = cpld_sysfs_store, }; -static struct kobj_type cpld_kobj_type = +static struct kobj_type cpld_kobj_type = { .release = cpld_sysfs_kobj_release, .sysfs_ops = &cpld_sysfs_ops, @@ -1308,6 +1343,10 @@ static struct kobj_type cpld_kobj_type = static const char driver_name[] = "cpld_drv"; static atomic_t cpld_available = ATOMIC_INIT(1); static struct class *cpld_class; +static struct device *cpld_dev; + + + #define CPLD_IOC_MAGIC '[' #define CPLD_IOC_RDREG _IOR(CPLD_IOC_MAGIC, 0, struct cpld_rw_msg) @@ -1340,7 +1379,7 @@ int cpld_release(struct inode *inode, struct file *flip) long cpld_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { - int rc = 0; + int rc = 0; int err = 0; struct cpld_dev_type *dev = (struct cpld_dev_type *)filp->private_data; struct cpld_rw_msg msg; @@ -1390,7 +1429,7 @@ struct file_operations cpld_fops = { .unlocked_ioctl = cpld_ioctl, .release = cpld_release, }; - + static void cpld_setup_cdev(struct cpld_dev_type *dev) { @@ -1404,166 +1443,710 @@ static void cpld_setup_cdev(struct cpld_dev_type *dev) if (err) DEB2(printk(KERN_NOTICE "Error %d adding cpld", err);) } -//#define CPLD_KTHREAD_TEST -#ifdef CPLD_KTHREAD_TEST -#include -#include -#include -#include -#include -#include -static struct task_struct *test_TaskStruct; -void get_random_bytes(void *buf, int nbytes); +/********************************************** End ********************************************************/ + + + -#define LM75_REAR_LEFT_PATH "/sys/class/hwmon/hwmon5/temp1_input" -#define LM75_REAR_RIGHT_PATH "/sys/class/hwmon/hwmon6/temp1_input" +/********************************************** Start ********************************************************/ +#include +#include +#include + +static spinlock_t irq_inter_lock; +static struct delayed_work irq_inter_work; +static unsigned long irq_inter_delay; -static int threadTask(void* arg) +static int cig_cpld_write_slave_cpld_register(u8 reg_addr, u8 reg_data) { - static int count =0; - unsigned char lpc_read_data=0; - unsigned char lpc_write_data=0; - unsigned char lpc_random_data=0; - - struct file *temp1_file = NULL,*temp2_file = NULL; - unsigned char temp1_buffer[8]={0},temp2_buffer[8]={0}; - - mm_segment_t old_fs; - while(1) + u8 read_status = 0; + u8 wait_time_out = WAIT_TIME_OUT_COUNT; + DEB2(printk("<=======write=========>")); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_ADDR, reg_addr << 1); + DEB2(printk("[62]=%x\n",reg_addr << 1)); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_TX, reg_data); + DEB2(printk("[63]=%x\n",reg_data)); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_COMMAND, 0x80); + DEB2(printk("[65]=%x\n",0x80)); + do{ + cig_cpld_read_register(ADDR_REG_SFP_STATUS_STATUS, &read_status); + DEB2(printk("[66]=%x\n",read_status)); + udelay(60); + wait_time_out--; + if(wait_time_out == 0) + break; + }while(read_status != 0x02); + DEB2(printk("<=======write=========>")); + + + if(wait_time_out == 0) + return -1; + + return 1; +} + + +static int cig_cpld_read_slave_cpld_register(u8 reg_addr, u8 *reg_data) +{ + u8 read_status = 0; + u8 wait_time_out = WAIT_TIME_OUT_COUNT; + DEB2(printk("<========read=========>")); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_ADDR, reg_addr << 1 | 1); + DEB2(printk("[62]=%x\n",reg_addr << 1 | 1)); + cig_cpld_write_register(ADDR_REG_SFP_STATUS_COMMAND, 0x80); + DEB2(printk("[65]=%x\n",0x80)); + do{ + udelay(60); + cig_cpld_read_register(ADDR_REG_SFP_STATUS_STATUS, &read_status); + DEB2(printk("[66]=%x\n",read_status)); + wait_time_out--; + if(wait_time_out == 0) + break; + }while(read_status != 0x01); + + cig_cpld_read_register(ADDR_REG_SFP_STATUS_RX,reg_data); + DEB2(printk("[64]=%x\n",*reg_data)); + DEB2(printk("<========read=========>")); + + if(wait_time_out == 0) + return -1; + + return 1; +} + + + +struct sock *nlsk = NULL; +extern struct net init_net; +#define NETLINK_TEST 26 +#define MSG_LEN 125 +#define USER_PORT 100 +static u32 irq_present_status_low_current,irq_present_status_low_next; +static u32 irq_present_status_high_current,irq_present_status_high_next; +static u32 irq_tx_fault_status_low_current,irq_tx_fault_status_low_next; +static u32 irq_tx_fault_status_high_current,irq_tx_fault_status_high_next; +static u32 irq_rx_lost_status_low_current,irq_rx_lost_status_low_next; +static u32 irq_rx_lost_status_high_current,irq_rx_lost_status_high_next; + +static u8 irq_present_qsfp_current,irq_present_qsfp_next; +static u8 irq_interrupt_qsfp_current,irq_interrupt_qsfp_next; + +struct input_dev *cpld_input_dev; + + + +int send_usrmsg(char *pbuf, uint16_t len) +{ + struct sk_buff *nl_skb; + struct nlmsghdr *nlh; + + int ret; + + + nl_skb = nlmsg_new(len, GFP_ATOMIC); + if(!nl_skb) + { + printk("netlink alloc failure\n"); + return -1; + } + + + nlh = nlmsg_put(nl_skb, 0, 0, NETLINK_TEST, len, 0); + if(nlh == NULL) + { + printk("nlmsg_put failaure \n"); + nlmsg_free(nl_skb); + return -1; + } + + memcpy(nlmsg_data(nlh), pbuf, len); + ret = netlink_unicast(nlsk, nl_skb, USER_PORT, MSG_DONTWAIT); + + return ret; +} + +static void netlink_rcv_msg(struct sk_buff *skb) +{ + + struct nlmsghdr *nlh = NULL; + char *umsg = NULL; + char kmsg[1024] = {0}; + char kmsg_tmp[16] = {0}; + u8 i = 0; + u8 tmp[3]={0}; + + if(skb->len >= nlmsg_total_size(0)) + { + nlh = nlmsg_hdr(skb); + umsg = NLMSG_DATA(nlh); + if(umsg) + { + for(i = 0;i < 24;i++) + { + if(!(irq_present_status_low_current & (0x1 << i))) + { + tmp[0] = 1; + } + else + { + tmp[0] = 0; + } + + if(!(irq_rx_lost_status_low_current & (0x1 << i))) + { + tmp[1] = 1; + } + else + { + tmp[1] = 0; + } + + if(!(irq_tx_fault_status_low_current & (0x1 << i))) + { + tmp[2] = 1; + } + else + { + tmp[2] = 0; + } + memset(kmsg_tmp,0xff,sizeof(kmsg_tmp)); + sprintf(kmsg_tmp,"sfp%02d:%1d:%1d:%1d ",i+1,tmp[0],tmp[1],tmp[2]); + strcat(kmsg,kmsg_tmp); + } + + for(i = 0;i < 24;i++) + { + if(!(irq_present_status_high_current & (0x1 << i))) + { + tmp[0] = 1; + } + else + { + tmp[0] = 0; + } + + if(!(irq_rx_lost_status_high_current & (0x1 << i))) + { + tmp[1] = 1; + } + else + { + tmp[1] = 0; + } + + if(!(irq_tx_fault_status_high_current & (0x1 << i))) + { + tmp[2] = 1; + } + else + { + tmp[2] = 0; + } + memset(kmsg_tmp,0xff,sizeof(kmsg_tmp)); + sprintf(kmsg_tmp,"sfp%02d:%1d:%1d:%1d ",i+25,tmp[0],tmp[1],tmp[2]); + strcat(kmsg,kmsg_tmp); + } + + + for(i = 0;i < 8;i++) + { + if(!(irq_present_qsfp_current & (0x1 << i))) + { + tmp[0] = 1; + } + else + { + tmp[0] = 0; + } + + if(!(irq_interrupt_qsfp_current & (0x1 << i))) + { + tmp[1] = 1; + } + else + { + tmp[1] = 0; + } + + memset(kmsg_tmp,0xff,sizeof(kmsg_tmp)); + sprintf(kmsg_tmp,"qsfp%02d:%1d:%1d:%1d ",i+49,tmp[0],tmp[1],0); + strcat(kmsg,kmsg_tmp); + } + + printk("kernel recv from user: %s\n", umsg); + send_usrmsg(kmsg, strlen(kmsg)); + } + } + + return ; +} + + + +struct netlink_kernel_cfg cfg = { + .input = netlink_rcv_msg, /* set recv callback */ +}; + + + +#define RANGE_OF_BYTE_SHIFT(to_arg,shift,from_arg) {to_arg &= ~(0xff << shift); to_arg |= from_arg << shift;} + + +static void irq_inter_wapper(struct work_struct * work) +{ + + u8 m_data = 0; + u8 data_high8 = 0,data_low8 = 0; + u16 data_16 = 0; + u8 status = 0; + u8 i = 0; + char kmsg[64]={0}; + u8 tmp[3] = {0}; + + DEB2(printk("CPLD_MASTER_INTERRUPT\r\n")); + + m_data = lpc_iic_getbyte(NULL,CPLD_MASTER_INTERRUPT_STATUS_REG); + lpc_iic_setbyte(NULL,CPLD_MASTER_INTERRUPT_STATUS_REG,0xff); + + cig_cpld_write_slave_cpld_register(CPLD_SLAVE1_INTERRUPT_MASK_REG,0xff); + cig_cpld_write_slave_cpld_register(CPLD_SLAVE2_INTERRUPT_MASK_REG,0xff); + if(!(m_data & CPLD_MASTER_INTERRUPT_CPLD1)) { - if(kthread_should_stop()) + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_INTERRUPT_STATUS_H_REG,&data_high8); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_INTERRUPT_STATUS_L_REG,&data_low8); + data_16 = data_low8 | data_high8 << 8; + if( + !(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT08) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT16) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT24) + ) { - DEB2(printk("threadTask: kthread_should_stop\n")); - break; - } - -#if 1 - get_random_bytes(&lpc_random_data,1); - - lpc_write_data = lpc_random_data; - - lpc_iic_setbyte(NULL,I2C_LPC_REG_TEST,lpc_write_data); - //DEB2(printk("threadTask: lpc write reg[01] data : %02x\n",lpc_write_data)); - - lpc_read_data = lpc_iic_getbyte(NULL,I2C_LPC_REG_TEST); - //DEB2(printk("threadTask: lpc read reg[01] data : %02x\n",lpc_read_data)); - udelay(10000); - if(lpc_write_data != lpc_read_data) + if(!(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT08)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT08\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_PRESENT08_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_low_current,0,status); + + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT16)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT16\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_PRESENT16_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_low_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_PRESENT24)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT24\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_PRESENT24_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_low_current,16,status); + } + DEB2(printk("irq_present_status_low_next = %08x irq_present_status_low_current = %08x \n",irq_present_status_low_next,irq_present_status_low_current)); + } + + if( + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST08) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST16) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST24) + ) { - printk("Error : WRITE %02x != READ %02x\n",lpc_write_data,lpc_read_data); + if(!(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST08)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_RX_LOST08\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_RX_LOST08_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_low_current,0,status); + + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST16)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT16\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_RX_LOST16_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_low_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST24)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_PRESENT24\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_RX_LOST24_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_low_current,16,status); + } + DEB2(printk("irq_rx_lost_status_low_next = %08x irq_rx_lost_status_low_current = %08x \n",irq_rx_lost_status_low_next,irq_rx_lost_status_low_current)); } - msleep(10); -#else - if(temp1_file != NULL) - temp1_file = filp_open(LM75_REAR_LEFT_PATH, O_RDONLY , 0); - if (IS_ERR(temp1_file)) { - printk("error occured while opening file %s, exiting...\n", LM75_REAR_LEFT_PATH); + if( + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST08) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST16) || + !(data_16 & CPLD_SLAVE1_INTERRUPT_RX_LOST24) + ) + { + if(!(data_16 & CPLD_SLAVE1_INTERRUPT_TX_FAULT08)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_TX_FAULT08\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_TX_FAULT08_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_low_current,0,status); + + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_TX_FAULT16)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_TX_FAULT16\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_TX_FAULT16_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_low_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE1_INTERRUPT_TX_FAULT24)) + { + DEB2(printk("CPLD_SLAVE1_INTERRUPT_TX_FAULT24\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE1_TX_FAULT24_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_low_current,16,status); + } + DEB2(printk("irq_tx_fault_status_low_next = %08x irq_tx_fault_status_low_current = %08x \n",irq_tx_fault_status_low_next,irq_tx_fault_status_low_current)); + + } + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_CPLD2)) + { + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_INTERRUPT_STATUS_H_REG,&data_high8); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_INTERRUPT_STATUS_L_REG,&data_low8); + data_16 = data_low8 | data_high8 << 8; + if( + !(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT32) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT40) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT48) + ) + { + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT32)) + { + DEB2(printk("CPLD_SLAVE2_PRESENT32_REG\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_PRESENT32_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_high_current,0,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT40)) + { + DEB2(printk("CPLD_SLAVE2_PRESENT40_REG\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_PRESENT40_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_high_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT48)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT48\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_PRESENT48_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_present_status_high_current,16,status); + } } - if(temp2_file != NULL) - temp2_file = filp_open(LM75_REAR_RIGHT_PATH, O_RDONLY ,0); - if (IS_ERR(temp2_file)) { - printk("error occured while opening file %s, exiting...\n", LM75_REAR_RIGHT_PATH); + if( + !(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST32) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST40) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST48) + ) + { + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST32)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_RX_LOST32\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_RX_LOST32_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_high_current,0,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST40)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT40\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_RX_LOST40_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_high_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_RX_LOST48)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT48\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_RX_LOST48_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_rx_lost_status_high_current,16,status); + } + } + if( + !(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT32) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT40) || + !(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT48) + ) + { + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT32)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_RX_LOST32\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_TX_FAULT32_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_high_current,0,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT40)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT40\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_TX_FAULT40_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_high_current,8,status); + } + else if(!(data_16 & CPLD_SLAVE2_INTERRUPT_TX_FAULT48)) + { + DEB2(printk("CPLD_SLAVE2_INTERRUPT_PRESENT48\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_TX_FAULT48_REG,&status); + RANGE_OF_BYTE_SHIFT(irq_tx_fault_status_high_current,16,status); + } + } - old_fs = get_fs(); - set_fs(KERNEL_DS); + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_PRESENT56)) + { + DEB2(printk("CPLD_SLAVE2_PRESENT56_REG\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_PRESENT56_REG,&status); + irq_present_qsfp_current = status; + } - temp1_file->f_op->read(temp1_file, (char *)temp1_buffer, strlen(temp1_buffer), &temp1_file->f_pos); + if(!(data_16 & CPLD_SLAVE2_INTERRUPT_QSFP_CR56)) + { + DEB2(printk("CPLD_SLAVE2_QSFP_CR56_REG\r\n")); + cig_cpld_read_slave_cpld_register(CPLD_SLAVE2_QSFP_CR56_REG,&status); + irq_interrupt_qsfp_current = status; + } + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_LSW)) + { + DEB2(printk("CPLD_MASTER_INTERRUPT_LSW\r\n")); + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_PSU1)) + { + DEB2(printk("CPLD_MASTER_INTERRUPT_PSU1\r\n")); + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_PSU2)) + { + DEB2(printk("CPLD_MASTER_INTERRUPT_PSU2\r\n")); + } + else if(!(m_data & CPLD_MASTER_INTERRUPT_6320)) + { + DEB2(printk("CPLD_MASTER_INTERRUPT_6320\r\n")); + } + cig_cpld_write_slave_cpld_register(CPLD_SLAVE1_INTERRUPT_MASK_REG,0x0); + cig_cpld_write_slave_cpld_register(CPLD_SLAVE2_INTERRUPT_MASK_REG,0x0); - temp2_file->f_op->read(temp2_file, (char *)temp2_buffer, strlen(temp2_buffer), &temp2_file->f_pos); - - set_fs(old_fs); + memset(tmp,0xff,sizeof(tmp)); - if((simple_strtoul(temp1_buffer,NULL,10) >=30000) || (simple_strtoul(temp2_buffer,NULL,10) >=30000)) + for(i = 0;i < 24;i++) + { + if(!(irq_present_status_low_current & (0x1 << i)) && (irq_present_status_low_next & (0x1 << i))) { - lpc_iic_setbyte(NULL,0x40,0xff); - printk("Full speed\n"); + DEB2(printk("SFP%d is present\r\n",i+1)); + tmp[0] = 1; + } + else if((irq_present_status_low_current & (0x1 << i)) && !(irq_present_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d is absent\r\n",i+1)); + tmp[0] = 0; } - msleep(1000); -#endif + if(!(irq_tx_fault_status_low_current & (0x1 << i)) && (irq_tx_fault_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d transmission is right\r\n",i+1)); + tmp[1] = 1; + } + else if((irq_tx_fault_status_low_current & (0x1 << i)) && !(irq_tx_fault_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d transmission is fault\r\n",i+1)); + tmp[1] = 0; + } + + if(!(irq_rx_lost_status_low_current & (0x1 << i)) && (irq_rx_lost_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d optical is meet\r\n",i+1)); + tmp[2] = 1; + } + else if((irq_rx_lost_status_low_current & (0x1 << i)) && !(irq_rx_lost_status_low_next & (0x1 << i))) + { + DEB2(printk("SFP%d optical is lost\r\n",i+1)); + tmp[2] = 0; + } + + if((tmp[0] != 0xff) || (tmp[1] != 0xff) || (tmp[2] != 0xff)) + { + memset(kmsg,0xff,sizeof(kmsg)); + snprintf(kmsg,sizeof(kmsg),"sfp%02d:%1d:%1d:%1d ",i+1,(tmp[0] == 0xff) ? 0:tmp[0],(tmp[1] == 0xff) ? 0:tmp[1],(tmp[2] == 0xff) ? 0:tmp[2]); + break; + } } -} - -static int init_kernel_Thread(void) -{ - test_TaskStruct=kthread_create(threadTask,NULL,"KernelThead",0); - if(IS_ERR(test_TaskStruct)) + + memset(tmp,0xff,sizeof(tmp)); + for(i = 0;i < 24;i++) { - printk("kthread_create error\n"); + if(!(irq_present_status_high_current & (0x1 << i)) && (irq_present_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d is present\r\n",i+25)); + tmp[0] = 1; + } + else if((irq_present_status_high_current & (0x1 << i)) && !(irq_present_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d is absent\r\n",i+25)); + tmp[0] = 0; + + } + + if(!(irq_rx_lost_status_high_current & (0x1 << i)) && (irq_rx_lost_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d optical is meet\r\n",i+25)); + tmp[1] = 1; + } + else if((irq_rx_lost_status_high_current & (0x1 << i)) && !(irq_rx_lost_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d optical is lost\r\n",i+25)); + tmp[1] = 0; + } + + if(!(irq_tx_fault_status_high_current & (0x1 << i)) && (irq_tx_fault_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d transmission is right\r\n",i+25)); + tmp[2] = 1; + } + else if((irq_tx_fault_status_high_current & (0x1 << i)) && !(irq_tx_fault_status_high_next & (0x1 << i))) + { + DEB2(printk("SFP%d transmission is fault\r\n",i+25)); + tmp[2] = 0; + } + + if((tmp[0] != 0xff) || (tmp[1] != 0xff) || (tmp[2] != 0xff)) + { + memset(kmsg,0xff,sizeof(kmsg)); + snprintf(kmsg,sizeof(kmsg),"sfp%02d:%1d:%1d:%1d ",i+25,(tmp[0] == 0xff) ? 0:tmp[0],(tmp[1] == 0xff) ? 0:tmp[1],(tmp[2] == 0xff) ? 0:tmp[2]); + break; + } } - else + + memset(tmp,0xff,sizeof(tmp)); + for(i = 0 ; i < 8; i++) { - wake_up_process(test_TaskStruct); + if(!(irq_present_qsfp_current & (0x1 << i)) && (irq_present_qsfp_next & (0x1 << i))) + { + DEB2(printk("SFP%d is present\r\n",i+49)); + tmp[0] = 1; + } + else if((irq_present_qsfp_current & (0x1 << i)) && !(irq_present_qsfp_next & (0x1 << i))) + { + DEB2(printk("SFP%d is absent\r\n",i+49)); + tmp[0] = 0; + } + + if(!(irq_interrupt_qsfp_current & (0x1 << i)) && (irq_interrupt_qsfp_next & (0x1 << i))) + { + DEB2(printk("SFP%d interrupt is occured \r\n",i+49)); + tmp[1] = 1; + } + else if((irq_interrupt_qsfp_current & (0x1 << i)) && !(irq_interrupt_qsfp_next & (0x1 << i))) + { + DEB2(printk("SFP%d interrupt is cleaned\r\n",i+49)); + tmp[1] = 0; + } + + if((tmp[0] != 0xff) || (tmp[1] != 0xff)) + { + memset(kmsg,0xff,sizeof(kmsg)); + snprintf(kmsg,sizeof(kmsg),"qsfp%02d:%1d:%1d:%1d ",i+49,(tmp[0] == 0xff) ? 0:tmp[0],(tmp[1] == 0xff) ? 0:tmp[1],0); + break; + } } - return 0; + + + irq_present_status_low_next = irq_present_status_low_current; + irq_rx_lost_status_low_next = irq_rx_lost_status_low_current; + irq_tx_fault_status_low_next = irq_tx_fault_status_low_current; + irq_present_status_high_next = irq_present_status_high_current; + irq_rx_lost_status_high_next = irq_rx_lost_status_high_current; + irq_tx_fault_status_high_next = irq_tx_fault_status_high_current; + irq_present_qsfp_next = irq_present_qsfp_current; + irq_interrupt_qsfp_next = irq_interrupt_qsfp_current; + + send_usrmsg(kmsg, strlen(kmsg)); } -static void exit_kernel_Thread(void) +static void disableIrq(unsigned short maskReg, unsigned short mask) { - kthread_stop(test_TaskStruct); - test_TaskStruct = NULL; + u8 data = 0; + + data = lpc_iic_getbyte(NULL,maskReg); + data |= mask; + lpc_iic_setbyte(NULL,maskReg, data); } -#endif +static void enableIrq(unsigned short maskReg, unsigned short mask) +{ + unsigned short data; + + data = lpc_iic_getbyte(NULL,maskReg); + data &= ~mask; + lpc_iic_setbyte(NULL,maskReg, data); +} + + +static irqreturn_t irq_inter_isr(int irq, void *handle) +{ + + /* + * use keventd context to read the event fifo registers + * Schedule readout at least 25ms after notification for + * REVID < 4 + */ + + schedule_delayed_work(&irq_inter_work, irq_inter_delay); + + return IRQ_HANDLED; +} + + +#define CIG_CPLD_CHR_NAME "cpld" static int __init cpld_init(void) { - int rval,rc; + int rval,rc=0; dev_t dev; - + u8 s_data; + int isr_GPIO_num = 289; + DEB2(printk("cpld_init\n");) +/**************************************************************************************/ + + LPC_INDEX_REG = lpc_base_addr; + LPC_DATA_REG = lpc_base_addr + 1; + cpld_device = kzalloc(sizeof(struct cpld_dev_type), GFP_KERNEL); if (!cpld_device) goto error3; - cpld_device->io_resource = request_region(lpc_base_addr, + cpld_device->io_resource = request_region(lpc_base_addr, lpc_io_space_size, "lpc-i2c"); if (!cpld_device->io_resource) { - DEB2(printk("lpc: claim I/O resource fail\n");) + printk("lpc: claim I/O resource fail\n"); goto error2; } sema_init(&cpld_device->sem, 1); - LPC_INDEX_REG = lpc_base_addr; - LPC_DATA_REG = lpc_base_addr + 1; - - rval = lpc_bus_init(); - rval = lpc_register_driver(&i2c_lpc_driver, 1); - - kobject_set_name(&cpld_kset.kobj, "cpld"); - cpld_kset.kobj.ktype= &cpld_kobj_type; - kset_register(&cpld_kset); - cpld_sysfs_add_attr(&cpld_kset.kobj, "read"); - cpld_sysfs_add_attr(&cpld_kset.kobj, "write"); - cpld_sysfs_add_attr(&cpld_kset.kobj, "version"); - if (cpld_major) { dev = MKDEV(cpld_major, cpld_minor); - rc = register_chrdev_region(dev, 1, "cpld"); + rc = register_chrdev_region(dev, 1, CIG_CPLD_CHR_NAME); } else { - rc = alloc_chrdev_region(&dev, cpld_major, 1, "cpld"); + rc = alloc_chrdev_region(&dev, cpld_major, 1, CIG_CPLD_CHR_NAME); cpld_major = MAJOR(dev); } cpld_setup_cdev(cpld_device); - cpld_class = class_create(THIS_MODULE, KBUILD_MODNAME); + cpld_class = class_create(THIS_MODULE,CIG_CPLD_CHR_NAME); if (!cpld_class) { DEB2(printk("failed to create class\n");) goto error1; } - device_create(cpld_class, NULL, dev, NULL, "cpld"); -#ifdef CPLD_KTHREAD_TEST - init_kernel_Thread(); -#endif - + cpld_class->p->subsys.kobj.ktype= &cpld_kobj_type; + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "read"); + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "write"); + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "reads"); + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "writes"); + cpld_sysfs_add_attr(&cpld_class->p->subsys.kobj, "version"); + + cpld_dev = device_create(cpld_class, NULL, dev, NULL, CIG_CPLD_CHR_NAME); + +/**************************************************************************************/ + + rval = lpc_bus_init(); + rval = lpc_register_driver(&i2c_lpc_driver, 1); + +/**************************************************************************************/ return 0; error1: cdev_del(&cpld_device->cdev); @@ -1572,20 +2155,18 @@ static int __init cpld_init(void) release_resource(cpld_device->io_resource); error3: kfree(cpld_device); - + return rc; } static void __exit cpld_exit(void) { - DEB2(printk("cpld_exit\n")); - - lpc_unregister_driver(&i2c_lpc_driver); - lpc_bus_exit(); -#ifdef CPLD_KTHREAD_TEST - exit_kernel_Thread(); -#endif - dev_t devno = MKDEV(cpld_major, cpld_minor); + + DEB2(printk("cpld_exit\n")); + + lpc_unregister_driver(&i2c_lpc_driver); + lpc_bus_exit(); + dev_t devno = MKDEV(cpld_major, cpld_minor); cdev_del(&cpld_device->cdev); if (cpld_class) { @@ -1593,11 +2174,6 @@ static void __exit cpld_exit(void) class_destroy(cpld_class); } - kobject_put(&cpld_kset.kobj); - - if(cpld_kset.kobj.ktype) - kset_unregister(&cpld_kset); - if (cpld_device) { if (cpld_device->io_resource) release_resource(cpld_device->io_resource); @@ -1622,11 +2198,7 @@ MODULE_DESCRIPTION("cs6436-56p-cpld driver"); MODULE_LICENSE("GPL"); - - - - - +/********************************************** End ********************************************************/ diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-fan.c b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-fan.c old mode 100755 new mode 100644 index 09beb6912c32..33eaaa840305 --- a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-fan.c +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-fan.c @@ -44,6 +44,9 @@ static struct cs6436_56p_fan_data *cs6436_56p_fan_update_device(struct device *d static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, char *buf); static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t set_fan_direction(struct device *dev, struct device_attribute *da, + const char *buf, size_t count); + extern int cig_cpld_write_register(u8 reg_off, u8 val); extern int cig_cpld_read_register(u8 reg_off, u8 *val); @@ -63,6 +66,7 @@ static const u8 fan_reg[] = { 0x47, /* rear fan 3 speed(rpm) */ 0x49, /* rear fan 4 speed(rpm) */ 0x4b, /* rear fan 5 speed(rpm) */ + 0x4c, /* fan direction rear to front or front to rear */ }; @@ -99,6 +103,7 @@ enum sysfs_fan_attributes { FAN3_REAR_SPEED_RPM, FAN4_REAR_SPEED_RPM, FAN5_REAR_SPEED_RPM, + FAN_DIRECTION, FAN1_STATE, FAN2_STATE, FAN3_STATE, @@ -109,6 +114,11 @@ enum sysfs_fan_attributes { FAN3_FAULT, FAN4_FAULT, FAN5_FAULT, + FAN1_DIRECTION, + FAN2_DIRECTION, + FAN3_DIRECTION, + FAN4_DIRECTION, + FAN5_DIRECTION, }; /* Define attributes @@ -131,6 +141,11 @@ enum sysfs_fan_attributes { #define DECLARE_FAN_SPEED_RPM_ATTR(index) &sensor_dev_attr_fan##index##_front_speed_rpm.dev_attr.attr, \ &sensor_dev_attr_fan##index##_rear_speed_rpm.dev_attr.attr +#define DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(index) \ + static SENSOR_DEVICE_ATTR(fan##index##_direction, S_IWUSR | S_IRUGO, fan_show_value, set_fan_direction, FAN##index##_DIRECTION) +#define DECLARE_FAN_DIRECTION_ATTR(index) &sensor_dev_attr_fan##index##_direction.dev_attr.attr + + /* 5 fan state attributes in this platform */ DECLARE_FAN_STATE_SENSOR_DEV_ATTR(1); DECLARE_FAN_STATE_SENSOR_DEV_ATTR(2); @@ -156,6 +171,13 @@ DECLARE_FAN_SPEED_RPM_SENSOR_DEV_ATTR(5); /* 1 fan duty cycle attribute in this platform */ DECLARE_FAN_DUTY_CYCLE_SENSOR_DEV_ATTR(); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(1); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(2); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(3); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(4); +DECLARE_FAN_DIRECTION_SENSOR_DEV_ATTR(5); + + static struct attribute *cs6436_56p_fan_attributes[] = { /* fan related attributes */ DECLARE_FAN_STATE_ATTR(1), @@ -174,6 +196,11 @@ static struct attribute *cs6436_56p_fan_attributes[] = { DECLARE_FAN_SPEED_RPM_ATTR(4), DECLARE_FAN_SPEED_RPM_ATTR(5), DECLARE_FAN_DUTY_CYCLE_ATTR(), + DECLARE_FAN_DIRECTION_ATTR(1), + DECLARE_FAN_DIRECTION_ATTR(2), + DECLARE_FAN_DIRECTION_ATTR(3), + DECLARE_FAN_DIRECTION_ATTR(4), + DECLARE_FAN_DIRECTION_ATTR(5), NULL }; @@ -230,6 +257,7 @@ static u8 is_fan_fault(struct cs6436_56p_fan_data *data, enum fan_id id) return ret; } + static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, const char *buf, size_t count) { @@ -247,6 +275,41 @@ static ssize_t set_duty_cycle(struct device *dev, struct device_attribute *da, return count; } +static ssize_t set_fan_direction(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + int error, value,fan_index; + u8 mask,reg_val; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + fan_index = attr->index - FAN1_DIRECTION; + error = kstrtoint(buf, 10, &value); + if (error) + return error; + + if (!(value == 0 || value == 1)) + return -EINVAL; + + + cig_cpld_read_register(fan_reg[FAN_DIRECTION],®_val); + + if(value == 1) + { + reg_val |= (1 << fan_index); + } + else + { + reg_val &= ~(1 << fan_index); + } + + cig_cpld_write_register(fan_reg[FAN_DIRECTION], reg_val); + + return count; +} + + + + + static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, char *buf) { @@ -300,6 +363,13 @@ static ssize_t fan_show_value(struct device *dev, struct device_attribute *da, case FAN5_FAULT: ret = sprintf(buf, "%d\n", is_fan_fault(data, attr->index - FAN1_FAULT)); break; + case FAN1_DIRECTION: + case FAN2_DIRECTION: + case FAN3_DIRECTION: + case FAN4_DIRECTION: + case FAN5_DIRECTION: + ret = sprintf(buf, "%d\n",reg_val_to_is_state(data->reg_val[FAN_DIRECTION],attr->index - FAN1_DIRECTION)); + break; default: break; } diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-led.c b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-led.c old mode 100755 new mode 100644 diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-psu.c b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-psu.c old mode 100755 new mode 100644 index 8754007408c7..1a4734d4ba25 --- a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-psu.c +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-psu.c @@ -17,265 +17,306 @@ * 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 - - - -#define MAX_FAN_DUTY_CYCLE 100 - -/* Address scanned */ -static const unsigned short normal_i2c[] = {I2C_CLIENT_END }; - -/* This is additional data */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "i2c-algo-lpc.h" + + + +#define MAX_FAN_DUTY_CYCLE 100 + +/* Address scanned */ +static const unsigned short normal_i2c[] = {I2C_CLIENT_END }; + +/* This is additional data */ struct cs6436_56p_psu_data { - struct device *hwmon_dev; - struct mutex update_lock; - char valid; - unsigned long last_updated; /* In jiffies */ - - /* Registers value */ - u8 vout_mode; - u16 v_in; - u16 v_out; - u16 i_in; - u16 i_out; - u16 p_in; - u16 p_out; - u16 temp_input[3]; - u8 temp_fault; - u8 fan_fault; - u16 fan_duty_cycle[2]; - u16 fan_speed[2]; - u8 mfr_id[8]; - u8 mfr_model[20]; - u8 mfr_serial[20]; + struct device *hwmon_dev; + struct mutex update_lock; + char valid; + unsigned long last_updated; /* In jiffies */ + + /* Registers value */ + u8 vout_mode; + u16 v_in; + u16 v_out; + u16 i_in; + u16 i_out; + u16 p_in; + u16 p_out; + u16 temp_input[3]; + u8 temp_fault; + u8 fan_fault; + u16 fan_duty_cycle[2]; + u16 fan_speed[2]; + u8 mfr_id[8]; + u8 mfr_model[20]; + u8 mfr_serial[20]; u8 psu_is_present; u8 psu_is_good; -}; - -static int two_complement_to_int(u16 data, u8 valid_bit, int mask); -static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *dev_attr, const char *buf, size_t count); -static ssize_t for_linear_data(struct device *dev, struct device_attribute *dev_attr, char *buf); -static ssize_t for_fan_fault(struct device *dev, struct device_attribute *dev_attr, char *buf); -static ssize_t for_fan_warning(struct device *dev, struct device_attribute *dev_attr, char *buf); -static ssize_t for_temp_fault(struct device *dev, struct device_attribute *dev_attr, char *buf); -static ssize_t for_temp_warning(struct device *dev, struct device_attribute *dev_attr, char *buf); -static ssize_t for_vout_data(struct device *dev, struct device_attribute *dev_attr, char *buf); + struct i2c_client *client; + struct bin_attribute *bin; /* eeprom data */ +}; + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask); +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute *dev_attr, const char *buf, size_t count); +static ssize_t for_linear_data(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_fan_fault(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_fan_warning(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_temp_fault(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_temp_warning(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_vout_data(struct device *dev, struct device_attribute *dev_attr, char *buf); static int cs6436_56p_psu_read_byte(struct i2c_client *client, u8 reg); static int cs6436_56p_psu_read_word(struct i2c_client *client, u8 reg); static int cs6436_56p_psu_write_word(struct i2c_client *client, u8 reg, u16 value); static int cs6436_56p_psu_read_block(struct i2c_client *client, u8 command, u8 *data, int data_len); static struct cs6436_56p_psu_data *cs6436_56p_psu_update_device(struct device *dev); -static ssize_t for_ascii(struct device *dev, struct device_attribute *dev_attr, char *buf); -static ssize_t for_status(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_ascii(struct device *dev, struct device_attribute *dev_attr, char *buf); +static ssize_t for_status(struct device *dev, struct device_attribute *dev_attr, char *buf); enum cs6436_56p_psu_sysfs_attributes { - PSU_V_IN, - PSU_V_OUT, - PSU_I_IN, - PSU_I_OUT, - PSU_P_IN, - PSU_P_OUT, - PSU_TEMP1_INPUT, - PSU_TEMP2_INPUT, - PSU_TEMP3_INPUT, - PSU_TEMP_FAULT, - PSU_TEMP_WARN, - PSU_FAN1_FAULT, - PSU_FAN1_WARN, - PSU_FAN1_DUTY_CYCLE, - PSU_FAN1_SPEED, - PSU_MFR_ID, - PSU_MFR_MODEL, - PSU_MFR_SERIAL, + PSU_V_IN, + PSU_V_OUT, + PSU_I_IN, + PSU_I_OUT, + PSU_P_IN, + PSU_P_OUT, + PSU_TEMP1_INPUT, + PSU_TEMP2_INPUT, + PSU_TEMP3_INPUT, + PSU_TEMP_FAULT, + PSU_TEMP_WARN, + PSU_FAN1_FAULT, + PSU_FAN1_WARN, + PSU_FAN1_DUTY_CYCLE, + PSU_FAN1_SPEED, + PSU_MFR_ID, + PSU_MFR_MODEL, + PSU_MFR_SERIAL, PSU_PRESENT, PSU_P_GOOD, -}; - -static int two_complement_to_int(u16 data, u8 valid_bit, int mask) -{ - u16 valid_data = data & mask; - - bool is_negative = valid_data >> (valid_bit - 1); - return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; -} - -static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute \ - *dev_attr, const char *buf, size_t count) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); - struct i2c_client *client = to_i2c_client(dev); +}; + +static int two_complement_to_int(u16 data, u8 valid_bit, int mask) +{ + u16 valid_data = data & mask; + + bool is_negative = valid_data >> (valid_bit - 1); + return is_negative ? (-(((~valid_data) & mask) + 1)) : valid_data; +} + +static ssize_t set_fan_duty_cycle(struct device *dev, struct device_attribute \ + *dev_attr, const char *buf, size_t count) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct i2c_client *client = to_i2c_client(dev); struct cs6436_56p_psu_data *data = i2c_get_clientdata(client); - int nr = (attr->index == PSU_FAN1_DUTY_CYCLE) ? 0 : 1; - long speed; - int error; - - error = kstrtol(buf, 10, &speed); - if (error) - return error; - - if (speed < 0 || speed > MAX_FAN_DUTY_CYCLE) - return -EINVAL; - - - mutex_lock(&data->update_lock); - data->fan_duty_cycle[nr] = speed; + int nr = (attr->index == PSU_FAN1_DUTY_CYCLE) ? 0 : 1; + long speed; + int error; + + if (data->valid != 1) + { + return -ENODEV; + } + + error = kstrtol(buf, 10, &speed); + if (error) + return error; + + if (speed < 0 || speed > MAX_FAN_DUTY_CYCLE) + return -EINVAL; + + + mutex_lock(&data->update_lock); + data->fan_duty_cycle[nr] = speed; cs6436_56p_psu_write_word(client, 0x3B + nr, data->fan_duty_cycle[nr]); - mutex_unlock(&data->update_lock); - - return count; -} - -static ssize_t for_linear_data(struct device *dev, struct device_attribute *dev_attr, char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + mutex_unlock(&data->update_lock); + + return count; +} + +static ssize_t for_linear_data(struct device *dev, struct device_attribute *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); struct cs6436_56p_psu_data *data = cs6436_56p_psu_update_device(dev); - - u16 value = 0; - int exponent, mantissa; - int multiplier = 1000; - - switch (attr->index) { - case PSU_V_IN: - value = data->v_in; - break; - case PSU_I_IN: - value = data->i_in; - break; - case PSU_I_OUT: - value = data->i_out; - break; - case PSU_P_IN: - value = data->p_in; - break; - case PSU_P_OUT: - value = data->p_out; - break; - case PSU_TEMP1_INPUT: - value = data->temp_input[0]; - break; - case PSU_TEMP2_INPUT: - value = data->temp_input[1]; - break; - case PSU_TEMP3_INPUT: - value = data->temp_input[2]; - break; - case PSU_FAN1_DUTY_CYCLE: - multiplier = 1; - value = data->fan_duty_cycle[0]; - break; - case PSU_FAN1_SPEED: - multiplier = 1; - value = data->fan_speed[0]; - break; - default: - break; - } - - exponent = two_complement_to_int(value >> 11, 5, 0x1f); - mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); - - return (exponent >= 0) ? sprintf(buf, "%d\n", \ - (mantissa << exponent) * multiplier) : \ - sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); -} - -static ssize_t for_fan_fault(struct device *dev, struct device_attribute \ - *dev_attr, char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); - struct cs6436_56p_psu_data *data = cs6436_56p_psu_update_device(dev); - - u8 shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6; - - return sprintf(buf, "%d\n", data->fan_fault >> shift); -} - -static ssize_t for_fan_warning(struct device *dev, struct device_attribute \ - *dev_attr, char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); - struct cs6436_56p_psu_data *data = cs6436_56p_psu_update_device(dev); - - u8 shift = (attr->index == PSU_FAN1_WARN) ? 5 : 4; - - return sprintf(buf, "%d\n", data->fan_fault >> shift); -} - -static ssize_t for_temp_fault(struct device *dev, struct device_attribute \ - *dev_attr, char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); - struct cs6436_56p_psu_data *data = cs6436_56p_psu_update_device(dev); - - - return sprintf(buf, "%d\n", data->temp_fault >> 7); -} - -static ssize_t for_temp_warning(struct device *dev, struct device_attribute \ - *dev_attr, char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); - struct cs6436_56p_psu_data *data = cs6436_56p_psu_update_device(dev); - - return sprintf(buf, "%d\n", data->temp_fault >> 6); -} -static ssize_t for_vout_data(struct device *dev, struct device_attribute \ - *dev_attr, char *buf) -{ + + u16 value = 0; + int exponent, mantissa; + int multiplier = 1000; + + if (data->valid != 1) + { + return -ENODEV; + } + + switch (attr->index) { + case PSU_V_IN: + value = data->v_in; + break; + case PSU_I_IN: + value = data->i_in; + break; + case PSU_I_OUT: + value = data->i_out; + break; + case PSU_P_IN: + value = data->p_in; + break; + case PSU_P_OUT: + value = data->p_out; + break; + case PSU_TEMP1_INPUT: + value = data->temp_input[0]; + break; + case PSU_TEMP2_INPUT: + value = data->temp_input[1]; + break; + case PSU_TEMP3_INPUT: + value = data->temp_input[2]; + break; + case PSU_FAN1_DUTY_CYCLE: + multiplier = 1; + value = data->fan_duty_cycle[0]; + break; + case PSU_FAN1_SPEED: + multiplier = 1; + value = data->fan_speed[0]; + break; + default: + break; + } + + exponent = two_complement_to_int(value >> 11, 5, 0x1f); + mantissa = two_complement_to_int(value & 0x7ff, 11, 0x7ff); + + return (exponent >= 0) ? \ + sprintf(buf, "%d\n", (mantissa << exponent) * multiplier) :\ + sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent)); +} + +static ssize_t for_fan_fault(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs6436_56p_psu_data *data = cs6436_56p_psu_update_device(dev); + + if (data->valid != 1) + { + return -ENODEV; + } + + u8 shift = (attr->index == PSU_FAN1_FAULT) ? 7 : 6; + + return sprintf(buf, "%d\n", data->fan_fault >> shift); +} + +static ssize_t for_fan_warning(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs6436_56p_psu_data *data = cs6436_56p_psu_update_device(dev); + + if (data->valid != 1) + { + return -ENODEV; + } + + u8 shift = (attr->index == PSU_FAN1_WARN) ? 5 : 4; + + return sprintf(buf, "%d\n", data->fan_fault >> shift); +} + +static ssize_t for_temp_fault(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs6436_56p_psu_data *data = cs6436_56p_psu_update_device(dev); + + if (data->valid != 1) + { + return -ENODEV; + } + + + + return sprintf(buf, "%d\n", data->temp_fault >> 7); +} + +static ssize_t for_temp_warning(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + struct cs6436_56p_psu_data *data = cs6436_56p_psu_update_device(dev); + if (data->valid != 1) + { + return -ENODEV; + } + + + return sprintf(buf, "%d\n", data->temp_fault >> 6); +} +static ssize_t for_vout_data(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ struct cs6436_56p_psu_data *data = cs6436_56p_psu_update_device(dev); - int exponent, mantissa; - int multiplier = 1000; - - exponent = two_complement_to_int(data->vout_mode, 5, 0x1f); - mantissa = data->v_out; - - return (exponent > 0) ? sprintf(buf, "%d\n", \ - (mantissa << exponent) * multiplier) : \ - sprintf(buf, "%d\n", ((mantissa * multiplier) >> (-exponent))); -} - -static ssize_t for_ascii(struct device *dev, struct device_attribute \ - *dev_attr, char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); + int exponent, mantissa; + int multiplier = 1000; + if (data->valid != 1) + { + return -ENODEV; + } + + + exponent = two_complement_to_int(data->vout_mode, 5, 0x1f); + mantissa = data->v_out; + + return (exponent > 0) ? sprintf(buf, "%d\n", \ + (mantissa << exponent) * multiplier) : \ + sprintf(buf, "%d\n", ((mantissa * multiplier) >> (-exponent))); +} + +static ssize_t for_ascii(struct device *dev, struct device_attribute \ + *dev_attr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr); struct cs6436_56p_psu_data *data = cs6436_56p_psu_update_device(dev); - u8 *ptr = NULL; - - if (!data->valid) - return 0; - - switch (attr->index) { - case PSU_MFR_ID: - ptr = data->mfr_id + 1; - break; - case PSU_MFR_MODEL: - ptr = data->mfr_model + 1; - break; - case PSU_MFR_SERIAL: - ptr = data->mfr_serial + 1; - break; - default: - return 0; - } - return sprintf(buf, "%s\n", ptr); -} + u8 *ptr = NULL; + + if (data->valid != 1) + { + return -ENODEV; + } + + switch (attr->index) { + case PSU_MFR_ID: + ptr = data->mfr_id + 1; + break; + case PSU_MFR_MODEL: + ptr = data->mfr_model + 1; + break; + case PSU_MFR_SERIAL: + ptr = data->mfr_serial + 1; + break; + default: + return 0; + } + return sprintf(buf, "%s\n", ptr); +} static ssize_t for_status(struct device *dev, struct device_attribute *dev_attr, char *buf) @@ -286,14 +327,14 @@ static ssize_t for_status(struct device *dev, struct device_attribute *dev_attr, u8 status = 0; - if (!data->valid) { - return -EIO; - } - if (attr->index == PSU_PRESENT) { status = data->psu_is_present; } else { /* PSU_POWER_GOOD */ + if (!data->valid) { + return -ENODEV; + } + status = data->psu_is_good; } @@ -301,286 +342,602 @@ static ssize_t for_status(struct device *dev, struct device_attribute *dev_attr, } - static int cs6436_56p_psu_read_byte(struct i2c_client *client, u8 reg) -{ - return i2c_smbus_read_byte_data(client, reg); -} - +{ + return i2c_smbus_read_byte_data(client, reg); +} + static int cs6436_56p_psu_read_word(struct i2c_client *client, u8 reg) -{ - return i2c_smbus_read_word_data(client, reg); -} - +{ + return i2c_smbus_read_word_data(client, reg); +} + static int cs6436_56p_psu_write_word(struct i2c_client *client, u8 reg, \ - u16 value) -{ - union i2c_smbus_data data; - data.word = value; - return i2c_smbus_xfer(client->adapter, client->addr, - client->flags |= I2C_CLIENT_PEC, - I2C_SMBUS_WRITE, reg, - I2C_SMBUS_WORD_DATA, &data); - -} - + u16 value) +{ + union i2c_smbus_data data; + data.word = value; + return i2c_smbus_xfer(client->adapter, client->addr, + client->flags |= I2C_CLIENT_PEC, + I2C_SMBUS_WRITE, reg, + I2C_SMBUS_WORD_DATA, &data); + +} + static int cs6436_56p_psu_read_block(struct i2c_client *client, u8 command, \ - u8 *data, int data_len) -{ - int result = i2c_smbus_read_i2c_block_data(client, command, data_len, - data); - if (unlikely(result < 0)) - goto abort; - if (unlikely(result != data_len)) { - result = -EIO; - goto abort; - } - - result = 0; -abort: - return result; - -} - -struct reg_data_byte { - u8 reg; - u8 *value; -}; - -struct reg_data_word { - u8 reg; - u16 *value; -}; - -static struct cs6436_56p_psu_data *cs6436_56p_psu_update_device( \ - struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); + u8 *data, int data_len) +{ + int result = i2c_smbus_read_i2c_block_data(client, command, data_len, + data); + if (unlikely(result < 0)) + goto abort; + if (unlikely(result != data_len)) { + result = -EIO; + goto abort; + } + + result = 0; +abort: + return result; + +} + +struct reg_data_byte { + u8 reg; + u8 *value; +}; + +struct reg_data_word { + u8 reg; + u16 *value; +}; + + + +#define EEPROM_NAME "psu_eeprom" +#define EEPROM_SIZE 256 /* 256 byte eeprom */ + +/* Platform dependent --- */ +static ssize_t psu_eeprom_write(struct i2c_client *client, u8 command, const char *data, + int data_len) +{ + int status, retry = 3; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + status = i2c_smbus_write_i2c_block_data(client, command, data_len, data); + if (unlikely(status < 0)) { + msleep(100); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + return status; + } + + return data_len; + +} + + +static ssize_t psu_page_write(struct i2c_client *client,const char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + return count; + } + + /* + * Write data to chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + + + while (count) { + ssize_t status; + + status = psu_eeprom_write(client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + buf += status; + off += status; + count -= status; + retval += status; + } + + + return retval; +} + + + +static ssize_t psu_bin_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + int present; + struct cs6436_56p_psu_data *data; + ssize_t retval = 0; + struct i2c_client *client; + + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + client = to_i2c_client(container_of(kobj, struct device, kobj)); + + mutex_lock(&data->update_lock); + retval = psu_page_write(client, buf, off, count); + mutex_unlock(&data->update_lock); + return retval; +} + + +static ssize_t psu_eeprom_read(struct i2c_client *client, u8 command, u8 *data, + int data_len) +{ + int status, retry = 3; + + if (data_len > I2C_SMBUS_BLOCK_MAX) { + data_len = I2C_SMBUS_BLOCK_MAX; + } + + while (retry) { + status = i2c_smbus_read_i2c_block_data(client, command, data_len, data); + if (unlikely(status < 0)) { + msleep(100); + retry--; + continue; + } + + break; + } + + if (unlikely(status < 0)) { + goto abort; + } + if (unlikely(status != data_len)) { + status = -EIO; + goto abort; + } + +abort: + return status; +} + + + +static ssize_t psu_page_read(struct i2c_client *client,char *buf, loff_t off, size_t count) +{ + ssize_t retval = 0; + + if (unlikely(!count)) { + printk("Count = 0, return"); + return count; + } + /* + * Read data from chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + + + while (count) { + ssize_t status; + + status = psu_eeprom_read(client, off, buf, count); + if (status <= 0) { + if (retval == 0) { + retval = status; + } + break; + } + + buf += status; + off += status; + count -= status; + retval += status; + } + + + return retval; + +} + + +static ssize_t psu_bin_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + int present; + struct cs6436_56p_psu_data *data; + struct i2c_client *client; + ssize_t retval = 0; + + data = dev_get_drvdata(container_of(kobj, struct device, kobj)); + client = to_i2c_client(container_of(kobj, struct device, kobj)); + mutex_lock(&data->update_lock); + retval = psu_page_read(client, buf, off, count); + mutex_unlock(&data->update_lock); + + return retval; +} + + + +static int psu_sysfs_eeprom_init(struct kobject *kobj, struct bin_attribute *eeprom) +{ + int err; + + sysfs_bin_attr_init(eeprom); + eeprom->attr.name = EEPROM_NAME; + eeprom->attr.mode = S_IWUSR | S_IRUGO; + eeprom->read = psu_bin_read; + eeprom->write = psu_bin_write; + eeprom->size = EEPROM_SIZE; + + /* Create eeprom file */ + err = sysfs_create_bin_file(kobj, eeprom); + if (err) { + return err; + } + + return 0; +} + + +static int psu_sysfs_eeprom_cleanup(struct kobject *kobj, struct bin_attribute *eeprom) +{ + sysfs_remove_bin_file(kobj, eeprom); + return 0; +} + + +static int psu_i2c_check_functionality(struct i2c_client *client) +{ + return i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_I2C_BLOCK); +} + + + +static int psu_eeprom_probe(struct i2c_client *client, const struct i2c_device_id *dev_id) +{ + int status; + + struct cs6436_56p_psu_data *data; + + if (!psu_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + mutex_init(&data->update_lock); + + data->bin = kzalloc(sizeof(struct bin_attribute), GFP_KERNEL); + if (!data->bin) { + status = -ENOMEM; + goto eeprom_bin_error; + } + + /* init eeprom */ + status = psu_sysfs_eeprom_init(&client->dev.kobj, data->bin); + if (status) { + status = -ENOMEM; + goto sys_init_error; + } + + dev_info(&client->dev, "psu eeprom '%s'\n", client->name); + + return 0; + + sys_init_error: + kfree(data->bin); + + eeprom_bin_error: + kfree(data); + + exit: + return status; +} + + + + +static struct cs6436_56p_psu_data *cs6436_56p_psu_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); struct cs6436_56p_psu_data *data = i2c_get_clientdata(client); - - mutex_lock(&data->update_lock); - - - if (time_after(jiffies, data->last_updated)) { - int i, status; - u8 command; - struct reg_data_byte regs_byte[] = { - {0x20, &data->vout_mode}, - {0x81, &data->fan_fault}, - {0x7d, &data->temp_fault}, - }; - struct reg_data_word regs_word[] = { - {0x88, &data->v_in}, - {0x8b, &data->v_out}, - {0x89, &data->i_in}, - {0x8c, &data->i_out}, - {0x96, &data->p_out}, - {0x97, &data->p_in}, - {0x8d, &(data->temp_input[0])}, - {0x8e, &(data->temp_input[1])}, - {0x8f, &(data->temp_input[2])}, - {0x3b, &(data->fan_duty_cycle[0])}, - {0x90, &(data->fan_speed[0])}, - }; - - dev_dbg(&client->dev, "start data update\n"); - - /* one milliseconds from now */ - data->last_updated = jiffies + HZ / 1000; - - for (i = 0; i < ARRAY_SIZE(regs_byte); i++) { - status = cs6436_56p_psu_read_byte(client, - regs_byte[i].reg); - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", - regs_byte[i].reg, status); - } else { - *(regs_byte[i].value) = status; - } - } - - for (i = 0; i < ARRAY_SIZE(regs_word); i++) { + + + mutex_lock(&data->update_lock); + + + if (time_after(jiffies, data->last_updated)) { + int i, status; + u8 command; + struct reg_data_byte regs_byte[] = { + {0x20, &data->vout_mode}, + {0x81, &data->fan_fault}, + {0x7d, &data->temp_fault}, + }; + struct reg_data_word regs_word[] = { + {0x88, &data->v_in}, + {0x8b, &data->v_out}, + {0x89, &data->i_in}, + {0x8c, &data->i_out}, + {0x96, &data->p_out}, + {0x97, &data->p_in}, + {0x8d, &(data->temp_input[0])}, + {0x8e, &(data->temp_input[1])}, + {0x3b, &(data->fan_duty_cycle[0])}, + {0x90, &(data->fan_speed[0])}, + }; + data->valid = 1; + + dev_dbg(&client->dev, "start data update\n"); + + /* one milliseconds from now */ + data->last_updated = jiffies + HZ / 1000; + + for (i = 0; i < ARRAY_SIZE(regs_byte); i++) { + status = cs6436_56p_psu_read_byte(client, + regs_byte[i].reg); + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_byte[i].reg, status); + *(regs_byte[i].value) = 0; + data->valid = 0; + } else { + *(regs_byte[i].value) = status; + } + } + + for (i = 0; i < ARRAY_SIZE(regs_word); i++) { status = cs6436_56p_psu_read_word(client, - regs_word[i].reg); - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", - regs_word[i].reg, status); - } else { - *(regs_word[i].value) = status; - } - } - - command = 0x99; /* PSU mfr_id */ - status = cs6436_56p_psu_read_block(client, command, - data->mfr_id, ARRAY_SIZE(data->mfr_id) - 1); - data->mfr_id[ARRAY_SIZE(data->mfr_id) - 1] = '\0'; - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - } - - command = 0x9a; /* PSU mfr_model */ - status = cs6436_56p_psu_read_block(client, command, - data->mfr_model, ARRAY_SIZE(data->mfr_model) - 1); - data->mfr_model[ARRAY_SIZE(data->mfr_model) - 1] = '\0'; - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - } - - command = 0x9e; /* PSU mfr_serial */ - status = cs6436_56p_psu_read_block(client, command, - data->mfr_serial, ARRAY_SIZE(data->mfr_serial) - 1); - data->mfr_serial[ARRAY_SIZE(data->mfr_serial) - 1] = '\0'; - if (status < 0) { - dev_dbg(&client->dev, "reg %d, err %d\n", command, status); - } - data->valid = 1; + regs_word[i].reg); + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", + regs_word[i].reg, status); + *(regs_word[i].value) = 0; + data->valid = 0; + } else { + *(regs_word[i].value) = status; + } + } + + command = 0x99; /* PSU mfr_id */ + status = cs6436_56p_psu_read_block(client, command, + data->mfr_id, ARRAY_SIZE(data->mfr_id) - 1); + data->mfr_id[ARRAY_SIZE(data->mfr_id) - 1] = '\0'; + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + memset(data->mfr_id, 0, sizeof(data->mfr_id)); + data->valid = 0; + } + + command = 0x9a; /* PSU mfr_model */ + status = cs6436_56p_psu_read_block(client, command, + data->mfr_model, ARRAY_SIZE(data->mfr_model) - 1); + data->mfr_model[ARRAY_SIZE(data->mfr_model) - 1] = '\0'; + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + memset(data->mfr_model, 0, sizeof(data->mfr_id)); + data->valid = 0; + } + + command = 0x9e; /* PSU mfr_serial */ + status = cs6436_56p_psu_read_block(client, command, + data->mfr_serial, ARRAY_SIZE(data->mfr_serial) - 1); + data->mfr_serial[ARRAY_SIZE(data->mfr_serial) - 1] = '\0'; + if (status < 0) { + dev_dbg(&client->dev, "reg %d, err %d\n", command, status); + memset(data->mfr_serial, 0, sizeof(data->mfr_id)); + data->valid = 0; + } + data->psu_is_present = strlen(data->mfr_id) > 1 ? 1:0; if(data->psu_is_present) + { data->psu_is_good = ((data->fan_fault) || (data->temp_fault))? 0:1; - else + } + else + { + data->valid = 0; data->psu_is_good = 0; - } - - mutex_unlock(&data->update_lock); - - return data; - -} - -/* sysfs attributes for hwmon */ -static SENSOR_DEVICE_ATTR(psu_v_in, S_IRUGO, for_linear_data, NULL, PSU_V_IN); -static SENSOR_DEVICE_ATTR(psu_v_out, S_IRUGO, for_vout_data, NULL, PSU_V_OUT); -static SENSOR_DEVICE_ATTR(psu_i_in, S_IRUGO, for_linear_data, NULL, PSU_I_IN); -static SENSOR_DEVICE_ATTR(psu_i_out, S_IRUGO, for_linear_data, NULL, PSU_I_OUT); -static SENSOR_DEVICE_ATTR(psu_p_in, S_IRUGO, for_linear_data, NULL, PSU_P_IN); -static SENSOR_DEVICE_ATTR(psu_p_out, S_IRUGO, for_linear_data, NULL, PSU_P_OUT); -static SENSOR_DEVICE_ATTR(psu_temp1_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP1_INPUT); -static SENSOR_DEVICE_ATTR(psu_temp2_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP2_INPUT); -static SENSOR_DEVICE_ATTR(psu_temp3_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP3_INPUT); -static SENSOR_DEVICE_ATTR(psu_temp_fault, S_IRUGO, for_temp_fault, NULL, PSU_TEMP_FAULT); -static SENSOR_DEVICE_ATTR(psu_temp_warning, S_IRUGO, for_temp_warning, NULL, PSU_TEMP_WARN); -static SENSOR_DEVICE_ATTR(psu_fan1_fault, S_IRUGO, for_fan_fault, NULL, PSU_FAN1_FAULT); -static SENSOR_DEVICE_ATTR(psu_fan1_warning, S_IRUGO, for_fan_warning, NULL, PSU_FAN1_WARN); -static SENSOR_DEVICE_ATTR(psu_fan1_duty_cycle_percentage, S_IWUSR | S_IRUGO, for_linear_data, set_fan_duty_cycle, PSU_FAN1_DUTY_CYCLE); -static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm, S_IRUGO, for_linear_data, NULL, PSU_FAN1_SPEED); -static SENSOR_DEVICE_ATTR(psu_mfr_id, S_IRUGO, for_ascii, NULL, PSU_MFR_ID); -static SENSOR_DEVICE_ATTR(psu_mfr_model, S_IRUGO, for_ascii, NULL, PSU_MFR_MODEL); -static SENSOR_DEVICE_ATTR(psu_mfr_serial, S_IRUGO, for_ascii, NULL, PSU_MFR_SERIAL); + } + } + + mutex_unlock(&data->update_lock); + + return data; + +} + +/* sysfs attributes for hwmon */ +static SENSOR_DEVICE_ATTR(psu_v_in, S_IRUGO, for_linear_data, NULL, PSU_V_IN); +static SENSOR_DEVICE_ATTR(psu_v_out, S_IRUGO, for_vout_data, NULL, PSU_V_OUT); +static SENSOR_DEVICE_ATTR(psu_i_in, S_IRUGO, for_linear_data, NULL, PSU_I_IN); +static SENSOR_DEVICE_ATTR(psu_i_out, S_IRUGO, for_linear_data, NULL, PSU_I_OUT); +static SENSOR_DEVICE_ATTR(psu_p_in, S_IRUGO, for_linear_data, NULL, PSU_P_IN); +static SENSOR_DEVICE_ATTR(psu_p_out, S_IRUGO, for_linear_data, NULL, PSU_P_OUT); +static SENSOR_DEVICE_ATTR(psu_temp1_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP1_INPUT); +static SENSOR_DEVICE_ATTR(psu_temp2_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP2_INPUT); +static SENSOR_DEVICE_ATTR(psu_temp3_input, S_IRUGO, for_linear_data, NULL, PSU_TEMP3_INPUT); +static SENSOR_DEVICE_ATTR(psu_temp_fault, S_IRUGO, for_temp_fault, NULL, PSU_TEMP_FAULT); +static SENSOR_DEVICE_ATTR(psu_temp_warning, S_IRUGO, for_temp_warning, NULL, PSU_TEMP_WARN); +static SENSOR_DEVICE_ATTR(psu_fan1_fault, S_IRUGO, for_fan_fault, NULL, PSU_FAN1_FAULT); +static SENSOR_DEVICE_ATTR(psu_fan1_warning, S_IRUGO, for_fan_warning, NULL, PSU_FAN1_WARN); +static SENSOR_DEVICE_ATTR(psu_fan1_duty_cycle_percentage, S_IWUSR | S_IRUGO, for_linear_data, set_fan_duty_cycle, PSU_FAN1_DUTY_CYCLE); +static SENSOR_DEVICE_ATTR(psu_fan1_speed_rpm, S_IRUGO, for_linear_data, NULL, PSU_FAN1_SPEED); +static SENSOR_DEVICE_ATTR(psu_mfr_id, S_IRUGO, for_ascii, NULL, PSU_MFR_ID); +static SENSOR_DEVICE_ATTR(psu_mfr_model, S_IRUGO, for_ascii, NULL, PSU_MFR_MODEL); +static SENSOR_DEVICE_ATTR(psu_mfr_serial, S_IRUGO, for_ascii, NULL, PSU_MFR_SERIAL); static SENSOR_DEVICE_ATTR(psu_present, S_IRUGO, for_status, NULL, PSU_PRESENT); static SENSOR_DEVICE_ATTR(psu_power_good, S_IRUGO, for_status, NULL, PSU_P_GOOD); - + static struct attribute *cs6436_56p_psu_attributes[] = { - &sensor_dev_attr_psu_v_in.dev_attr.attr, - &sensor_dev_attr_psu_v_out.dev_attr.attr, - &sensor_dev_attr_psu_i_in.dev_attr.attr, - &sensor_dev_attr_psu_i_out.dev_attr.attr, - &sensor_dev_attr_psu_p_in.dev_attr.attr, - &sensor_dev_attr_psu_p_out.dev_attr.attr, - &sensor_dev_attr_psu_temp1_input.dev_attr.attr, - &sensor_dev_attr_psu_temp2_input.dev_attr.attr, - &sensor_dev_attr_psu_temp3_input.dev_attr.attr, - &sensor_dev_attr_psu_temp_fault.dev_attr.attr, - &sensor_dev_attr_psu_temp_warning.dev_attr.attr, - &sensor_dev_attr_psu_fan1_fault.dev_attr.attr, - &sensor_dev_attr_psu_fan1_warning.dev_attr.attr, - &sensor_dev_attr_psu_fan1_duty_cycle_percentage.dev_attr.attr, - &sensor_dev_attr_psu_fan1_speed_rpm.dev_attr.attr, - &sensor_dev_attr_psu_mfr_id.dev_attr.attr, - &sensor_dev_attr_psu_mfr_model.dev_attr.attr, - &sensor_dev_attr_psu_mfr_serial.dev_attr.attr, + &sensor_dev_attr_psu_v_in.dev_attr.attr, + &sensor_dev_attr_psu_v_out.dev_attr.attr, + &sensor_dev_attr_psu_i_in.dev_attr.attr, + &sensor_dev_attr_psu_i_out.dev_attr.attr, + &sensor_dev_attr_psu_p_in.dev_attr.attr, + &sensor_dev_attr_psu_p_out.dev_attr.attr, + &sensor_dev_attr_psu_temp1_input.dev_attr.attr, + &sensor_dev_attr_psu_temp2_input.dev_attr.attr, + &sensor_dev_attr_psu_temp3_input.dev_attr.attr, + &sensor_dev_attr_psu_temp_fault.dev_attr.attr, + &sensor_dev_attr_psu_temp_warning.dev_attr.attr, + &sensor_dev_attr_psu_fan1_fault.dev_attr.attr, + &sensor_dev_attr_psu_fan1_warning.dev_attr.attr, + &sensor_dev_attr_psu_fan1_duty_cycle_percentage.dev_attr.attr, + &sensor_dev_attr_psu_fan1_speed_rpm.dev_attr.attr, + &sensor_dev_attr_psu_mfr_id.dev_attr.attr, + &sensor_dev_attr_psu_mfr_model.dev_attr.attr, + &sensor_dev_attr_psu_mfr_serial.dev_attr.attr, &sensor_dev_attr_psu_present.dev_attr.attr, &sensor_dev_attr_psu_power_good.dev_attr.attr, - NULL -}; - + NULL +}; + static const struct attribute_group cs6436_56p_psu_group = { .attrs = cs6436_56p_psu_attributes, -}; - -static int cs6436_56p_psu_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ +}; + + +static int psu_register_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int status; + + struct cs6436_56p_psu_data *data; - int status; - - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) { - status = -EIO; - goto exit; - } - - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) { - status = -ENOMEM; - goto exit; - } - - i2c_set_clientdata(client, data); - data->valid = 0; - mutex_init(&data->update_lock); - - dev_info(&client->dev, "new chip found\n"); - - /* Register sysfs hooks */ + + if (!psu_i2c_check_functionality(client)) { + status = -EIO; + goto exit; + } + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) { + status = -ENOMEM; + goto exit; + } + + i2c_set_clientdata(client, data); + data->valid = 0; + mutex_init(&data->update_lock); + + /* Register sysfs hooks */ status = sysfs_create_group(&client->dev.kobj, &cs6436_56p_psu_group); - if (status) - goto exit_sysfs_create_group; - - data->hwmon_dev = hwmon_device_register(&client->dev); - if (IS_ERR(data->hwmon_dev)) { - status = PTR_ERR(data->hwmon_dev); - goto exit_hwmon_device_register; - } - - return 0; - -exit_hwmon_device_register: - sysfs_remove_group(&client->dev.kobj, &cs6436_56p_psu_group); -exit_sysfs_create_group: - kfree(data); -exit: - return status; -} - + if (status) + goto exit_sysfs_create_group; + + cs6436_56p_sysfs_add_client(client); + + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + status = PTR_ERR(data->hwmon_dev); + goto exit_hwmon_device_register; + } + + /* init eeprom */ + + return 0; + + exit_hwmon_device_register: + sysfs_remove_group(&client->dev.kobj, &cs6436_56p_psu_group); + exit_sysfs_create_group: + kfree(data); + exit: + return status; + +} + + +static int cs6436_56p_psu_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int status; + + if((client->addr == 0x52) ||(client->addr == 0x53)) + { + status = psu_eeprom_probe(client, id); + } + else if((client->addr == 0x5a) ||(client->addr == 0x5b)) + { + status = psu_register_probe(client, id); + } + return status; +} + static int cs6436_56p_psu_remove(struct i2c_client *client) -{ - struct cs6436_56p_psu_data *data = i2c_get_clientdata(client); - hwmon_device_unregister(data->hwmon_dev); - sysfs_remove_group(&client->dev.kobj, &cs6436_56p_psu_group); - kfree(data); - - return 0; -} - -enum psu_index -{ +{ + cs6436_56p_sysfs_remove_client(client); + + if((client->addr == 0x52) ||(client->addr == 0x53)) + { + struct cs6436_56p_psu_data *data; + data = i2c_get_clientdata(client); + psu_sysfs_eeprom_cleanup(&client->dev.kobj,data->bin); + kfree(data); + } + else if((client->addr == 0x5a) ||(client->addr == 0x5b)) + { + struct cs6436_56p_psu_data *data; + data = i2c_get_clientdata(client); + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &cs6436_56p_psu_group); + kfree(data); + } + + return 0; +} + +enum psu_index +{ cs6436_56p_psu1, cs6436_56p_psu2 -}; - +}; + static const struct i2c_device_id cs6436_56p_psu_id[] = { { "cs6436_56p_psu1", cs6436_56p_psu1 }, { "cs6436_56p_psu2", cs6436_56p_psu2 }, - {} -}; + {} +}; MODULE_DEVICE_TABLE(i2c, cs6436_56p_psu_id); - + static struct i2c_driver cs6436_56p_psu_driver = { - .class = I2C_CLASS_HWMON, - .driver = { + .class = I2C_CLASS_HWMON, + .driver = { .name = "cs6436_56p_psu", - }, + }, .probe = cs6436_56p_psu_probe, .remove = cs6436_56p_psu_remove, .id_table = cs6436_56p_psu_id, - .address_list = normal_i2c, -}; + .address_list = normal_i2c, +}; module_i2c_driver(cs6436_56p_psu_driver); - -MODULE_AUTHOR("Zhang Peng "); + +MODULE_AUTHOR("Zhang Peng "); MODULE_DESCRIPTION("cs6436_56p_psu driver"); MODULE_LICENSE("GPL"); diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-sfp.c b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-sfp.c old mode 100755 new mode 100644 index f2b54a260fcb..5665fa33048b --- a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-sfp.c +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-sfp.c @@ -28,6 +28,7 @@ #include #include #include +#include "i2c-algo-lpc.h" #define DRIVER_NAME "cs6436_56p_sfp" /* Platform dependent */ @@ -64,15 +65,9 @@ #define SFF8436_RX_LOS_ADDR 3 #define SFF8436_TX_FAULT_ADDR 4 #define SFF8436_TX_DISABLE_ADDR 86 - - -#define ADDR_REG_SFP_STATUS_ADDR 0X62 //reg addr +R/W# //1031 -#define ADDR_REG_SFP_STATUS_TX 0X63 // write data -#define ADDR_REG_SFP_STATUS_RX 0X64 //read data -#define ADDR_REG_SFP_STATUS_COMMAND 0X65 //cmd bit7=1,go -#define ADDR_REG_SFP_STATUS_STATUS 0X66 //status - - +#define QSFP_RESET_ADDR 0x1b +#define QSFP_INTER_ADDR 0x1a +#define QSFP_LPMODE_ADDR 0x1c static ssize_t show_port_number(struct device *dev, struct device_attribute *da, char *buf); static ssize_t show_port_type(struct device *dev, struct device_attribute *da, char *buf); @@ -87,6 +82,11 @@ static ssize_t sfp_eeprom_write(struct i2c_client *, u8 , const char *,int); extern int cig_cpld_read_register(u8 reg_off, u8 *val); extern int cig_cpld_write_register(u8 reg_off, u8 val); +static ssize_t qsfp_reset_read(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_reset_write(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t qsfp_inter_read(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_lpmode_read(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t qsfp_lpmode_write(struct device *dev, struct device_attribute *da, const char *buf, size_t count); enum sfp_sysfs_attributes { PRESENT, @@ -109,7 +109,10 @@ enum sfp_sysfs_attributes { RX_LOS2, RX_LOS3, RX_LOS4, - RX_LOS_ALL + RX_LOS_ALL, + QSFPRESET, + QSFPINT, + QSFPLPMODE }; /* SFP/QSFP common attributes for sysfs */ @@ -134,6 +137,9 @@ static SENSOR_DEVICE_ATTR(sfp_tx_fault1, S_IRUGO, qsfp_show_tx_rx_status, NULL, static SENSOR_DEVICE_ATTR(sfp_tx_fault2, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT2); static SENSOR_DEVICE_ATTR(sfp_tx_fault3, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT3); static SENSOR_DEVICE_ATTR(sfp_tx_fault4, S_IRUGO, qsfp_show_tx_rx_status, NULL, TX_FAULT4); +static SENSOR_DEVICE_ATTR(sfp_reset, S_IWUSR | S_IRUGO, qsfp_reset_read, qsfp_reset_write, QSFPRESET); +static SENSOR_DEVICE_ATTR(sfp_inter, S_IRUGO, qsfp_inter_read, NULL, QSFPINT); +static SENSOR_DEVICE_ATTR(sfp_lpmode, S_IWUSR | S_IRUGO, qsfp_lpmode_read, qsfp_lpmode_write, QSFPLPMODE); static struct attribute *qsfp_attributes[] = { &sensor_dev_attr_sfp_port_number.dev_attr.attr, &sensor_dev_attr_sfp_port_type.dev_attr.attr, @@ -154,6 +160,9 @@ static struct attribute *qsfp_attributes[] = { &sensor_dev_attr_sfp_tx_fault2.dev_attr.attr, &sensor_dev_attr_sfp_tx_fault3.dev_attr.attr, &sensor_dev_attr_sfp_tx_fault4.dev_attr.attr, + &sensor_dev_attr_sfp_reset.dev_attr.attr, + &sensor_dev_attr_sfp_inter.dev_attr.attr, + &sensor_dev_attr_sfp_lpmode.dev_attr.attr, NULL }; @@ -342,13 +351,13 @@ static ssize_t show_port_number(struct device *dev, struct device_attribute *da, return sprintf(buf, "%d\n", CPLD_PORT_TO_FRONT_PORT(data->port)); } -#define WAIT_TIME_OUT_COUNT 100 + static int cig_cpld_write_sfp_register(u8 sfp_reg_addr, u8 sfp_write_reg_data) { u8 sfp_read_status = 0; u8 wait_time_out = WAIT_TIME_OUT_COUNT; - + cig_cpld_write_register(ADDR_REG_SFP_STATUS_ADDR, sfp_reg_addr << 1); cig_cpld_write_register(ADDR_REG_SFP_STATUS_TX, sfp_write_reg_data); cig_cpld_write_register(ADDR_REG_SFP_STATUS_COMMAND, 0x80); @@ -371,7 +380,7 @@ static int cig_cpld_read_sfp_register(u8 sfp_reg_addr, u8 *sfp_read_reg_data) { u8 sfp_read_status = 0; u8 wait_time_out = WAIT_TIME_OUT_COUNT; - + cig_cpld_write_register(ADDR_REG_SFP_STATUS_ADDR, sfp_reg_addr << 1 | 1); cig_cpld_write_register(ADDR_REG_SFP_STATUS_COMMAND, 0x80); do{ @@ -393,7 +402,7 @@ static int cig_cpld_read_sfp_register(u8 sfp_reg_addr, u8 *sfp_read_reg_data) - + /* Platform dependent +++ */ static struct sfp_port_data *sfp_update_present(struct i2c_client *client) @@ -411,7 +420,7 @@ static struct sfp_port_data *sfp_update_present(struct i2c_client *client) /* Read present status of port 1~48(SFP port) */ for (i = 0; i < 6; i++) { cpld_reg_addr = 1 + i; - + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); if (unlikely(status < 0)) { @@ -420,8 +429,8 @@ static struct sfp_port_data *sfp_update_present(struct i2c_client *client) } data->present |= (u64)cpld_reg_data << (i*8); - - DEBUG_PRINT("Present status = 0x%lx\r\n", data->present); + + DEBUG_PRINT("Present status = 0x%lx\r\n", data->present); } /* Read present status of port 49-56(QSFP port) */ @@ -433,7 +442,7 @@ static struct sfp_port_data *sfp_update_present(struct i2c_client *client) } else { data->present |= (u64)cpld_reg_data << 48; - } + } DEBUG_PRINT("Present status = 0x%lx", data->present); exit: @@ -463,7 +472,7 @@ static struct sfp_port_data *sfp_update_tx_rx_status(struct device *dev) /* Read status of port 1~48(SFP port) */ for (i = 0; i < 6; i++) { cpld_reg_addr = 13+i; - + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); if (unlikely(status < 0)) { dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status); @@ -471,14 +480,14 @@ static struct sfp_port_data *sfp_update_tx_rx_status(struct device *dev) } data->msa->status[0] |= (u64)cpld_reg_data << (i * 8); - - DEBUG_PRINT("tx rx status[0] = 0x%lx\r\n", data->msa->status[0]); + + DEBUG_PRINT("tx rx status[0] = 0x%lx\r\n", data->msa->status[0]); } - + for (i = 0; i < 6; i++) { cpld_reg_addr = 19+i; - + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); if (unlikely(status < 0)) { dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status); @@ -486,13 +495,13 @@ static struct sfp_port_data *sfp_update_tx_rx_status(struct device *dev) } data->msa->status[1] |= (u64)cpld_reg_data << (i * 8); - - DEBUG_PRINT("tx rx status[1] = 0x%lx\r\n", data->msa->status[1]); + + DEBUG_PRINT("tx rx status[1] = 0x%lx\r\n", data->msa->status[1]); } for (i = 0; i < 6; i++) { cpld_reg_addr = 7+i; - + status = cig_cpld_read_sfp_register(cpld_reg_addr, &cpld_reg_data); if (unlikely(status < 0)) { dev_dbg(&client->dev, "cpld(0x%x) reg(0x%x) err %d\n", cpld_reg_addr, cpld_reg_data, status); @@ -500,8 +509,8 @@ static struct sfp_port_data *sfp_update_tx_rx_status(struct device *dev) } data->msa->status[2] |= (u64)cpld_reg_data << (i * 8); - - DEBUG_PRINT("tx rx status[2] = 0x%lx\r\n", data->msa->status[2]); + + DEBUG_PRINT("tx rx status[2] = 0x%lx\r\n", data->msa->status[2]); } data->msa->valid = 1; @@ -531,12 +540,12 @@ static ssize_t sfp_set_tx_disable(struct device *dev, struct device_attribute *d } mutex_lock(&data->update_lock); - + udelay(6000); if(data->port <= 48) { cpld_reg_addr = 19 + data->port / 8; - cpld_reg_bit = 1 << (data->port); + cpld_reg_bit = 1 << ((data->port) % 8); } /* Read current status */ @@ -548,10 +557,10 @@ static ssize_t sfp_set_tx_disable(struct device *dev, struct device_attribute *d cpld_reg_data |= cpld_reg_bit; } else { - data->msa->status[1] &= ~BIT_INDEX(data->port); + data->msa->status[1] &= ~ BIT_INDEX(data->port); cpld_reg_data &= ~cpld_reg_bit; } - + error = cig_cpld_write_sfp_register(cpld_reg_addr,cpld_reg_data); mutex_unlock(&data->update_lock); @@ -582,7 +591,7 @@ static ssize_t show_present(struct device *dev, struct device_attribute *da, int i; u8 values[7] = {0}; struct sfp_port_data *data = sfp_update_present(client); - + if (IS_ERR(data)) { return PTR_ERR(data); } @@ -682,7 +691,7 @@ static ssize_t show_port_type(struct device *dev, struct device_attribute *da, char *buf) { struct i2c_client *client = to_i2c_client(dev); - struct sfp_port_data *data = i2c_get_clientdata(client); + struct sfp_port_data *data = i2c_get_clientdata(client); int present = sfp_is_port_present(client, data->port); if (IS_ERR_VALUE(present)) { @@ -750,6 +759,253 @@ static struct sfp_port_data *qsfp_update_tx_rx_status(struct device *dev) return (status < 0) ? ERR_PTR(status) : data; } +static ssize_t qsfp_inter_read(struct device *dev, struct device_attribute *da, char *buf) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_INTER_ADDR, &cpld_reg_data); + index = data->port - 48; + index = 1 << index; + val = (cpld_reg_data & index) > 0 ? 1 : 0; + + printk("inter read:data->port = %d, index = %hhu, cpld_reg_data = %hhu\n", data->port, index, cpld_reg_data); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", val); +} + + +static ssize_t qsfp_reset_read(struct device *dev, struct device_attribute *da, char *buf) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_RESET_ADDR, &cpld_reg_data); + index = data->port - 48; + index = 1 << index; + val = (cpld_reg_data & index) > 0 ? 1 : 0; + + printk("reset read:data->port = %d, index = %hhu, cpld_reg_data = %hhu\n", data->port, index, cpld_reg_data); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", val); +} + +static ssize_t qsfp_reset_write(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + long usrdata; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + ret = kstrtol(buf, 10, &usrdata); + if (ret) { + return ret; + } + + usrdata = usrdata > 0 ? 1 : 0; + index = data->port - 48; + + DEBUG_PRINT("usrdata = %u, index = %hhu\n", usrdata, index); + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_RESET_ADDR, &cpld_reg_data); + if (ret == 1) + { + + DEBUG_PRINT("cpld_reg_data = %x\n", cpld_reg_data); + cpld_reg_data &= ~(1 << index); + cpld_reg_data |= usrdata << index; + + DEBUG_PRINT("cpld_reg_data = %x\n", cpld_reg_data); + ret = cig_cpld_write_sfp_register(QSFP_RESET_ADDR, cpld_reg_data); + if (1 != ret) + { + DEBUG_PRINT("write failed\n"); + } + } + else + { + DEBUG_PRINT("read failed\n"); + } + + mutex_unlock(&data->update_lock); + + if (ret != 1) + return -1; + + return count; +} + + + + +static ssize_t qsfp_lpmode_read(struct device *dev, struct device_attribute *da, char *buf) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_LPMODE_ADDR, &cpld_reg_data); + index = data->port - 48; + index = 1 << index; + val = (cpld_reg_data & index) > 0 ? 1 : 0; + + printk("lpmode read:data->port = %d, index = %hhu, cpld_reg_data = %hhu\n", data->port, index, cpld_reg_data); + mutex_unlock(&data->update_lock); + + return sprintf(buf, "%d\n", val); +} + +static ssize_t qsfp_lpmode_write(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + int present; + int status; + u8 val = 0; + int ret = 0; + u8 cpld_reg_data = 0; + u8 index = 0; + long usrdata; + struct sensor_device_attribute *attr = to_sensor_dev_attr(da); + struct i2c_client *client = to_i2c_client(dev); + struct sfp_port_data *data = i2c_get_clientdata(client); + + present = sfp_is_port_present(client, data->port); + if (IS_ERR_VALUE(present)) { + return present; + } + + if (present == 0) { + /* port is not present */ + return -ENODEV; + } + + ret = kstrtol(buf, 10, &usrdata); + if (ret) { + return ret; + } + + usrdata = usrdata > 0 ? 1 : 0; + index = data->port - 48; + + DEBUG_PRINT("usrdata = %u, index = %hhu\n", usrdata, index); + + mutex_lock(&data->update_lock); + + udelay(6000); + /* Read current status */ + ret = cig_cpld_read_sfp_register(QSFP_LPMODE_ADDR, &cpld_reg_data); + if (ret == 1) + { + + DEBUG_PRINT("cpld_reg_data = %x\n", cpld_reg_data); + cpld_reg_data &= ~(1 << index); + cpld_reg_data |= usrdata << index; + + DEBUG_PRINT("cpld_reg_data = %x\n", cpld_reg_data); + ret = cig_cpld_write_sfp_register(QSFP_LPMODE_ADDR, cpld_reg_data); + if (1 != ret) + { + DEBUG_PRINT("write failed\n"); + } + } + else + { + DEBUG_PRINT("read failed\n"); + } + + mutex_unlock(&data->update_lock); + + if (ret != 1) + return -1; + + return count; +} + + + static ssize_t qsfp_show_tx_rx_status(struct device *dev, struct device_attribute *da, char *buf) { @@ -822,7 +1078,7 @@ static ssize_t qsfp_set_tx_disable(struct device *dev, struct device_attribute * int status; struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct i2c_client *client = to_i2c_client(dev); - struct sfp_port_data *data = i2c_get_clientdata(client); + struct sfp_port_data *data = i2c_get_clientdata(client); status = sfp_is_port_present(client, data->port); if (IS_ERR_VALUE(status)) { @@ -922,13 +1178,13 @@ static ssize_t sfp_show_tx_rx_status(struct device *dev, struct device_attribute for (i = 0; i < ARRAY_SIZE(values); i++) { values[i] = (u8)(data->msa->status[2] >> (i * 8)); } - + /** Return values 1 -> 48 in order */ return sprintf(buf, "%.2x %.2x %.2x %.2x %.2x %.2x\n", values[0], values[1], values[2], - values[3], values[4], values[5]); + values[3], values[4], values[5]); } - + switch (attr->index) { case TX_FAULT: index = 0; @@ -938,7 +1194,7 @@ static ssize_t sfp_show_tx_rx_status(struct device *dev, struct device_attribute break; case RX_LOS: index = 2; - break; + break; default: break; } @@ -1246,6 +1502,8 @@ static int sfp_msa_probe(struct i2c_client *client, const struct i2c_device_id * *data = msa; dev_info(&client->dev, "sfp msa '%s'\n", client->name); + cs6436_56p_sysfs_add_client(client); + return 0; exit_remove: @@ -1386,7 +1644,7 @@ static int sfp_device_probe(struct i2c_client *client, return qsfp_probe(client, dev_id, &data->qsfp); } } - + return -ENODEV; } /* Platform dependent --- */ @@ -1419,6 +1677,7 @@ static int sfp_device_remove(struct i2c_client *client) { struct sfp_port_data *data = i2c_get_clientdata(client); + cs6436_56p_sysfs_remove_client(client); switch (data->driver_type) { case DRIVER_TYPE_SFP_MSA: return sfp_msa_remove(client, data->msa); diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-sysfs.c b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-sysfs.c new file mode 100644 index 000000000000..89f6bba3aab2 --- /dev/null +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/modules/x86-64-cig-cs6436-56p-sysfs.c @@ -0,0 +1,335 @@ +/* + * A hwmon driver for the CIG cs6436-56P sysfs Module + * + * Copyright (C) 2018 Cambridge, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 +#include +#include + +#include "i2c-algo-lpc.h" + + +static LIST_HEAD(sysfs_client_list); +static struct mutex list_lock; + +struct sysfs_client_node { + struct i2c_client *client; + struct list_head list; +}; + +#define DEVICE_NAME "cigfs" +static int dev_major; +static struct class *dev_class; +static struct cdev *dev_cdev; +static struct device *dev_device; +static struct class *psu_class; +static struct class *sfp_class; + + +void cs6436_56p_sysfs_add_client(struct i2c_client *client) +{ + struct sysfs_client_node *node = kzalloc(sizeof(struct sysfs_client_node), GFP_KERNEL); + + if (!node) { + dev_dbg(&client->dev, "Can't allocate sysfs_client_node (0x%x)\n", client->addr); + return; + } + node->client = client; + + mutex_lock(&list_lock); + list_add(&node->list, &sysfs_client_list); + mutex_unlock(&list_lock); +} + +EXPORT_SYMBOL(cs6436_56p_sysfs_add_client); + +void cs6436_56p_sysfs_remove_client(struct i2c_client *client) +{ + struct list_head *list_node = NULL; + struct sysfs_client_node *sysfs_node = NULL; + int found = 0; + + mutex_lock(&list_lock); + + list_for_each(list_node, &sysfs_client_list) + { + sysfs_node = list_entry(list_node, struct sysfs_client_node, list); + if (IS_ERR(sysfs_node)) + { + break; + } + if (sysfs_node->client == client) { + found = 1; + break; + } + } + if (found) { + list_del(list_node); + kfree(sysfs_node); + } + + mutex_unlock(&list_lock); +} + +EXPORT_SYMBOL(cs6436_56p_sysfs_remove_client); + +struct class * cs6436_56p_sysfs_create_symclass(char *cls_name) +{ + int rc = 0; + struct class *my_class; +/**************************************************************************************/ + my_class = class_create(THIS_MODULE,cls_name); + if (IS_ERR(my_class)) { + pr_err("failed to create my class\n"); + } + return my_class; + +/**************************************************************************************/ +} + +void cs6436_56p_sysfs_delete_symclass(struct class *my_class) +{ +/**************************************************************************************/ + + if (IS_ERR(my_class)) { + pr_err("Pointer is invaild\n"); + } + class_destroy(my_class); + +/**************************************************************************************/ +} + + + + + +int cs6436_56p_sysfs_create_symlink(struct class *my_class,char * driver_name,char *device_name) +{ + struct list_head *list_node = NULL; + struct sysfs_client_node *sysfs_node = NULL; + int ret = -EPERM; + int rc = 0; + + mutex_lock(&list_lock); + list_for_each(list_node, &sysfs_client_list) + { + sysfs_node = list_entry(list_node, struct sysfs_client_node, list); + if (!strcmp(sysfs_node->client->name,driver_name)) { + rc = sysfs_create_link(&my_class->p->subsys.kobj, &sysfs_node->client->dev.kobj,device_name); + if(rc) + { + pr_err("failed to create symlink %d\n",rc); + } + break; + } + } + mutex_unlock(&list_lock); + return ret; +} + + +int cs6436_56p_sysfs_delete_symlink(struct class *my_class,char * driver_name,char *device_name) +{ + struct list_head *list_node = NULL; + struct sysfs_client_node *sysfs_node = NULL; + int ret = -EPERM; + int rc = 0; + + mutex_lock(&list_lock); + list_for_each(list_node, &sysfs_client_list) + { + sysfs_node = list_entry(list_node, struct sysfs_client_node, list); + if (!strcmp(sysfs_node->client->name,driver_name)) { + sysfs_remove_link(&my_class->p->subsys.kobj,device_name); + break; + } + } + mutex_unlock(&list_lock); + return ret; +} + + +static int cs6436_56p_sysfs_open(struct inode *inode, struct file *file) +{ + return 0; +} + + + +static ssize_t cs6436_56p_sysfs_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos) +{ + char str[10],name[18],port[8]; + int ret; + int i; + memset(str, 0, sizeof(str)); + ret = copy_from_user(str, buf, count); + if (ret) + { + printk(KERN_ERR "copy_from_user fail\n"); + return -EINVAL; + } + + if(!strncmp(str,"start",5)) + { + psu_class = cs6436_56p_sysfs_create_symclass("psu"); + cs6436_56p_sysfs_create_symlink(psu_class,"cs6436_56p_psu1","psu1"); + cs6436_56p_sysfs_create_symlink(psu_class,"cs6436_56p_psu2","psu2"); + sfp_class = cs6436_56p_sysfs_create_symclass("swps"); + for(i = 1; i <= 48;i++) + { + memset(name,0xff,sizeof(name)); + memset(port,0xff,sizeof(port)); + snprintf(name,sizeof(name),"cs6436_56p_sfp%d",i); + snprintf(port,sizeof(port),"port%d",i); + cs6436_56p_sysfs_create_symlink(sfp_class,name,port); + } + } + else if(!strncmp(str,"stop",4)) + { + cs6436_56p_sysfs_delete_symlink(psu_class,"cs6436_56p_psu1","psu1"); + cs6436_56p_sysfs_delete_symlink(psu_class,"cs6436_56p_psu2","psu2"); + cs6436_56p_sysfs_delete_symclass(psu_class); + + for(i = 1; i <= 48;i++) + { + memset(name,0xff,sizeof(name)); + memset(port,0xff,sizeof(port)); + snprintf(name,sizeof(name),"cs6436_56p_sfp%d",i); + snprintf(port,sizeof(port),"port%d",i); + cs6436_56p_sysfs_delete_symlink(sfp_class,name,port); + } + cs6436_56p_sysfs_delete_symclass(sfp_class); + } + return count; +} + + +static struct file_operations cs6436_56p_sysfs_fops = { + .owner = THIS_MODULE, + .open = cs6436_56p_sysfs_open, + .write = cs6436_56p_sysfs_write, +}; + + +static int __init cs6436_56p_sysfs_init(void) +{ + int result = 0; + int err = 0; + dev_t dev = MKDEV(dev_major, 0); + + if (dev_major) + result = register_chrdev_region(dev, 1, DEVICE_NAME); + else { + result = alloc_chrdev_region(&dev, 0, 1, DEVICE_NAME); + dev_major = MAJOR(dev); + } + if (result < 0) + { + printk("unable to get major %d\n", dev_major); + err= -EINVAL; + } + printk("get major is %d\n", dev_major); + if (dev_major == 0) + dev_major = result; + + dev_cdev= kmalloc(sizeof(struct cdev), GFP_KERNEL); + if(IS_ERR(dev_cdev)) { + err= -ENOMEM; + } + + cdev_init(dev_cdev, &cs6436_56p_sysfs_fops); + dev_cdev->owner = THIS_MODULE; + dev_cdev->ops = &cs6436_56p_sysfs_fops; + err = cdev_add(dev_cdev, dev, 1); + if (err) + { + printk("error %d add fpga ", err); + goto err_malloc; + } + + dev_class = class_create(THIS_MODULE, DEVICE_NAME); + if (IS_ERR(dev_class)) + { + printk("Err:failed in creating class.\n"); + goto err_cdev_add; + } + + dev_device = device_create(dev_class, NULL, MKDEV(dev_major, 0), NULL, DEVICE_NAME); + if (IS_ERR(dev_device)) + { + printk("Err:failed in creating device.\n"); + goto err_class_crt; + } + + mutex_init(&list_lock); + + return err; + + err_class_crt: + cdev_del(dev_cdev); + err_cdev_add: + kfree(dev_cdev); + err_malloc: + unregister_chrdev_region(MKDEV(dev_major,0), 1); + + return err; + +} + +static void __exit cs6436_56p_sysfs_exit(void) +{ + cdev_del(dev_cdev); + printk("cdev_del ok\n"); + device_destroy(dev_class, MKDEV(dev_major, 0)); + + class_destroy(dev_class); + + if(dev_cdev != NULL) + kfree(dev_cdev); + + unregister_chrdev_region(MKDEV(dev_major, 0), 1); + printk("cs6436_56p_sysfs_exit...\r\n"); +} + + +MODULE_AUTHOR("Zhang Peng "); +MODULE_DESCRIPTION("cs6436-56p-sysfs driver"); +MODULE_LICENSE("GPL"); + +module_init(cs6436_56p_sysfs_init); +module_exit(cs6436_56p_sysfs_exit); + + diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/service/cs6436-platform-init.service b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/service/cs6436-platform-init.service old mode 100755 new mode 100644 diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/service/cs6436-platform-misc.service b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/service/cs6436-platform-misc.service old mode 100755 new mode 100644 index 7ff410cbb3c1..ed44bc0b3438 --- a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/service/cs6436-platform-misc.service +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/service/cs6436-platform-misc.service @@ -4,7 +4,7 @@ After=cs6436-platform-init.service DefaultDependencies=no [Service] -ExecStart=/usr/local/bin/cig_cs6436_misc.py +ExecStart=/usr/local/bin/cig_cs6436_misc.py KillSignal=SIGKILL SuccessExitStatus=SIGKILL diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/utils/cig_cs6436_misc.py b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/utils/cig_cs6436_misc.py index 08decef98ad0..3b685236a075 100755 --- a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/utils/cig_cs6436_misc.py +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/utils/cig_cs6436_misc.py @@ -21,12 +21,259 @@ import logging import re import time +import datetime from collections import namedtuple from threading import Thread DEBUG = False i2c_prefix = '/sys/bus/i2c/devices/' -cs6436__prefix = '/sys/devices/platform/cs6436_56p_led/leds/' +leds_prefix = '/sys/devices/platform/cs6436_56p_led/leds/' +fans_prefix = '/sys/devices/platform/cs6436_56p_fan/' +fansdir_prefix = fans_prefix + 'fan{}_direction' + +ageing_controlfile = '/etc/sonic/agcontrol' +AGFlag = 0 + + +platform_misc_log = '/var/log/platform_misc.log' +misclogger = logging.getLogger('platform_misc') +misclogger.setLevel(logging.INFO) +miscformatter = logging.Formatter('%(asctime)s-%(levelname)s-%(message)s') + +if not os.path.isfile(platform_misc_log): + try: + os.mknod(platform_misc_log) + except: + print 'Failed to creat platform_misc.log' + +fileHandler = logging.FileHandler(platform_misc_log) +fileHandler.setLevel(logging.INFO) +fileHandler.setFormatter(miscformatter) +misclogger.addHandler(fileHandler) + + +starttime = datetime.datetime.now() +IsGetlswt = 0 +coretemp_prefix = '/sys/class/hwmon/hwmon1/' +coretemp_ps = [] +psu1_p = '/sys/bus/i2c/devices/5-005a/psu_present' +psu2_p = '/sys/bus/i2c/devices/5-005b/psu_present' +psu1_d = '/sys/bus/i2c/devices/5-0052/psu_eeprom' +psu2_d = '/sys/bus/i2c/devices/5-0053/psu_eeprom' +psu1led_d = leds_prefix + 'cs6436_56p_led::psu1/brightness' +psu2led_d = leds_prefix + 'cs6436_56p_led::psu2/brightness' +cs6436_ledpath = {'fan':leds_prefix + 'cs6436_56p_led::fan/brightness', + 'fan1':leds_prefix + 'cs6436_56p_led::fan1/brightness', + 'fan2':leds_prefix + 'cs6436_56p_led::fan2/brightness', + 'fan3':leds_prefix + 'cs6436_56p_led::fan3/brightness', + 'fan4':leds_prefix + 'cs6436_56p_led::fan4/brightness', + 'fan5':leds_prefix + 'cs6436_56p_led::fan5/brightness', + 'psu1':leds_prefix + 'cs6436_56p_led::psu1/brightness', + 'psu2':leds_prefix + 'cs6436_56p_led::psu2/brightness', + 'sys':leds_prefix + 'cs6436_56p_led::sys/brightness'} + + +def system_read_filestr(node): + with open(node, 'r') as f: + try: + str = f.read() + except IOError as e: + misclogger.error('Failed to get node, str={}'.format(node)) + return "0" + return str + + +def system_bright_leds(dev, colour): + global AGFlag + + if AGFlag == 1: + return + + cmd = 'echo {} > {}'.format(colour, dev) + log_os_system(cmd, 1) + return + +''' +1: front in tail out +0: front out tail in +''' +def system_getpsu_direction(dev): + try: + with open(dev) as f: + f.seek(0x30) + str = f.read(2) + except IOError as e: + misclogger.error('Failed to get psu eep') + return 1 + if str == 'AA': ## front in tail out + return 1 + elif str == 'RA':## tail in front out + return 0 + else: + misclogger.error('Failed to get psu eep, str={}'.format(str)) + return -1 + + +def system_get_cputype(): + cmdretfd = os.popen("lscpu | grep 'Model name'") + retstring = cmdretfd.read() + endindex = retstring.find('@') - 1 + startindex = retstring[:endindex].rfind(' ') + 1 + cputype = retstring[startindex:endindex] + + return cputype + + +def system_init_coretemppath(): + global coretemp_ps + + cmdstr = "ls {} | grep 'input'".format(coretemp_prefix) + cmdretfd = os.popen(cmdstr) + + coretemppss = cmdretfd.read().splitlines() + if len(coretemppss) < 3: + cputype = system_get_cputype() + misclogger.error('Failed to init core temperature path.' + ' cpu type = {}, num thermal = {}'.format(cputype, len(coretemp_ps))) + return 1 + + for i in range(0,3): + coretemp_ps.append(coretemp_prefix + coretemppss[i]) + + print coretemp_ps + + return 0 + + +class cs6436_fanattr: + def __init__(self, name): + self.name = name + self.direction = 0 + self.direction_p = '' + self.rear = 0 + self.rear_p = '' + self.front = 0 + self.front_p = '' + self.fault = 0 + self.fault_p = '' + self.status = 0 + self.setpath() + self.updatedevice() + + return + + def setpath(self): + self.direction_p = fans_prefix + '{}_direction'.format(self.name) + self.rear_p = fans_prefix + '{}_rear_speed_rpm'.format(self.name) + self.front_p = fans_prefix + '{}_front_speed_rpm'.format(self.name) + self.fault_p = fans_prefix + '{}_fault'.format(self.name) + + return + + def updatedevice(self): + self.direction = int(system_read_filestr(self.direction_p)) + self.rear = int(system_read_filestr(self.rear_p)) + self.front = int(system_read_filestr(self.front_p)) + self.fault = int(system_read_filestr(self.fault_p)) + + return + + def checkspeedrpm(self, speedrpm): + frontrpmexp = speedrpm * 21000 / 100 + rearrpmexp = speedrpm * 19000 / 100 + deviationfront = abs(frontrpmexp - self.front) / float(frontrpmexp) + deviationrear = abs(rearrpmexp - self.rear) / float(rearrpmexp) + + if deviationfront < 0.3 and deviationrear < 0.3: + return 0 + else: + misclogger.error(':{} speed wrong. frontexp is {}, but rpm is {}.rearexp is {}, but rpm is {}'.format(self.name, frontrpmexp, self.front, rearrpmexp, self.rear)) + return 1 + + def checkstatus(self, speedrpm, totaldirct): + speedstatus = self.checkspeedrpm(speedrpm) + if self.direction != totaldirct: + self.status = 1 + misclogger.error(':{} direction = {}.fan direction is not ok.'.format(self.name, self.direction)) + elif speedstatus != 0: + self.status = 1 + elif self.fault != 0: + misclogger.error(':{} fault.'.format(self.name)) + self.status = 1 + else: + self.status = 0 + + if self.status == 1: + system_bright_leds(cs6436_ledpath[self.name], 3) + else: + system_bright_leds(cs6436_ledpath[self.name], 1) + + return self.status + +cs6436_fanattrnodes = [] + + +class cs6436_psuattr: + def __init__(self, name): + self.name = name + self.direction = 0 + self.direction_p = '' + self.present = 0 + self.present_p = '' + self.status = 0 + + self.setpath() + self.updatepresent() + self.updatedirection() + + return + + def setpath(self): + if self.name == 'psu1': + self.present_p = psu1_p + self.direction_p = psu1_d + if self.name == 'psu2': + self.present_p = psu2_p + self.direction_p = psu2_d + + return + + def updatepresent(self): + self.present = int(system_read_filestr(self.present_p)) + + return + + def updatedirection(self): + if self.present == 1: + self.direction = system_getpsu_direction(self.direction_p) + else: + self.direction = 2 + + return + + def checkstatus(self, totaldirct): + if self.present != 1: + self.status = 1 + misclogger.error(':{} not present.'.format(self.name)) + elif self.direction == 2: + self.status = 0 + misclogger.info(':{} direction need to be update.'.format(self.name)) + elif self.direction != totaldirct: + self.status = 1 + misclogger.info(':{} direction is wrong.'.format(self.name)) + else: + self.status = 0 + + if self.status == 1: + system_bright_leds(cs6436_ledpath[self.name], 3) + else: + system_bright_leds(cs6436_ledpath[self.name], 1) + + return self.status + +cs6436_psuattrnodes = [] + + def my_log(txt): if DEBUG == True: @@ -36,15 +283,15 @@ def my_log(txt): def device_exist(): ret1, log = log_os_system("ls "+i2c_prefix+"5-005a", 0) ret2, log = log_os_system("ls "+i2c_prefix+"5-005b", 0) - ret3, log = log_os_system("ls "+cs6436__prefix+"cs6436_56p_led*", 0) + ret3, log = log_os_system("ls "+leds_prefix+"cs6436_56p_led*", 0) return not(ret1 or ret2 or ret3) - + def log_os_system(cmd, show): - logging.info('Run :'+cmd) - status, output = commands.getstatusoutput(cmd) + logging.info('Run :'+cmd) + status, output = commands.getstatusoutput(cmd) my_log (cmd +"with result:" + str(status)) - my_log (" output:"+output) + my_log (" output:"+output) if status: logging.info('Failed :'+cmd) if show: @@ -52,7 +299,223 @@ def log_os_system(cmd, show): return status, output -def system_misc_polling(threadName,delay): +def system_get_coretemp(): + temp1 = system_read_filestr(coretemp_ps[0]).strip() + temp2 = system_read_filestr(coretemp_ps[1]).strip() + temp3 = system_read_filestr(coretemp_ps[2]).strip() + + return int(temp1), int(temp2), int(temp3) + +def system_get_boardtemp(): + for i in range(0,16): + temp1path = "/sys/bus/i2c/devices/5-004a/hwmon/hwmon%d/temp1_input" % i + if os.access(temp1path, os.F_OK): + break + for i in range(0,16): + temp2path = "/sys/bus/i2c/devices/5-004b/hwmon/hwmon%d/temp1_input" % i + if os.access(temp2path, os.F_OK): + break + temp1 = system_read_filestr(temp1path).strip() + temp2 = system_read_filestr(temp2path).strip() + + return int(temp1), int(temp2) + + +def system_get_lswtemp(): + global IsGetlswt + global starttime + if IsGetlswt == 0: + now = datetime.datetime.now() + misclogger.info("time wait.") + misclogger.info("start = {}, now = {}.".format(starttime, now)) + if (now - starttime).seconds > 150: + misclogger.info("time = ".format((now - starttime).seconds)) + IsGetlswt = 1 + + return 25 + +# chp = subprocess.Popen("docker ps --filter name=syncd", shell=True, stdout=subprocess.PIPE) +# if chp.poll() == None: +# misclogger.info("No subp.") +# chp.kill() +# +# return 25 + +# retstring = chp.stdout.read() +# chp.kill() +# if 'Up' not in retstring: +# misclogger.info("lsw not up.") +# +# return 25 + + status, output = log_os_system('npx_diag swc show temperature', 1) + if status: + misclogger.error('failed to show lsw temperature') + + return 25 + + output = output.strip() + if output.find("it 0, temperature ") > 0: + startindex = output.find('temperature') + len('temperature') + 1 + endindex = output[startindex:].find(" ") + endindex = startindex + endindex + temp = output[startindex:endindex] + b = temp.find('.') + if b > 0: + temp=temp[:b] + temp = int(temp) + else: + misclogger.error("Failed to get temperature.") + temp = 0 + + return int(temp) + +def system_monitor_temperature(): + + ctemp1, ctemp2, ctemp3 = system_get_coretemp() + btemp1, btemp2 = system_get_boardtemp() + ltemp = system_get_lswtemp() + fan_speed_str = system_cs6436_getfanexspeed() + fan_speed = int(fan_speed_str) + policy = 'stay' + pos = 0 + #speed c1 c2 c3 b1 b2 lsw + fan_policy_up = ([30, 40000, 40000, 40000, 42000, 35000, 95], + [40, 44000, 44000, 44000, 44000, 39000, 96], + [50, 49000, 49000, 49000, 47000, 44000, 91], + [60, 52000, 52000, 52000, 51500, 47500, 92], + [70, 53000, 53000, 53000, 52000, 49000, 93], + [100,999999,999999,999999,999999,999999,999]) + + fan_policy_down=([30, 0, 0, 0, 0, 0, 0], + [40, 34000, 34000, 34000, 34000, 30000, 80], + [50, 38000, 38000, 38000, 37000, 33000, 81], + [60, 44000, 44000, 44000, 43000, 39000, 84], + [70, 44000, 44000, 44000, 43000, 40000, 84], + [100, 48000, 48000, 48000, 46000, 42000, 85],) + + for policytable in fan_policy_up: + if fan_speed <= policytable[0]: + break + pos = pos + 1 + fan_speed = policytable[0] + if (ctemp1 < policytable[1]) and (ctemp2 < policytable[2]) and (ctemp3 < policytable[3]) and (btemp1 < policytable[4]) and (btemp2 < policytable[5]) and (ltemp < policytable[6]): + policy = 'stay' + policytable = fan_policy_down[pos] + if (ctemp1 < policytable[1]) and (ctemp2 < policytable[2]) and (ctemp3 < policytable[3]) and (btemp1 < policytable[4]) and (btemp2 < policytable[5]) and (ltemp < policytable[6]): + policy = 'down' + else: + policy = 'up' + + if policy == 'up': + misclogger.info("speed = %d." % fan_speed) + misclogger.info("core1 = %d, core2 = %d, core3 = %d." % (ctemp1, ctemp2, ctemp3)) + misclogger.info("board1 = %d, board2 = %d." % (btemp1, btemp2)) + misclogger.info("lsw = %d" % ltemp) + fan_speed = fan_policy_down[pos + 1][0] + misclogger.info("fan policy: up. speedexp = {}".format(fan_speed)) + + if policy == 'stay': + fan_speed = fan_policy_down[pos] + return + + if policy == 'down': + misclogger.info("speed = %d." % fan_speed) + misclogger.info("core1 = %d, core2 = %d, core3 = %d." % (ctemp1, ctemp2, ctemp3)) + misclogger.info("board1 = %d, board2 = %d." % (btemp1, btemp2)) + misclogger.info("lsw = %d" % ltemp) + fan_speed = fan_policy_down[pos - 1][0] + misclogger.info("fan policy: down.speedexp = {}".format(fan_speed)) + + cmd = "echo %d > /sys/devices/platform/cs6436_56p_fan/fan_duty_cycle_percentage" % fan_speed + status, output = log_os_system(cmd, 1) + if status: + misclogger.error("set fan speed fault") + + return + + +def system_cs6436_setfanexspeed(num): + fanspeednode = fans_prefix + 'fan_duty_cycle_percentage' + numstr = str(num) + with open(fanspeednode, 'w') as f: + f.write(numstr) + + +def system_cs6436_getfanexspeed(): + fanspeednode = fans_prefix + 'fan_duty_cycle_percentage' + fanspeedstr = system_read_filestr(fanspeednode) + fanspeedexp = int(fanspeedstr) + + return fanspeedexp + + +def system_cs6436_getdirection(): + global cs6436_fanattrnodes + direction = 0 + + for fan in cs6436_fanattrnodes: + direction = direction + fan.direction + + if direction > 2: + direction = 1 + else: + direction = 0 + + return direction + + +def system_check_psusdirection(): + global cs6436_psuattrnodes + cs6436totaldirct = system_cs6436_getdirection() + psutatus = 0 + + for psu in cs6436_psuattrnodes: + psu.updatedirection() + psu.checkstatus(cs6436totaldirct) + psutatus = psu.status + psutatus + + return (psutatus != 0) + + +def system_check_psuspresent(): + global cs6436_psuattrnodes + cs6436totaldirct = system_cs6436_getdirection() + psutatus = 0 + + for psu in cs6436_psuattrnodes: + psu.updatepresent() + psu.checkstatus(cs6436totaldirct) + psutatus = psu.status + psutatus + + return (psutatus != 0) + + +def system_check_fansstate(): + global cs6436_fanattrnodes + global cs6436_ledpath + cs6436totaldirct = system_cs6436_getdirection() + fanstatus = 0 + fanexspeed = 0 + + fanexspeed = system_cs6436_getfanexspeed() + + for fan in cs6436_fanattrnodes: + fan.updatedevice() + fan.checkstatus(fanexspeed, cs6436totaldirct) + fanstatus = fanstatus + fan.status + + if fanstatus > 0: + misclogger.error(':fan error.set fans speed 100.') + system_cs6436_setfanexspeed(100) + system_bright_leds(cs6436_ledpath['fan'], 3) + else: + system_bright_leds(cs6436_ledpath['fan'], 1) + + return (fanstatus != 0) + + +def system_misc_polling(threadName,delay): for count in range(1,5): if device_exist() == False: time.sleep(delay+3) @@ -62,93 +525,50 @@ def system_misc_polling(threadName,delay): if count == 4: return - + status, output = log_os_system("echo 1 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::sys/brightness", 1) status, output = log_os_system("hwconfig -cfp 1", 1) + global AGFlag + if os.access(ageing_controlfile, os.F_OK): + AGFlag = 1 + else: + AGFlag = 0 + + os.system('csw_daemon &') + + + global cs6436_fanattrnodes + global cs6436_psuattrnodes + + for num in range(1,6): + name = 'fan{}'.format(num) + fannode = cs6436_fanattr(name) + cs6436_fanattrnodes.append(fannode) + for num in range(1,3): + name = 'psu{}'.format(num) + psunode = cs6436_psuattr(name) + cs6436_psuattrnodes.append(psunode) + + tempcontrol = system_init_coretemppath() + + misclogger.info("%s: %s misc start." % ( threadName, time.ctime(time.time()))) + count = 0 while 1: - status, output = log_os_system("cat /sys/bus/i2c/devices/5-005a/psu_present", 1) - if status: - print "failed to check status for 5-005a/psu_present" - continue - - if output=='1': - log_os_system("echo 1 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::psu1/brightness", 1) - else: - log_os_system("echo 0 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::psu1/brightness", 1) - - status, output = log_os_system("cat /sys/bus/i2c/devices/5-005b/psu_present", 1) - if status: - print "failed to check status for 5-005b/psu_present" - continue - - if output=='1': - log_os_system("echo 1 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::psu2/brightness", 1) - else: - log_os_system("echo 0 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::psu2/brightness", 1) - - status, fan1 = log_os_system(" cat /sys/devices/platform/cs6436_56p_fan/fan1_fault",1) - if status: - print "failed to check status for cs6436_56p_fan/fan1_fault" - continue - - if fan1=='0': - log_os_system("echo 1 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan1/brightness", 1) - else: - log_os_system("echo 3 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan1/brightness", 1) - - status, fan2 = log_os_system(" cat /sys/devices/platform/cs6436_56p_fan/fan2_fault",1) - - if status: - print "failed to check status for cs6436_56p_fan/fan2_fault" - continue - - if fan2=='0': - log_os_system("echo 1 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan2/brightness", 1) - else: - log_os_system("echo 3 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan2/brightness", 1) - - status, fan3 = log_os_system(" cat /sys/devices/platform/cs6436_56p_fan/fan3_fault",1) - if status: - print "failed to check status for cs6436_56p_fan/fan3_fault" - continue - - if fan3=='0': - log_os_system("echo 1 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan3/brightness", 1) - else: - log_os_system("echo 3 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan3/brightness", 1) - - status, fan4 = log_os_system(" cat /sys/devices/platform/cs6436_56p_fan/fan4_fault",1) - if status: - print "failed to check status for cs6436_56p_fan/fan4_fault" - continue - - if fan4=='0': - log_os_system("echo 1 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan4/brightness", 1) - else: - log_os_system("echo 3 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan4/brightness", 1) - - status, fan5 = log_os_system(" cat /sys/devices/platform/cs6436_56p_fan/fan5_fault",1) - if status: - print "failed to check status for cs6436_56p_fan/fan5_fault" - continue - - if fan5=='0': - log_os_system("echo 1 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan5/brightness", 1) - else: - log_os_system("echo 3 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan5/brightness", 1) - - if fan1=='0' or fan2=='0' or fan3=='0' or fan4=='0' or fan5=='0': - log_os_system("echo 1 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan/brightness", 1) - else: - log_os_system("echo 3 > /sys/devices/platform/cs6436_56p_led/leds/cs6436_56p_led::fan/brightness", 1) + count = count + 1 + ret = system_check_psuspresent() + ret = system_check_fansstate() + + if count % 10 == 0: + misclogger.info(": adjust fans and check psu direction.") + system_check_psusdirection() + if tempcontrol == 0: + system_monitor_temperature() + count = 0 time.sleep(delay) - print "%s: %s" % ( threadName, time.ctime(time.time())) + return if __name__ == '__main__': - target=system_misc_polling("Thread-misc",3) - - - + target=system_misc_polling("Thread-misc",10) diff --git a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/utils/cig_cs6436_util.py b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/utils/cig_cs6436_util.py index 2b64d2e107b9..86285c7e4106 100755 --- a/platform/nephos/sonic-platform-modules-cig/cs6436-56p/utils/cig_cs6436_util.py +++ b/platform/nephos/sonic-platform-modules-cig/cs6436-56p/utils/cig_cs6436_util.py @@ -21,13 +21,13 @@ options: -h | --help : this help message -d | --debug : run with debug mode - -f | --force : ignore error during installation or clean + -f | --force : ignore error during installation or clean command: install : install drivers and generate related sysfs nodes clean : uninstall drivers and remove related sysfs nodes show : show all systen status sff : dump SFP eeprom - set : change board setting with fan|led|sfp + set : change board setting with fan|led|sfp """ import os @@ -42,47 +42,48 @@ PROJECT_NAME = 'cs6436_56p' -version = '0.1.0' +version = '0.1.1' verbose = False DEBUG = False args = [] -ALL_DEVICE = {} +ALL_DEVICE = {} DEVICE_NO = {'led':9, 'fan':5, 'thermal':4, 'psu':2, 'sfp':56} FORCE = 0 +CPU_TYPE = 'C3308' if DEBUG == True: print sys.argv[0] - print 'ARGV :', sys.argv[1:] + print 'ARGV :', sys.argv[1:] def main(): global DEBUG global args global FORCE - + if len(sys.argv)<2: show_help() - + options, args = getopt.getopt(sys.argv[1:], 'hdf', ['help', 'debug', 'force', ]) - if DEBUG == True: + if DEBUG == True: print options print args print len(sys.argv) - + for opt, arg in options: if opt in ('-h', '--help'): show_help() - elif opt in ('-d', '--debug'): + elif opt in ('-d', '--debug'): DEBUG = True logging.basicConfig(level=logging.INFO) - elif opt in ('-f', '--force'): + elif opt in ('-f', '--force'): FORCE = 1 else: - logging.info('no option') - for arg in args: + logging.info('no option') + for arg in args: if arg == 'install': do_install() elif arg == 'clean': @@ -92,23 +93,23 @@ def main(): elif arg == 'sff': if len(args)!=2: show_eeprom_help() - elif int(args[1]) ==0 or int(args[1]) > DEVICE_NO['sfp']: + elif int(args[1]) ==0 or int(args[1]) > DEVICE_NO['sfp']: show_eeprom_help() else: - show_eeprom(args[1]) - return + show_eeprom(args[1]) + return elif arg == 'set': if len(args)<3: show_set_help() else: - set_device(args[1:]) - return + set_device(args[1:]) + return else: show_help() - - - return 0 - + + + return 0 + def show_help(): print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]} sys.exit(0) @@ -117,31 +118,31 @@ def show_set_help(): cmd = sys.argv[0].split("/")[-1]+ " " + args[0] print cmd +" [led|sfp|fan]" print " use \""+ cmd + " led 0-4 \" to set led color" - print " use \""+ cmd + " fan 0-100\" to set fan duty percetage" - print " use \""+ cmd + " sfp 1-56 {0|1}\" to set sfp# tx_disable" - sys.exit(0) - + print " use \""+ cmd + " fan 0-100\" to set fan duty percetage" + print " use \""+ cmd + " sfp 1-56 {0|1}\" to set sfp# tx_disable" + sys.exit(0) + def show_eeprom_help(): cmd = sys.argv[0].split("/")[-1]+ " " + args[0] - print " use \""+ cmd + " 1-56 \" to dump sfp# eeprom" - sys.exit(0) - + print " use \""+ cmd + " 1-56 \" to dump sfp# eeprom" + sys.exit(0) + def my_log(txt): if DEBUG == True: - print "[ROY]"+txt + print "[ROY]"+txt return - + def log_os_system(cmd, show): - logging.info('Run :'+cmd) - status, output = commands.getstatusoutput(cmd) + logging.info('Run :'+cmd) + status, output = commands.getstatusoutput(cmd) my_log (cmd +"with result:" + str(status)) - my_log (" output:"+output) + my_log (" output:"+output) if status: logging.info('Failed :'+cmd) if show: print('Failed :'+cmd) return status, output - + def driver_check(): for count in range(1,5): time.sleep(1) @@ -154,11 +155,11 @@ def driver_check(): if len(lsmod) > 2: log_os_system("rmmod i2c_designware_platform", 0) log_os_system("modprobe i2c-designware-platform", 0) - + ret, lsmod = log_os_system("lsmod| grep cig", 0) logging.info('mods:'+lsmod) if len(lsmod) ==0: - return False + return False return True @@ -167,6 +168,7 @@ def driver_check(): 'depmod', 'modprobe i2c_dev', 'modprobe i2c_mux_pca954x force_deselect_on_exit=1', + 'modprobe x86-64-cig-cs6436-56p-sysfs ' , 'modprobe x86-64-cig-cs6436-56p-cpld ' , 'modprobe x86-64-cig-cs6436-56p-fan' , 'modprobe x86-64-cig-cs6436-56p-psu' , @@ -175,28 +177,31 @@ def driver_check(): def driver_install(): global FORCE - + for i in range(0,len(kos)): - if i == 3: - ret, board_type = log_os_system("cat /proc/cpuinfo | grep \"model name\" | cut -b 32-39 | head -n 1", 0) - if board_type=='i3-6100U': - kos[i] =kos[i] + 'board_id=1' - + if i == 4: + ret, CPU_TYPE = log_os_system("cat /proc/cpuinfo | grep \"model name\" | cut -b 32-39 | head -n 1", 0) + if CPU_TYPE=='i3-6100U': + kos[i] =kos[i] + 'board_id=1' + ret, CPU_TYPE = log_os_system("cat /proc/cpuinfo | grep \"model name\" | cut -b 36-40 | head -n 1", 0) + if CPU_TYPE=='C3758' or CPU_TYPE=='C3308': + kos[i] =kos[i] + 'board_id=2' + status, output = log_os_system(kos[i], 1) if status: - if FORCE == 0: - return status + if FORCE == 0: + return status return 0 - + def driver_uninstall(): global FORCE for i in range(0,len(kos)): rm = kos[-(i+1)].replace("modprobe", "modprobe -rq") - rm = rm.replace("insmod", "rmmod") + rm = rm.replace("insmod", "rmmod") status, output = log_os_system(rm, 1) if status: - if FORCE == 0: - return status + if FORCE == 0: + return status return 0 led_prefix ='/sys/class/leds/'+PROJECT_NAME+'_led::' @@ -245,23 +250,22 @@ def driver_uninstall(): def device_install(): global FORCE - + for i in range(0,len(mknod)): - #for pca954x need times to built new i2c buses - if mknod[i].find('pca954') != -1: - time.sleep(1) - + #all nodes need times to built new i2c buses + time.sleep(1) + status, output = log_os_system(mknod[i], 1) if status: print output - if FORCE == 0: + if FORCE == 0: return status - + for i in range(0,len(sfp_map)): status, output =log_os_system("echo cs6436_56p_sfp"+str(i+1)+" 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1) if status: print output - if FORCE == 0: + if FORCE == 0: return status if i <= 47: @@ -271,21 +275,21 @@ def device_install(): if FORCE == 0: return status - return - + return + def device_uninstall(): global FORCE - + for i in range(0,len(sfp_map)): target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/delete_device" status, output =log_os_system("echo 0x50 > "+ target, 1) if status: print output - if FORCE == 0: + if FORCE == 0: return status - + nodelist = mknod - + for i in range(len(nodelist)): target = nodelist[-(i+1)] temp = target.split() @@ -294,129 +298,129 @@ def device_uninstall(): status, output = log_os_system(" ".join(temp), 1) if status: print output - if FORCE == 0: - return status - - return - + if FORCE == 0: + return status + + return + def system_ready(): if driver_check() == False: return False - if not device_exist(): + if not device_exist(): return False return True - + def do_install(): print "Checking system...." if driver_check() == False: - print "No driver, installing...." + print "No driver, installing...." status = driver_install() if status: - if FORCE == 0: + if FORCE == 0: return status else: - print PROJECT_NAME.upper()+" drivers detected...." + print PROJECT_NAME.upper()+" drivers detected...." if not device_exist(): - print "No device, installing...." - status = device_install() + print "No device, installing...." + status = device_install() if status: - if FORCE == 0: - return status + if FORCE == 0: + return status else: - print PROJECT_NAME.upper()+" devices detected...." + print PROJECT_NAME.upper()+" devices detected...." return - + def do_uninstall(): print "Checking system...." if not device_exist(): - print PROJECT_NAME.upper() +" has no device installed...." + print PROJECT_NAME.upper() +" has no device installed...." else: - print "Removing device...." - status = device_uninstall() + print "Removing device...." + status = device_uninstall() if status: - if FORCE == 0: - return status - + if FORCE == 0: + return status + if driver_check()== False : print PROJECT_NAME.upper() +" has no driver installed...." else: print "Removing installed driver...." status = driver_uninstall() if status: - if FORCE == 0: - return status - - return + if FORCE == 0: + return status + + return def devices_info(): global DEVICE_NO global ALL_DEVICE global i2c_bus, hwmon_types, fan_types - for key in DEVICE_NO: - ALL_DEVICE[key]= {} + for key in DEVICE_NO: + ALL_DEVICE[key]= {} for i in range(0,DEVICE_NO[key]): ALL_DEVICE[key][key+str(i+1)] = [] - + for key in i2c_bus: buses = i2c_bus[key] - nodes = i2c_nodes[key] + nodes = i2c_nodes[key] for i in range(0,len(buses)): for j in range(0,len(nodes)): if 'sfp' == key: for k in range(0,DEVICE_NO[key]): node = key+str(k+1) - path = i2c_prefix+ str(sfp_map[k])+ buses[i]+"/"+ nodes[j] + path = i2c_prefix+ str(sfp_map[k])+ buses[i]+"/"+ nodes[j] my_log(node+": "+ path) - ALL_DEVICE[key][node].append(path) + ALL_DEVICE[key][node].append(path) else: node = key+str(i+1) - path = i2c_prefix+ buses[i]+"/"+ nodes[j] + path = i2c_prefix+ buses[i]+"/"+ nodes[j] my_log(node+": "+ path) - ALL_DEVICE[key][node].append(path) - + ALL_DEVICE[key][node].append(path) + for key in hwmon_types: itypes = hwmon_types[key] - nodes = hwmon_nodes[key] + nodes = hwmon_nodes[key] for i in range(0,len(itypes)): - for j in range(0,len(nodes)): + for j in range(0,len(nodes)): node = key+"_"+itypes[i] - path = hwmon_prefix[key]+ itypes[i]+"/"+ nodes[j] + path = hwmon_prefix[key]+ itypes[i]+"/"+ nodes[j] my_log(node+": "+ path) - ALL_DEVICE[key][ key+str(i+1)].append(path) + ALL_DEVICE[key][ key+str(i+1)].append(path) for key in fan_types: itypes = fan_types[key] - nodes = fan_nodes[key] + nodes = fan_nodes[key] for i in range(0,len(itypes)): - for j in range(0,len(nodes)): + for j in range(0,len(nodes)): node = key+"_"+itypes[i] - path = fan_prefix+"/"+ itypes[i]+"_"+ nodes[j] + path = fan_prefix+"/"+ itypes[i]+"_"+ nodes[j] my_log(node+": "+ path) ALL_DEVICE[key][ key+str(i+1)].append(path) - + #show dict all in the order if DEBUG == True: for i in sorted(ALL_DEVICE.keys()): print(i+": ") - for j in sorted(ALL_DEVICE[i].keys()): + for j in sorted(ALL_DEVICE[i].keys()): print(" "+j) - for k in (ALL_DEVICE[i][j]): + for k in (ALL_DEVICE[i][j]): print(" "+" "+k) - return - + return + def show_eeprom(index): if system_ready()==False: - print("System's not ready.") + print("System's not ready.") print("Please install first!") - return - + return + if len(ALL_DEVICE)==0: - devices_info() + devices_info() node = ALL_DEVICE['sfp'] ['sfp'+str(index)][0] node = node.replace(node.split("/")[-1], 'sfp_eeprom') # check if got hexdump command in current environment ret, log = log_os_system("which hexdump", 0) - ret, log2 = log_os_system("which busybox hexdump", 0) + ret, log2 = log_os_system("which busybox hexdump", 0) if len(log): hex_cmd = 'hexdump' elif len(log2): @@ -425,109 +429,123 @@ def show_eeprom(index): log = 'Failed : no hexdump cmd!!' logging.info(log) print log - return 1 - + return 1 + print node + ":" ret, log = log_os_system("cat "+node+"| "+hex_cmd+" -C", 1) - if ret==0: - print log + if ret==0: + print log else: - print "**********device no found**********" - return - + print "**********device no found**********" + return + def set_device(args): global DEVICE_NO global ALL_DEVICE if system_ready()==False: - print("System's not ready.") + print("System's not ready.") print("Please install first!") - return - + return + if len(ALL_DEVICE)==0: - devices_info() - + devices_info() + if args[0]=='led': if int(args[1])>4: show_set_help() return #print ALL_DEVICE['led'] - for i in range(0,len(ALL_DEVICE['led'])): - for k in (ALL_DEVICE['led']['led'+str(i+1)]): + for i in range(0,len(ALL_DEVICE['led'])): + for k in (ALL_DEVICE['led']['led'+str(i+1)]): ret, log = log_os_system("echo "+args[1]+" >"+k, 1) if ret: - return ret + return ret elif args[0]=='fan': if int(args[1])>100: show_set_help() return #print ALL_DEVICE['fan'] - #fan1~6 is all fine, all fan share same setting - node = ALL_DEVICE['fan'] ['fan1'][0] + #fan1~6 is all fine, all fan share same setting + node = ALL_DEVICE['fan'] ['fan1'][0] node = node.replace(node.split("/")[-1], 'fan_duty_cycle_percentage') - ret, log = log_os_system("cat "+ node, 1) + ret, log = log_os_system("cat "+ node, 1) if ret==0: - print ("Previous fan duty: " + log.strip() +"%") + print ("Previous fan duty: " + log.strip() +"%") ret, log = log_os_system("echo "+args[1]+" >"+node, 1) if ret==0: - print ("Current fan duty: " + args[1] +"%") + print ("Current fan duty: " + args[1] +"%") return ret elif args[0]=='sfp': if int(args[1])> DEVICE_NO[args[0]] or int(args[1])==0: show_set_help() - return + return if len(args)<2: show_set_help() - return - + return + if int(args[2])>1: show_set_help() return - - #print ALL_DEVICE[args[0]] - for i in range(0,len(ALL_DEVICE[args[0]])): - for j in ALL_DEVICE[args[0]][args[0]+str(args[1])]: - if j.find('tx_disable')!= -1: + + #print ALL_DEVICE[args[0]] + for i in range(0,len(ALL_DEVICE[args[0]])): + for j in ALL_DEVICE[args[0]][args[0]+str(args[1])]: + if j.find('tx_disable')!= -1: ret, log = log_os_system("echo "+args[2]+" >"+ j, 1) if ret: - return ret - + return ret + return def get_value(input): digit = re.findall('\d+', input) return int(digit[0]) - + + +def get_ledname(ledx): + name_table={'led1':'SYS','led2':'FSTUS','led3':'FAN1','led4':'FAN2','led5':'FAN3','led6':'FAN4','led7':'FAN5','led8':'PSU1','led9':'PSU2'} + if name_table.has_key(ledx): + name = name_table[ledx] + else: + name = ledx + return name + + def device_traversal(): if system_ready()==False: - print("System's not ready.") + print("System's not ready.") print("Please install first!") - return - + return + if len(ALL_DEVICE)==0: devices_info() for i in sorted(ALL_DEVICE.keys()): - print("============================================") + print("============================================") print(i.upper()+": ") print("============================================") - - for j in sorted(ALL_DEVICE[i].keys(), key=get_value): - print " "+j+":", + + for j in sorted(ALL_DEVICE[i].keys(), key=get_value): + nwnamex = get_ledname(j) + if nwnamex == j: + print " "+j+":", + else: + print " "+nwnamex+":", for k in (ALL_DEVICE[i][j]): ret, log = log_os_system("cat "+k, 0) func = k.split("/")[-1].strip() func = re.sub(j+'_','',func,1) - func = re.sub(i.lower()+'_','',func,1) + func = re.sub(i.lower()+'_','',func,1) if ret==0: - print func+"="+log+" ", + print func+"="+log+" ", else: print func+"="+"X"+" ", - print + print print("----------------------------------------------------------------") - - + + print return - + def device_exist(): ret1, log = log_os_system("ls "+i2c_prefix+"*0077", 0) ret2, log = log_os_system("ls "+i2c_prefix+"i2c-3", 0) diff --git a/platform/nephos/sonic-platform-modules-cig/debian/changelog b/platform/nephos/sonic-platform-modules-cig/debian/changelog old mode 100755 new mode 100644 diff --git a/platform/nephos/sonic-platform-modules-cig/debian/compat b/platform/nephos/sonic-platform-modules-cig/debian/compat old mode 100755 new mode 100644 diff --git a/platform/nephos/sonic-platform-modules-cig/debian/control b/platform/nephos/sonic-platform-modules-cig/debian/control old mode 100755 new mode 100644 index 356ce313ab63..bf40791b24e0 --- a/platform/nephos/sonic-platform-modules-cig/debian/control +++ b/platform/nephos/sonic-platform-modules-cig/debian/control @@ -7,5 +7,15 @@ Standards-Version: 3.9.3 Package: sonic-platform-cig-cs6436-56p Architecture: amd64 -Depends: linux-image-4.9.0-9-amd64 +Depends: linux-image-4.9.0-11-2-amd64 +Description: kernel modules for platform devices such as fan, led, sfp + +Package: sonic-platform-cig-cs6436-54p +Architecture: amd64 +Depends: linux-image-4.9.0-11-2-amd64 +Description: kernel modules for platform devices such as fan, led, sfp + +Package: sonic-platform-cig-cs5435-54p +Architecture: amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/nephos/sonic-platform-modules-cig/debian/rules b/platform/nephos/sonic-platform-modules-cig/debian/rules index 3192948cc08d..b9ca7642b8bd 100755 --- a/platform/nephos/sonic-platform-modules-cig/debian/rules +++ b/platform/nephos/sonic-platform-modules-cig/debian/rules @@ -19,7 +19,7 @@ PACKAGE_PRE_NAME := sonic-platform-cig KVERSION ?= $(shell uname -r) KERNEL_SRC := /lib/modules/$(KVERSION) MOD_SRC_DIR:= $(shell pwd) -MODULE_DIRS:= cs6436-56p +MODULE_DIRS:= cs6436-56p cs6436-54p cs5435-54p MODULE_DIR := modules UTILS_DIR := utils SERVICE_DIR := service @@ -59,11 +59,12 @@ binary-indep: # Custom package commands (for mod in $(MODULE_DIRS); do \ - dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod} /$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod}/usr/local/bin; \ dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod}/lib/systemd/system; \ + dh_installdirs -p$(PACKAGE_PRE_NAME)-$${mod}/etc/sonic; \ cp $(MOD_SRC_DIR)/$${mod}/$(MODULE_DIR)/*.ko debian/$(PACKAGE_PRE_NAME)-$${mod}/$(KERNEL_SRC)/$(INSTALL_MOD_DIR); \ - cp $(MOD_SRC_DIR)/$${mod}/$(UTILS_DIR)/* debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/local/bin/; \ + cp $(MOD_SRC_DIR)/$${mod}/$(UTILS_DIR)/*.py debian/$(PACKAGE_PRE_NAME)-$${mod}/usr/local/bin/; \ cp $(MOD_SRC_DIR)/$${mod}/$(SERVICE_DIR)/*.service debian/$(PACKAGE_PRE_NAME)-$${mod}/lib/systemd/system/; \ $(PYTHON) $${mod}/setup.py install --root=$(MOD_SRC_DIR)/debian/$(PACKAGE_PRE_NAME)-$${mod} --install-layout=deb; \ done) From 20510d58d3b7f12237d787d7dc3feaec6ae47fe8 Mon Sep 17 00:00:00 2001 From: Prince Sunny Date: Thu, 20 Feb 2020 12:54:39 -0800 Subject: [PATCH 076/178] Sleep done before mismatch handler (#4165) * Sleep done before mismatch handler --- files/scripts/arp_update | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/files/scripts/arp_update b/files/scripts/arp_update index 4c7d655cfdaf..3cc9cd267985 100755 --- a/files/scripts/arp_update +++ b/files/scripts/arp_update @@ -47,6 +47,9 @@ while /bin/true; do eval `eval $ip6cmd` done + # sleep here before handling the mismatch as it is not required during startup + sleep 300 + # refresh neighbor entries from APP_DB in case of mismatch with kernel DBNEIGH=$(sonic-db-cli APPL_DB keys NEIGH_TABLE*) KERNEIGH4=$(ip -4 neigh show | grep Vlan | cut -d ' ' -f 1,3 --output-delimiter=',') @@ -67,5 +70,4 @@ while /bin/true; do fi done - sleep 300 done From 4f3d3990927fd7e377051a101c85aac6df9e55c7 Mon Sep 17 00:00:00 2001 From: Prince Sunny Date: Thu, 20 Feb 2020 19:16:14 -0800 Subject: [PATCH 077/178] [orchagent] Use mac address from config_db instead of from eth0 (#4166) * Use mac address from config_db instead of eth0 --- dockers/docker-orchagent/orchagent.sh | 6 +++++- platform/p4/docker-sonic-p4/orchagent.sh | 6 +++++- platform/vs/docker-sonic-vs/orchagent.sh | 6 +++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/dockers/docker-orchagent/orchagent.sh b/dockers/docker-orchagent/orchagent.sh index 5e01cd480f52..3352e5fbb7ec 100755 --- a/dockers/docker-orchagent/orchagent.sh +++ b/dockers/docker-orchagent/orchagent.sh @@ -4,7 +4,11 @@ # vendor specific code. export platform=`sonic-cfggen -y /etc/sonic/sonic_version.yml -v asic_type` -MAC_ADDRESS=`ip link show eth0 | grep ether | awk '{print $2}'` +MAC_ADDRESS=$(sonic-cfggen -d -v 'DEVICE_METADATA.localhost.mac') +if [ "$MAC_ADDRESS" == "None" ] || [ -z "$MAC_ADDRESS" ]; then + MAC_ADDRESS=$(ip link show eth0 | grep ether | awk '{print $2}') + logger "Mac address not found in Device Metadata, Falling back to eth0" +fi # Create a folder for SwSS record files mkdir -p /var/log/swss diff --git a/platform/p4/docker-sonic-p4/orchagent.sh b/platform/p4/docker-sonic-p4/orchagent.sh index 7e250dfa20e9..9abfc22c967e 100755 --- a/platform/p4/docker-sonic-p4/orchagent.sh +++ b/platform/p4/docker-sonic-p4/orchagent.sh @@ -1,6 +1,10 @@ #!/usr/bin/env bash -MAC_ADDRESS=`ip link show eth0 | grep ether | awk '{print $2}'` +MAC_ADDRESS=$(sonic-cfggen -d -v 'DEVICE_METADATA.localhost.mac') +if [ "$MAC_ADDRESS" == "None" ] || [ -z "$MAC_ADDRESS" ]; then + MAC_ADDRESS=$(ip link show eth0 | grep ether | awk '{print $2}') + logger "Mac address not found in Device Metadata, Falling back to eth0" +fi # Create a folder for SsWW record files mkdir -p /var/log/swss diff --git a/platform/vs/docker-sonic-vs/orchagent.sh b/platform/vs/docker-sonic-vs/orchagent.sh index d9bebf117346..2acd709a8e94 100755 --- a/platform/vs/docker-sonic-vs/orchagent.sh +++ b/platform/vs/docker-sonic-vs/orchagent.sh @@ -6,7 +6,11 @@ else export platform=$fake_platform fi -MAC_ADDRESS=`ip link show eth0 | grep ether | awk '{print $2}'` +MAC_ADDRESS=$(sonic-cfggen -d -v 'DEVICE_METADATA.localhost.mac') +if [ "$MAC_ADDRESS" == "None" ] || [ -z "$MAC_ADDRESS" ]; then + MAC_ADDRESS=$(ip link show eth0 | grep ether | awk '{print $2}') + logger "Mac address not found in Device Metadata, Falling back to eth0" +fi # Create a folder for SwSS record files mkdir -p /var/log/swss From 315663241d9a6f607c5edf72eea4b6b50a8754dc Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Fri, 21 Feb 2020 10:20:07 -0800 Subject: [PATCH 078/178] Made Change to have Configurable option to enable/disable docker image (#4171) * Made Change to have Configurable option to enable/disable docker image * [Submodule-Update] sonic-utilities . Following PR has been merged tp 201911 * Platform Driver Development Framework (PDDF): Adding PDDF CLI utils * [config] Add 'feature' subcommand * [fwutil]: Command-line utility for interacting with platform components * [show] Add subcommand to display the status of auto-restart feature for each container * [config] Add subcommand to configure the status of auto-restart feature for each container * [Command Reference] Document CLI commands related to container auto-restart feature * [config/main.py] Modify reload() function to load configuration from init_cfg.json * Fix for dhcp_relay deletion on a VLAN * [config] Check if service exists before start/stop/restart of service * Multi-Db changes for NAT feature * [reboot] make sure the reboot happens even if platform reboot failed --- rules/config | 3 +++ rules/docker-nat.mk | 4 ++++ slave.mk | 7 +++++++ src/sonic-utilities | 2 +- 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/rules/config b/rules/config index 2ba9dcf301fe..5d4f01e05746 100644 --- a/rules/config +++ b/rules/config @@ -104,3 +104,6 @@ ENABLE_MGMT_FRAMEWORK = y # ENABLE_RESTAPI - build docker-sonic-restapi for configuring the switch using REST APIs ENABLE_RESTAPI = n + +# ENABLE_NAT - build docker-sonic-nat for nat support +ENABLE_NAT = y diff --git a/rules/docker-nat.mk b/rules/docker-nat.mk index f41c8f06647c..dcccc24ba2ff 100644 --- a/rules/docker-nat.mk +++ b/rules/docker-nat.mk @@ -13,13 +13,17 @@ $(DOCKER_NAT)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_P $(DOCKER_NAT)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_STRETCH) +ifeq ($(ENABLE_NAT), y) SONIC_DOCKER_IMAGES += $(DOCKER_NAT) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_NAT) SONIC_STRETCH_DOCKERS += $(DOCKER_NAT) +endif +ifeq ($(ENABLE_NAT), y) SONIC_DOCKER_DBG_IMAGES += $(DOCKER_NAT_DBG) SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_NAT_DBG) SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_NAT_DBG) +endif $(DOCKER_NAT)_CONTAINER_NAME = nat $(DOCKER_NAT)_RUN_OPT += --privileged -t diff --git a/slave.mk b/slave.mk index dc15d7ad2577..f630aaf47f4e 100644 --- a/slave.mk +++ b/slave.mk @@ -116,6 +116,11 @@ ifeq ($(SONIC_ENABLE_SFLOW),y) ENABLE_SFLOW = y endif +ifeq ($(SONIC_ENABLE_NAT),y) +ENABLE_NAT = y +endif + + include $(RULES_PATH)/functions include $(RULES_PATH)/*.mk ifneq ($(CONFIGURED_PLATFORM), undefined) @@ -203,6 +208,7 @@ $(info "BUILD_TIMESTAMP" : "$(BUILD_TIMESTAMP)") $(info "BLDENV" : "$(BLDENV)") $(info "VS_PREPARE_MEM" : "$(VS_PREPARE_MEM)") $(info "ENABLE_SFLOW" : "$(ENABLE_SFLOW)") +$(info "ENABLE_NAT" : "$(ENABLE_NAT)") $(info ) ifeq ($(SONIC_USE_DOCKER_BUILDKIT),y) @@ -649,6 +655,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export enable_system_telemetry="$(ENABLE_SYSTEM_TELEMETRY)" export enable_restapi="$(ENABLE_RESTAPI)" export enable_ztp="$(ENABLE_ZTP)" + export enable_nat="$(ENABLE_NAT)" export shutdown_bgp_on_start="$(SHUTDOWN_BGP_ON_START)" export enable_pfcwd_on_start="$(ENABLE_PFCWD_ON_START)" export installer_debs="$(addprefix $(STRETCH_DEBS_PATH)/,$($*_INSTALLS))" diff --git a/src/sonic-utilities b/src/sonic-utilities index 6a36a6be6a0d..eeb312d85e8d 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 6a36a6be6a0df48062902528970a97460c675bcf +Subproject commit eeb312d85e8d044573521e574bd09889ffa744b9 From 398929c622d405dca01fd42800c4b2cae6f25d77 Mon Sep 17 00:00:00 2001 From: Stepan Blyshchak <38952541+stepanblyschak@users.noreply.github.com> Date: Fri, 21 Feb 2020 00:49:28 +0200 Subject: [PATCH 079/178] [mgmt-framework] start after syncd (#4174) every service starts after syncd to start the most critical parts first Signed-off-by: Stepan Blyschak --- files/build_templates/mgmt-framework.service.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/build_templates/mgmt-framework.service.j2 b/files/build_templates/mgmt-framework.service.j2 index d0a030347b51..acc938c13d90 100644 --- a/files/build_templates/mgmt-framework.service.j2 +++ b/files/build_templates/mgmt-framework.service.j2 @@ -1,7 +1,7 @@ [Unit] Description=Management Framework container Requires=swss.service -After=swss.service +After=swss.service syncd.service Before=ntp-config.service [Service] From 4cadca43c37893310164b3506492587b431cd414 Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Sun, 23 Feb 2020 15:48:15 +0800 Subject: [PATCH 080/178] [Mellanox]Fix issue that syncd rpc docker unable to start (#4181) --- platform/mellanox/docker-syncd-mlnx-rpc.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/mellanox/docker-syncd-mlnx-rpc.mk b/platform/mellanox/docker-syncd-mlnx-rpc.mk index 608c1bb3ad20..ed9eea9ae8f8 100644 --- a/platform/mellanox/docker-syncd-mlnx-rpc.mk +++ b/platform/mellanox/docker-syncd-mlnx-rpc.mk @@ -20,7 +20,7 @@ SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_SYNCD_MLNX_RPC) endif $(DOCKER_SYNCD_MLNX_RPC)_CONTAINER_NAME = syncd -$(DOCKER_SYNCD_MLNX_RPC)_RUN_OPT += --net=host --privileged -t +$(DOCKER_SYNCD_MLNX_RPC)_RUN_OPT += --privileged -t $(DOCKER_SYNCD_MLNX_RPC)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf $(DOCKER_SYNCD_MLNX_RPC)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_SYNCD_MLNX_RPC)_RUN_OPT += -v /host/warmboot:/var/warmboot From fe9baadc544f403c2e207abd639d4e3229a4c115 Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Sat, 22 Feb 2020 07:22:43 -0800 Subject: [PATCH 081/178] Updated the file permission mode to include +x (#4183) This to avoid git status reporting dirty. Signed-off-by: Abhishek Dosi --- platform/broadcom/sonic-platform-modules-quanta/debian/rules | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 platform/broadcom/sonic-platform-modules-quanta/debian/rules diff --git a/platform/broadcom/sonic-platform-modules-quanta/debian/rules b/platform/broadcom/sonic-platform-modules-quanta/debian/rules old mode 100644 new mode 100755 From 1aac1535b28e3ab42250755c6669d8f9d45e9cd4 Mon Sep 17 00:00:00 2001 From: Abhishek Dosi Date: Mon, 24 Feb 2020 11:11:41 -0800 Subject: [PATCH 082/178] [Submodule Update] sonic-swss Following PR have been CHerry-picked: * [portsorch] fix wrong orchagent behaviour when LAG member gets disabled * [team sync/mgr] Add debug message before cleaning up LAGs --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index beff2f0a0b47..a92df1912151 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit beff2f0a0b47ea94057ed8436ae6de385af85e11 +Subproject commit a92df1912151bc152f5629148ae16e7d1ad42371 From 1edb69647e1c6a90d1e194e90e0fb51d52c4a00c Mon Sep 17 00:00:00 2001 From: rajendra-dendukuri <47423477+rajendra-dendukuri@users.noreply.github.com> Date: Wed, 4 Dec 2019 07:50:56 -0500 Subject: [PATCH 083/178] [sonic-ztp]: Build sonic-ztp package (#3299) * Build sonic-ztp package - Add changes in make rules to conditionally include sonic-ztp package Signed-off-by: Rajendra Dendukuri --- Makefile.work | 2 ++ files/build_templates/sonic_debian_extension.j2 | 6 ++++++ rules/config | 3 +++ rules/sonic-ztp.mk | 17 +++++++++++++++++ slave.mk | 1 + 5 files changed, 29 insertions(+) create mode 100644 rules/sonic-ztp.mk diff --git a/Makefile.work b/Makefile.work index c81586ecf577..a1ccf8715567 100644 --- a/Makefile.work +++ b/Makefile.work @@ -7,6 +7,7 @@ # * BUILD_NUMBER: Desired version-number to pass to the building-system. # * ENABLE_DHCP_GRAPH_SERVICE: Enables get-graph service to fetch minigraph files # through http. +# * ENABLE_ZTP: Enables zero touch provisioning. # * SHUTDOWN_BGP_ON_START: Sets admin-down state for all bgp peerings after restart. # * ENABLE_PFCWD_ON_START: Enable PFC Watchdog (PFCWD) on server-facing ports # * by default for TOR switch. @@ -162,6 +163,7 @@ SONIC_BUILD_INSTRUCTION := make \ BUILD_NUMBER=$(BUILD_NUMBER) \ BUILD_TIMESTAMP=$(BUILD_TIMESTAMP) \ ENABLE_DHCP_GRAPH_SERVICE=$(ENABLE_DHCP_GRAPH_SERVICE) \ + ENABLE_ZTP=$(ENABLE_ZTP) \ SHUTDOWN_BGP_ON_START=$(SHUTDOWN_BGP_ON_START) \ SONIC_ENABLE_PFCWD_ON_START=$(ENABLE_PFCWD_ON_START) \ SONIC_ENABLE_SYNCD_RPC=$(ENABLE_SYNCD_RPC) \ diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index aa44ca703507..5ba38a38502a 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -147,6 +147,12 @@ sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install tabulat sudo dpkg --root=$FILESYSTEM_ROOT -i $python_debs_path/python-sonic-utilities_*.deb || \ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f +{% if enable_ztp == "y" %} +# Install ZTP (and its dependencies via 'apt-get -y install -f') +sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/sonic-ztp_*.deb || \ + sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f +{% endif %} + # SONiC utilities installs bash-completion as a dependency. However, it is disabled by default # in bash.bashrc, so we copy a version of the file with it enabled here. sudo cp -f $IMAGE_CONFIGS/bash/bash.bashrc $FILESYSTEM_ROOT/etc/ diff --git a/rules/config b/rules/config index 5d4f01e05746..c168fa5a964e 100644 --- a/rules/config +++ b/rules/config @@ -44,6 +44,9 @@ DEFAULT_PASSWORD = YourPaSsWoRd # If not set (default behavior) the default minigraph built into the image will be used. # ENABLE_DHCP_GRAPH_SERVICE = y +# ENABLE_ZTP - installs Zero Touch Provisioning support. +# ENABLE_ZTP = y + # SHUTDOWN_BGP_ON_START - if set to y all bgp sessions will be in admin down state when # bgp service starts. # SHUTDOWN_BGP_ON_START = y diff --git a/rules/sonic-ztp.mk b/rules/sonic-ztp.mk new file mode 100644 index 000000000000..43615b7dcc8a --- /dev/null +++ b/rules/sonic-ztp.mk @@ -0,0 +1,17 @@ +# SONiC ztp package +# + +ifeq ($(ENABLE_ZTP), y) + +SONIC_ZTP_VERSION = 1.0.0 + +SONIC_ZTP = sonic-ztp_$(SONIC_ZTP_VERSION)_all.deb +$(SONIC_ZTP)_SRC_PATH = $(SRC_PATH)/sonic-ztp +SONIC_DPKG_DEBS += $(SONIC_ZTP) +SONIC_STRETCH_DEBS += $(SONIC_ZTP) + +export SONIC_ZTP_VERSION +export SONIC_ZTP + +endif + diff --git a/slave.mk b/slave.mk index f630aaf47f4e..16c4d4ef6a8b 100644 --- a/slave.mk +++ b/slave.mk @@ -632,6 +632,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $(MONIT)) \ $$(addprefix $(TARGET_PATH)/,$$($$*_DOCKERS)) \ $$(addprefix $(FILES_PATH)/,$$($$*_FILES)) \ + $(if $(findstring y,$(ENABLE_ZTP)),$(addprefix $(DEBS_PATH)/,$(SONIC_ZTP))) \ $(addprefix $(STRETCH_FILES_PATH)/, $(if $(filter $(CONFIGURED_ARCH),amd64), $(IXGBE_DRIVER))) \ $(addprefix $(PYTHON_DEBS_PATH)/,$(SONIC_UTILS)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_CONFIG_ENGINE)) \ From 69879e4ed4d2d0c72b88d9b63c446869085f4f52 Mon Sep 17 00:00:00 2001 From: rajendra-dendukuri <47423477+rajendra-dendukuri@users.noreply.github.com> Date: Mon, 16 Dec 2019 11:28:29 -0500 Subject: [PATCH 084/178] [sonic-ztp]: Add Azure/sonic-ztp as a submodule to Azure/sonic-buildimage (#3903) --- .gitmodules | 3 +++ src/sonic-ztp | 1 + 2 files changed, 4 insertions(+) create mode 160000 src/sonic-ztp diff --git a/.gitmodules b/.gitmodules index afaa78686c14..ca8b4b0098a8 100644 --- a/.gitmodules +++ b/.gitmodules @@ -79,3 +79,6 @@ path = src/sonic-restapi url = https://github.com/Azure/sonic-restapi.git branch = master +[submodule "src/sonic-ztp"] + path = src/sonic-ztp + url = https://github.com/Azure/sonic-ztp diff --git a/src/sonic-ztp b/src/sonic-ztp new file mode 160000 index 000000000000..374c9e804a9f --- /dev/null +++ b/src/sonic-ztp @@ -0,0 +1 @@ +Subproject commit 374c9e804a9f434cdb58fa7afe0c3f6201bfe56f From c495dc30505a4e151d174e86b141c2e6bb550acd Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Tue, 25 Feb 2020 09:14:23 -0800 Subject: [PATCH 085/178] [broadcom]: Updated BRCM SAI Debian package revision number to 3.7.3.3-2. (#4182) This has patch to fix enable/disable attribute for lag member. It's on top of vanilla 3.7.3.3 --- platform/broadcom/sai.mk | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index 63c1e21ec7fc..54f44271ad56 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,9 +1,9 @@ -BRCM_SAI = libsaibcm_3.7.3.3_amd64.deb -$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm_3.7.3.3_amd64.deb?sv=2015-04-05&sr=b&sig=Y66VSRUEl4PDf5kHRo%2FS3DBBE9tONSyCzNJvi8IP9n8%3D&se=2033-08-25T01%3A22%3A08Z&sp=r" +BRCM_SAI = libsaibcm_3.7.3.3-2_amd64.deb +$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm_3.7.3.3-2_amd64.deb?sv=2015-04-05&sr=b&sig=701AT0Rwcn%2FKT33UPE1TTQRoJ9tQG0iDfOSXXVCtnyY%3D&se=2033-10-29T22%3A32%3A29Z&sp=r" -BRCM_SAI_DEV = libsaibcm-dev_3.7.3.3_amd64.deb +BRCM_SAI_DEV = libsaibcm-dev_3.7.3.3-2_amd64.deb $(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV))) -$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm-dev_3.7.3.3_amd64.deb?sv=2015-04-05&sr=b&sig=6%2BWzgFL845H9lKE0COsN53P4MO4UWfSo0z%2FmUMFbYVk%3D&se=2033-08-25T01%3A21%3A50Z&sp=r" +$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm-dev_3.7.3.3-2_amd64.deb?sv=2015-04-05&sr=b&sig=vXdUpaP0o71SatqEoqqDH2kai%2FLuFUWZWZAy7HKfeiQ%3D&se=2033-10-29T22%3A31%3A07Z&sp=r" SONIC_ONLINE_DEBS += $(BRCM_SAI) -$(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) \ No newline at end of file +$(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) From 5c8c4b2a50ba368f0dc9208da28acd654aa0cc47 Mon Sep 17 00:00:00 2001 From: yozhao101 <56170650+yozhao101@users.noreply.github.com> Date: Tue, 3 Mar 2020 16:50:32 -0800 Subject: [PATCH 086/178] [Services] Restart BGP service upon unexpected critical process exit. (#4207) --- dockers/docker-database/supervisord.conf.j2 | 1 - dockers/docker-fpm-frr/Dockerfile.j2 | 2 ++ dockers/docker-fpm-frr/critical_processes | 5 +++++ dockers/docker-fpm-frr/supervisord.conf | 8 +++++++- dockers/docker-fpm-gobgp/Dockerfile.j2 | 2 ++ dockers/docker-fpm-gobgp/critical_processes | 2 ++ dockers/docker-fpm-gobgp/supervisord.conf | 8 +++++++- dockers/docker-fpm-quagga/Dockerfile.j2 | 2 ++ dockers/docker-fpm-quagga/critical_processes | 4 ++++ dockers/docker-fpm-quagga/supervisord.conf | 8 +++++++- files/build_templates/single_instance/bgp.service.j2 | 4 ++++ rules/docker-fpm-frr.mk | 2 ++ rules/docker-fpm-gobgp.mk | 1 + rules/docker-fpm-quagga.mk | 2 ++ 14 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 dockers/docker-fpm-frr/critical_processes create mode 100644 dockers/docker-fpm-gobgp/critical_processes create mode 100644 dockers/docker-fpm-quagga/critical_processes diff --git a/dockers/docker-database/supervisord.conf.j2 b/dockers/docker-database/supervisord.conf.j2 index 442bec1438c8..9e855527edba 100644 --- a/dockers/docker-database/supervisord.conf.j2 +++ b/dockers/docker-database/supervisord.conf.j2 @@ -9,7 +9,6 @@ events=PROCESS_STATE_EXITED autostart=true autorestart=unexpected - [program:rsyslogd] command=/bin/bash -c "rm -f /var/run/rsyslogd.pid && /usr/sbin/rsyslogd -n" priority=1 diff --git a/dockers/docker-fpm-frr/Dockerfile.j2 b/dockers/docker-fpm-frr/Dockerfile.j2 index 418676c18329..1c670682a342 100644 --- a/dockers/docker-fpm-frr/Dockerfile.j2 +++ b/dockers/docker-fpm-frr/Dockerfile.j2 @@ -50,6 +50,8 @@ COPY ["snmp.conf", "/etc/snmp/frr.conf"] COPY ["TSA", "/usr/bin/TSA"] COPY ["TSB", "/usr/bin/TSB"] COPY ["TSC", "/usr/bin/TSC"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor"] RUN chmod a+x /usr/bin/TSA && \ chmod a+x /usr/bin/TSB && \ chmod a+x /usr/bin/TSC diff --git a/dockers/docker-fpm-frr/critical_processes b/dockers/docker-fpm-frr/critical_processes new file mode 100644 index 000000000000..8ea09e1bb538 --- /dev/null +++ b/dockers/docker-fpm-frr/critical_processes @@ -0,0 +1,5 @@ +zebra +staticd +bgpd +fpmsyncd +bgpcfgd diff --git a/dockers/docker-fpm-frr/supervisord.conf b/dockers/docker-fpm-frr/supervisord.conf index fe0ce6eda1a4..3e544b64b296 100644 --- a/dockers/docker-fpm-frr/supervisord.conf +++ b/dockers/docker-fpm-frr/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener --container-name bgp +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 @@ -25,7 +31,7 @@ stderr_logfile=syslog command=/usr/sbin/rsyslogd -n priority=3 autostart=false -autorestart=false +autorestart=unexpected startsecs=0 stdout_logfile=syslog stderr_logfile=syslog diff --git a/dockers/docker-fpm-gobgp/Dockerfile.j2 b/dockers/docker-fpm-gobgp/Dockerfile.j2 index 1e333d9026c0..b9b969edeb09 100644 --- a/dockers/docker-fpm-gobgp/Dockerfile.j2 +++ b/dockers/docker-fpm-gobgp/Dockerfile.j2 @@ -24,5 +24,7 @@ COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["*.j2", "/usr/share/sonic/templates/"] COPY ["daemons", "/etc/quagga/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor"] ENTRYPOINT ["/usr/bin/supervisord"] diff --git a/dockers/docker-fpm-gobgp/critical_processes b/dockers/docker-fpm-gobgp/critical_processes new file mode 100644 index 000000000000..2a9e47831e0d --- /dev/null +++ b/dockers/docker-fpm-gobgp/critical_processes @@ -0,0 +1,2 @@ +gobgpd +fpmsyncd diff --git a/dockers/docker-fpm-gobgp/supervisord.conf b/dockers/docker-fpm-gobgp/supervisord.conf index 4e635f4093d4..b814dc024fa3 100644 --- a/dockers/docker-fpm-gobgp/supervisord.conf +++ b/dockers/docker-fpm-gobgp/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener --container-name bgp +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 @@ -15,7 +21,7 @@ stderr_logfile=syslog command=/usr/sbin/rsyslogd -n priority=2 autostart=false -autorestart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog diff --git a/dockers/docker-fpm-quagga/Dockerfile.j2 b/dockers/docker-fpm-quagga/Dockerfile.j2 index f048e2789429..9d1312d073ee 100644 --- a/dockers/docker-fpm-quagga/Dockerfile.j2 +++ b/dockers/docker-fpm-quagga/Dockerfile.j2 @@ -33,5 +33,7 @@ RUN rm -rf /debs ~/.cache COPY ["bgpcfgd", "start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["*.j2", "/usr/share/sonic/templates/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor"] ENTRYPOINT ["/usr/bin/supervisord"] diff --git a/dockers/docker-fpm-quagga/critical_processes b/dockers/docker-fpm-quagga/critical_processes new file mode 100644 index 000000000000..f151af9c4bdd --- /dev/null +++ b/dockers/docker-fpm-quagga/critical_processes @@ -0,0 +1,4 @@ +zebra +bgpd +fpmsyncd +bgpcfgd diff --git a/dockers/docker-fpm-quagga/supervisord.conf b/dockers/docker-fpm-quagga/supervisord.conf index c4351fafefe9..7397a7428a08 100644 --- a/dockers/docker-fpm-quagga/supervisord.conf +++ b/dockers/docker-fpm-quagga/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener --container-name bgp +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 @@ -25,7 +31,7 @@ stderr_logfile=syslog command=/usr/sbin/rsyslogd -n priority=3 autostart=false -autorestart=false +autorestart=unexpected startsecs=0 stdout_logfile=syslog stderr_logfile=syslog diff --git a/files/build_templates/single_instance/bgp.service.j2 b/files/build_templates/single_instance/bgp.service.j2 index 7200a0e3ecf2..fdf9d9c78c04 100644 --- a/files/build_templates/single_instance/bgp.service.j2 +++ b/files/build_templates/single_instance/bgp.service.j2 @@ -3,12 +3,16 @@ Description=BGP container Requires=updategraph.service After=updategraph.service Before=ntp-config.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 [Service] User={{ sonicadmin_user }} ExecStartPre=/usr/bin/{{docker_container_name}}.sh start ExecStart=/usr/bin/{{docker_container_name}}.sh wait ExecStop=/usr/bin/{{docker_container_name}}.sh stop +Restart=always +RestartSec=30 [Install] WantedBy=multi-user.target diff --git a/rules/docker-fpm-frr.mk b/rules/docker-fpm-frr.mk index 1d918830ab55..517aff3ea9fc 100644 --- a/rules/docker-fpm-frr.mk +++ b/rules/docker-fpm-frr.mk @@ -26,6 +26,8 @@ $(DOCKER_FPM_FRR)_RUN_OPT += --privileged -t $(DOCKER_FPM_FRR)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_FPM_FRR)_RUN_OPT += -v /etc/sonic/frr:/etc/frr:rw +$(DOCKER_FPM_FRR)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) + $(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += vtysh:/usr/bin/vtysh $(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += TSA:/usr/bin/TSA $(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += TSB:/usr/bin/TSB diff --git a/rules/docker-fpm-gobgp.mk b/rules/docker-fpm-gobgp.mk index 3e1839d47099..03ec88e85b56 100644 --- a/rules/docker-fpm-gobgp.mk +++ b/rules/docker-fpm-gobgp.mk @@ -9,3 +9,4 @@ SONIC_DOCKER_IMAGES += $(DOCKER_FPM_GOBGP) $(DOCKER_FPM_GOBGP)_CONTAINER_NAME = bgp $(DOCKER_FPM_GOBGP)_RUN_OPT += --privileged -t $(DOCKER_FPM_GOBGP)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_FPM_GOBPG)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/rules/docker-fpm-quagga.mk b/rules/docker-fpm-quagga.mk index 2c78d1917b0e..5a384eedab2c 100644 --- a/rules/docker-fpm-quagga.mk +++ b/rules/docker-fpm-quagga.mk @@ -10,4 +10,6 @@ $(DOCKER_FPM_QUAGGA)_CONTAINER_NAME = bgp $(DOCKER_FPM_QUAGGA)_RUN_OPT += --privileged -t $(DOCKER_FPM_QUAGGA)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_FPM_QUAGGA)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) + $(DOCKER_FPM_QUAGGA)_BASE_IMAGE_FILES += vtysh:/usr/bin/vtysh From d2c10bab2952d8f361e00163d34eb0ca608fa035 Mon Sep 17 00:00:00 2001 From: Stepan Blyshchak <38952541+stepanblyschak@users.noreply.github.com> Date: Sat, 29 Feb 2020 01:57:03 +0200 Subject: [PATCH 087/178] [snmp] remove hostname change as it share uts namespace with host (#4206) Signed-off-by: Stepan Blyschak --- dockers/docker-snmp-sv2/start.sh | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/dockers/docker-snmp-sv2/start.sh b/dockers/docker-snmp-sv2/start.sh index 786968cf9d90..6ec3379df58f 100755 --- a/dockers/docker-snmp-sv2/start.sh +++ b/dockers/docker-snmp-sv2/start.sh @@ -9,17 +9,6 @@ sonic-cfggen -d -y /etc/sonic/snmp.yml -t /usr/share/sonic/templates/snmpd.conf. mkdir -p /var/sonic echo "# Config files managed by sonic-config-engine" > /var/sonic/config_status -CURRENT_HOSTNAME=`hostname` -HOSTNAME=`sonic-cfggen -d -v DEVICE_METADATA[\'localhost\'][\'hostname\']` - -if [ "$?" == "0" ] && [ "$HOSTNAME" != "" ]; then - echo $HOSTNAME > /etc/hostname - hostname -F /etc/hostname - - sed -i "/\s$CURRENT_HOSTNAME$/d" /etc/hosts - echo "127.0.0.1 $HOSTNAME" >> /etc/hosts -fi - rm -f /var/run/rsyslogd.pid supervisorctl start rsyslogd From bd99464d5268333ca4e8ce1c633bd17377b87f9a Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Thu, 27 Feb 2020 22:08:52 -0800 Subject: [PATCH 088/178] [sonic-cfggen] Load JSON files before minigraph file (#4202) If sonic-cfggen is passed the -m argument (to load the minigraph file) along with one or more -j arguments, load the JSON files before loading the minigraph file. This ensures that the init_cfg.json file is loaded before the minigraph, therefore the minigraph can override any default configuration options specified in init_cfg.json. Currently, the behavior is reversed. Note: This is not an issue if loading loading multiple JSON files, because sonic-cfggen loads them in the left-to-right order they were specified on the command line, therefore providing flexibility for loading JSON files in a specific order. As long as init_cfg.json is specified before config_db.json, the values specified in config_db.json will take precedence. --- src/sonic-config-engine/sonic-cfggen | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index 7cff6c9fb384..34f5a36f0fe3 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -233,6 +233,10 @@ def main(): sys.exit(1) deep_update(data, {'PORT': ports}) + for json_file in args.json: + with open(json_file, 'r') as stream: + deep_update(data, FormatConverter.to_deserialized(json.load(stream))) + if args.minigraph != None: minigraph = args.minigraph if platform: @@ -254,10 +258,6 @@ def main(): additional_data = yaml.load(stream) deep_update(data, FormatConverter.to_deserialized(additional_data)) - for json_file in args.json: - with open(json_file, 'r') as stream: - deep_update(data, FormatConverter.to_deserialized(json.load(stream))) - if args.additional_data != None: deep_update(data, json.loads(args.additional_data)) From aef526306199cf4c21811b3d70e889473cfefa27 Mon Sep 17 00:00:00 2001 From: noaOrMlnx <58519608+noaOrMlnx@users.noreply.github.com> Date: Fri, 28 Feb 2020 07:03:13 +0200 Subject: [PATCH 089/178] [Mellanox] Update MFT version to 4.13.5 (#4199) --- platform/mellanox/mft.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/mellanox/mft.mk b/platform/mellanox/mft.mk index af2192de4543..e6c9d9ba0ea6 100644 --- a/platform/mellanox/mft.mk +++ b/platform/mellanox/mft.mk @@ -1,7 +1,7 @@ # Mellanox SAI -MFT_VERSION = 4.13.3 -MFT_REVISION = 6 +MFT_VERSION = 4.13.5 +MFT_REVISION = 1 export MFT_VERSION MFT_REVISION From 0050cc1ce7b0c3f4c633572cf2514c72cf320c58 Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Wed, 4 Mar 2020 03:19:30 +0800 Subject: [PATCH 090/178] filter out CPU ports to avoid any operation on them (#4197) --- device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfplpmset.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfplpmset.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfplpmset.py index c11675766d3f..f9b35b8e74e7 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfplpmset.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfplpmset.py @@ -18,14 +18,19 @@ PMAOS_ENABLE = 1 PMAOS_DISABLE = 2 +PORT_TYPE_CPU = 4 PORT_TYPE_NVE = 8 PORT_TYPE_OFFSET = 28 PORT_TYPE_MASK = 0xF0000000 NVE_MASK = PORT_TYPE_MASK & (PORT_TYPE_NVE << PORT_TYPE_OFFSET) +CPU_MASK = PORT_TYPE_MASK & (PORT_TYPE_CPU << PORT_TYPE_OFFSET) def is_nve(port): return (port & NVE_MASK) != 0 +def is_cpu(port): + return (port & CPU_MASK) != 0 + def is_port_admin_status_up(log_port): oper_state_p = new_sx_port_oper_state_t_p() admin_state_p = new_sx_port_admin_state_t_p() @@ -57,6 +62,7 @@ def get_log_ports(handle, sfp_module): for i in range(0, port_cnt): port_attributes = sx_port_attributes_t_arr_getitem(port_attributes_list, i) if is_nve(int(port_attributes.log_port)) == False \ + and is_cpu(int(port_attributes.log_port)) == False \ and port_attributes.port_mapping.module_port == sfp_module \ and is_port_admin_status_up(port_attributes.log_port): log_port_list.append(port_attributes.log_port) From c603ed32fd9115b6eb87dc04b7a53bb9f509d87e Mon Sep 17 00:00:00 2001 From: Mykola F <37578614+mykolaf@users.noreply.github.com> Date: Tue, 25 Feb 2020 10:25:31 +0200 Subject: [PATCH 091/178] cherrypick [Mellanox] update hw-mgmt patch for SimX (#4180) Signed-off-by: Mykola Faryma --- .../0001-Make-hw-mgmt-SimX-compatiable.patch | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/platform/mellanox/hw-management/0001-Make-hw-mgmt-SimX-compatiable.patch b/platform/mellanox/hw-management/0001-Make-hw-mgmt-SimX-compatiable.patch index 31a85434fb49..ff792af02beb 100644 --- a/platform/mellanox/hw-management/0001-Make-hw-mgmt-SimX-compatiable.patch +++ b/platform/mellanox/hw-management/0001-Make-hw-mgmt-SimX-compatiable.patch @@ -1,7 +1,7 @@ -From 051938b7c49cc18aaddd699939353f591554d635 Mon Sep 17 00:00:00 2001 +From 6aecc8fed8cc78c1fb5c6b52bdfa3d07ca66e652 Mon Sep 17 00:00:00 2001 From: Mykola Faryma -Date: Wed, 3 Apr 2019 14:09:26 +0000 -Subject: [PATCH] Make hw-mgmt SimX compatiable. +Date: Fri, 21 Feb 2020 12:28:54 +0200 +Subject: [PATCH 1/1] Make hw-mgmt SimX compatiable Signed-off-by: Mykola Faryma --- @@ -9,7 +9,7 @@ Signed-off-by: Mykola Faryma 1 file changed, 29 insertions(+) diff --git a/usr/usr/bin/hw-management.sh b/usr/usr/bin/hw-management.sh -index fdb3013..68da9bc 100755 +index cff10fe..7f3c295 100755 --- a/usr/usr/bin/hw-management.sh +++ b/usr/usr/bin/hw-management.sh @@ -646,6 +646,35 @@ do_chip_down() @@ -40,9 +40,9 @@ index fdb3013..68da9bc 100755 + esac +} + -+if [[ "$(cat /sys/devices/virtual/dmi/id/chassis_vendor)" = "QEMU" ]]; then -+ handle_simx -+ exit 0 ++if [[ "$(cat /sys/devices/virtual/dmi/id/sys_vendor)" = "QEMU" ]]; then ++ handle_simx ++ exit 0 +fi + case $ACTION in From 11503c76e7718845461ce0bbad45aa4b168dc1ef Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Wed, 26 Feb 2020 21:27:52 +0200 Subject: [PATCH 092/178] [image]: Add SSD maintenance utility - hdparm. (#4177) Signed-off-by: Nazarii Hnydyn --- build_debian.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/build_debian.sh b/build_debian.sh index d21456b2be45..7d87f0508fad 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -139,7 +139,9 @@ sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/initramfs-tools_*.deb || \ sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/linux-image-${LINUX_KERNEL_VERSION}-*_${CONFIGURED_ARCH}.deb || \ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install acl -[[ $CONFIGURED_ARCH == amd64 ]] && sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install dmidecode +if [[ $CONFIGURED_ARCH == amd64 ]]; then + sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install dmidecode hdparm +fi ## Update initramfs for booting with squashfs+overlay cat files/initramfs-tools/modules | sudo tee -a $FILESYSTEM_ROOT/etc/initramfs-tools/modules > /dev/null From 8581a52571fcca16a7c23d8064283fd72534a526 Mon Sep 17 00:00:00 2001 From: rajendra-dendukuri <47423477+rajendra-dendukuri@users.noreply.github.com> Date: Tue, 10 Dec 2019 11:16:56 -0500 Subject: [PATCH 093/178] ZTP infrastructure changes to support DHCP discovery provisioning data (#3298) * ZTP infrastructure changes to support DHCP discovery provisioning data - Dynamically generate DHCP client configuration based on current ZTP state - Added support to request and process hostname when using DHCPv6 - Do not process graphservice url dhcp option if ZTP is enabled, ZTP service will process it - Generate /e/n/i file with all active interfaces seeking address assignment via DHCP. Only interfaces that are created in Linux will be added to /e/n/i. Also DHCP is started only on linked up in-band interfaces. Signed-off-by: Rajendra Dendukuri --- build_debian.sh | 5 +-- .../build_templates/sonic_debian_extension.j2 | 6 +++ files/dhcp/90-dhcp6-systcl.conf.j2 | 7 +++ files/dhcp/dhclient.conf | 24 ---------- files/dhcp/dhclient.conf.j2 | 45 +++++++++++++++++++ files/dhcp/graphserviceurl | 26 ++++++----- files/dhcp/ifupdown2_policy.json | 12 +++++ files/dhcp/rfc3442-classless-routes | 7 ++- files/dhcp/sethostname6 | 14 ++++++ .../interfaces/interfaces-config.sh | 34 +++++++++++++- files/image_config/interfaces/interfaces.j2 | 36 +++++++++++++++ 11 files changed, 174 insertions(+), 42 deletions(-) create mode 100644 files/dhcp/90-dhcp6-systcl.conf.j2 delete mode 100644 files/dhcp/dhclient.conf create mode 100644 files/dhcp/dhclient.conf.j2 create mode 100644 files/dhcp/ifupdown2_policy.json create mode 100644 files/dhcp/sethostname6 diff --git a/build_debian.sh b/build_debian.sh index 7d87f0508fad..7583942b23c3 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -396,9 +396,6 @@ set /files/etc/sysctl.conf/net.ipv6.conf.default.keep_addr_on_down 1 set /files/etc/sysctl.conf/net.ipv6.conf.all.keep_addr_on_down 1 set /files/etc/sysctl.conf/net.ipv6.conf.eth0.keep_addr_on_down 1 -set /files/etc/sysctl.conf/net.ipv6.conf.eth0.accept_ra_defrtr 0 -set /files/etc/sysctl.conf/net.ipv6.conf.eth0.accept_ra 0 - set /files/etc/sysctl.conf/net.ipv4.tcp_l3mdev_accept 1 set /files/etc/sysctl.conf/net.ipv4.udp_l3mdev_accept 1 @@ -433,10 +430,10 @@ EOF sudo cp files/dhcp/rfc3442-classless-routes $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks.d sudo cp files/dhcp/sethostname $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks.d/ +sudo cp files/dhcp/sethostname6 $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks.d/ sudo cp files/dhcp/graphserviceurl $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks.d/ sudo cp files/dhcp/snmpcommunity $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks.d/ sudo cp files/dhcp/vrf $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks.d/ -sudo cp files/dhcp/dhclient.conf $FILESYSTEM_ROOT/etc/dhcp/ if [ -f files/image_config/ntp/ntp ]; then sudo cp ./files/image_config/ntp/ntp $FILESYSTEM_ROOT/etc/init.d/ fi diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 5ba38a38502a..9967f0fefdef 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -219,6 +219,12 @@ sudo cp $IMAGE_CONFIGS/interfaces/interfaces-config.sh $FILESYSTEM_ROOT/usr/bin/ sudo cp $IMAGE_CONFIGS/interfaces/*.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ echo "interfaces-config.service" | sudo tee -a $GENERATED_SERVICE_FILE +# Copy dhcp client configuration template and create an initial configuration +sudo cp files/dhcp/dhclient.conf.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ +j2 files/dhcp/dhclient.conf.j2 | sudo tee $FILESYSTEM_ROOT/etc/dhcp/dhclient.conf +sudo cp files/dhcp/ifupdown2_policy.json $FILESYSTEM_ROOT/etc/network/ifupdown2/policy.d +sudo cp files/dhcp/90-dhcp6-systcl.conf.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ + # Copy initial interfaces configuration file, will be overwritten on first boot sudo cp $IMAGE_CONFIGS/interfaces/init_interfaces $FILESYSTEM_ROOT/etc/network/interfaces sudo mkdir -p $FILESYSTEM_ROOT/etc/network/interfaces.d diff --git a/files/dhcp/90-dhcp6-systcl.conf.j2 b/files/dhcp/90-dhcp6-systcl.conf.j2 new file mode 100644 index 000000000000..addb94675258 --- /dev/null +++ b/files/dhcp/90-dhcp6-systcl.conf.j2 @@ -0,0 +1,7 @@ +{% if MGMT_INTERFACE %} +net.ipv6.conf.eth0.accept_ra_defrtr = 0 +net.ipv6.conf.eth0.accept_ra = 0 +{% else %} +net.ipv6.conf.eth0.accept_ra_defrtr = 1 +net.ipv6.conf.eth0.accept_ra = 1 +{% endif %} diff --git a/files/dhcp/dhclient.conf b/files/dhcp/dhclient.conf deleted file mode 100644 index 6a542e069fab..000000000000 --- a/files/dhcp/dhclient.conf +++ /dev/null @@ -1,24 +0,0 @@ -# Configuration file for /sbin/dhclient, which is included in Debian's -# dhcp3-client package. -# -# This is a sample configuration file for dhclient. See dhclient.conf's -# man page for more information about the syntax of this file -# and a more comprehensive list of the parameters understood by -# dhclient. -# -# Normally, if the DHCP server provides reasonable information and does -# not leave anything out (like the domain name, for example), then -# few changes must be made to this file, if any. -# - -option rfc3442-classless-static-routes code 121 = array of unsigned integer 8; -option snmp-community code 224 = text; -option minigraph-url code 225 = text; -option acl-url code 226 = text; - -send host-name = gethostname(); -request subnet-mask, broadcast-address, time-offset, routers, - domain-name, domain-name-servers, domain-search, host-name, - dhcp6.name-servers, dhcp6.domain-search, interface-mtu, - rfc3442-classless-static-routes, ntp-servers, - snmp-community, minigraph-url, acl-url; diff --git a/files/dhcp/dhclient.conf.j2 b/files/dhcp/dhclient.conf.j2 new file mode 100644 index 000000000000..2a6f6fa84fbd --- /dev/null +++ b/files/dhcp/dhclient.conf.j2 @@ -0,0 +1,45 @@ +{% block banner %} +# =============== Managed by SONiC Config Engine DO NOT EDIT! =============== +# generated from /usr/share/sonic/templates/dhclient.conf.j2 using sonic-cfggen +# file: /etc/dhcp/dhclient.conf +# +{% endblock banner %} +# Configuration file for /sbin/dhclient, which is included in Debian's +# dhcp3-client package. +# +# This is a sample configuration file for dhclient. See dhclient.conf's +# man page for more information about the syntax of this file +# and a more comprehensive list of the parameters understood by +# dhclient. +# +# Normally, if the DHCP server provides reasonable information and does +# not leave anything out (like the domain name, for example), then +# few changes must be made to this file, if any. +# + +option rfc3442-classless-static-routes code 121 = array of unsigned integer 8; +option snmp-community code 224 = text; +option minigraph-url code 225 = text; +option acl-url code 226 = text; +option tftp-server-name code 66 = text; +option bootfile-name code 67 = text; +option user-class code 77 = text; +option provisioning-script-url code 239 = text; +option dhcp6.user-class code 15 = text; +option dhcp6.provisioning-script-url code 239 = text; +option dhcp6.boot-file-url code 59 = text; + +send host-name = gethostname(); +request subnet-mask, broadcast-address, time-offset, routers, + domain-name, domain-name-servers, domain-search, host-name, + dhcp6.name-servers, dhcp6.domain-search, interface-mtu, dhcp6.fqdn, + rfc3442-classless-static-routes, ntp-servers, log-servers, +{%- if ZTP is defined and ZTP_DHCP_DISABLED is not defined -%}bootfile-name, provisioning-script-url, tftp-server-name, + dhcp6.provisioning-script-url, dhcp6.boot-file-url,{%- endif -%} + snmp-community, minigraph-url, acl-url; +{% if ZTP is defined and ZTP_DHCP_DISABLED is not defined %} +send user-class "SONiC-ZTP"; +send dhcp6.user-class "SONiC-ZTP"; +send dhcp-client-identifier "SONiC##{{ ZTP['mode']['product-name'] }}##{{ ZTP['mode']['serial-no'] }}"; +retry 60; +{% endif %} diff --git a/files/dhcp/graphserviceurl b/files/dhcp/graphserviceurl index f255cdff9877..9bd5fded4b8f 100644 --- a/files/dhcp/graphserviceurl +++ b/files/dhcp/graphserviceurl @@ -1,12 +1,14 @@ -case $reason in - BOUND|RENEW|REBIND|REBOOT) - if [ -n "$new_minigraph_url" ]; then - echo $new_minigraph_url > /tmp/dhcp_graph_url - else - echo "N/A" > /tmp/dhcp_graph_url - fi - if [ -n "$new_acl_url" ]; then - echo $new_acl_url > /tmp/dhcp_acl_url - fi - ;; -esac +if [ ! -e /usr/bin/ztp ] || [ "$(ztp status -c)" = "0:DISABLED" ]; then + case $reason in + BOUND|RENEW|REBIND|REBOOT) + if [ -n "$new_minigraph_url" ]; then + echo $new_minigraph_url > /tmp/dhcp_graph_url + else + echo "N/A" > /tmp/dhcp_graph_url + fi + if [ -n "$new_acl_url" ]; then + echo $new_acl_url > /tmp/dhcp_acl_url + fi + ;; + esac +fi diff --git a/files/dhcp/ifupdown2_policy.json b/files/dhcp/ifupdown2_policy.json new file mode 100644 index 000000000000..9a5010dead8a --- /dev/null +++ b/files/dhcp/ifupdown2_policy.json @@ -0,0 +1,12 @@ +{ + "dhcp" : { + "defaults" : { + "dhcp-wait" : "no" + }, + "iface_defaults" : { + "eth0" : { + "dhcp6-duid" : "LL" + } + } + } +} diff --git a/files/dhcp/rfc3442-classless-routes b/files/dhcp/rfc3442-classless-routes index 64e24192816b..797a0d24429f 100644 --- a/files/dhcp/rfc3442-classless-routes +++ b/files/dhcp/rfc3442-classless-routes @@ -55,8 +55,13 @@ if [ "$RUN" = "yes" ]; then fi # set route (ip detects host routes automatically) - ip -4 route add "${net_address}/${net_length}" \ + if echo $interface | grep -v Ethernet ; then + ip -4 route add "${net_address}/${net_length}" \ ${via_arg} dev "${interface}" table default >/dev/null 2>&1 + else + ip -4 route add "${net_address}/${net_length}" \ + ${via_arg} dev "${interface}" >/dev/null 2>&1 + fi done fi fi diff --git a/files/dhcp/sethostname6 b/files/dhcp/sethostname6 new file mode 100644 index 000000000000..6ca5d8dbc995 --- /dev/null +++ b/files/dhcp/sethostname6 @@ -0,0 +1,14 @@ +case $reason in + BOUND6|RENEW6|REBIND6|REBOOT) + current_dhcp6_fqdn=`hostname` + if [ "$current_dhcp6_fqdn" != "$new_dhcp6_fqdn" ] && [ -n "$new_dhcp6_fqdn" ] + then + echo $new_dhcp6_fqdn > /etc/hostname + hostname -F /etc/hostname + sed -i "/\s$current_dhcp6_fqdn$/d" /etc/hosts + sed -i "/\s$new_dhcp6_fqdn$/d" /etc/hosts + echo "127.0.0.1 $new_dhcp6_fqdn" >> /etc/hosts + echo ":: $new_dhcp6_fqdn" >> /etc/hosts + fi + ;; +esac diff --git a/files/image_config/interfaces/interfaces-config.sh b/files/image_config/interfaces/interfaces-config.sh index 9ee7de392bb6..8dddc215bbd9 100755 --- a/files/image_config/interfaces/interfaces-config.sh +++ b/files/image_config/interfaces/interfaces-config.sh @@ -2,8 +2,40 @@ ifdown --force eth0 -sonic-cfggen -d -t /usr/share/sonic/templates/interfaces.j2 > /etc/network/interfaces +# Check if ZTP DHCP policy has been installed +if [ -e /etc/network/ifupdown2/policy.d/ztp_dhcp.json ]; then + # Obtain port operational state information + redis-dump -d 0 -k "PORT_TABLE:Ethernet*" -y > /tmp/ztp_port_data.json + + if [ $? -ne 0 ] || [ ! -e /tmp/ztp_port_data.json ] || [ "$(cat /tmp/ztp_port_data.json)" = "" ]; then + echo "{}" > /tmp/ztp_port_data.json + fi + + # Create an input file with ztp input information + echo "{ \"PORT_DATA\" : $(cat /tmp/ztp_port_data.json) }" > \ + /tmp/ztp_input.json +else + echo "{ \"ZTP_DHCP_DISABLED\" : \"true\" }" > /tmp/ztp_input.json +fi + +# Create /e/n/i file for existing and active interfaces +sonic-cfggen -d -j /tmp/ztp_input.json -t /usr/share/sonic/templates/interfaces.j2 > /etc/network/interfaces [ -f /var/run/dhclient.eth0.pid ] && kill `cat /var/run/dhclient.eth0.pid` && rm -f /var/run/dhclient.eth0.pid +[ -f /var/run/dhclient6.eth0.pid ] && kill `cat /var/run/dhclient6.eth0.pid` && rm -f /var/run/dhclient6.eth0.pid + +for intf_pid in $(ls -1 /var/run/dhclient*.Ethernet*.pid 2> /dev/null); do + [ -f ${intf_pid} ] && kill `cat ${intf_pid}` && rm -f ${intf_pid} +done +sonic-cfggen -d -j /tmp/ztp_input.json -t /usr/share/sonic/templates/90-dhcp6-systcl.conf.j2 > /etc/sysctl.d/90-dhcp6-systcl.conf +# Read sysctl conf files again +sysctl -p /etc/sysctl.d/90-dhcp6-systcl.conf + +sonic-cfggen -d -j /tmp/ztp_input.json -t /usr/share/sonic/templates/dhclient.conf.j2 > /etc/dhcp/dhclient.conf systemctl restart networking + +# Clean-up created files +rm -f /tmp/ztp_input.json /tmp/ztp_port_data.json + +ifdown lo && ifup lo diff --git a/files/image_config/interfaces/interfaces.j2 b/files/image_config/interfaces/interfaces.j2 index 0b64fdfbbdb2..dbb2b1f3418a 100644 --- a/files/image_config/interfaces/interfaces.j2 +++ b/files/image_config/interfaces/interfaces.j2 @@ -27,6 +27,38 @@ iface lo inet loopback # The management network interface auto eth0 +{% if (ZTP_DHCP_DISABLED is not defined) and (ZTP is defined) and (ZTP['mode'] is defined and ZTP['mode']['profile'] == 'active') %} + + +# ZTP out-of-band interface +allow-hotplug eth0 +{% if ZTP['mode']['ipv4'] == 'true' %} +iface eth0 inet dhcp +{% endif %} +{% if ZTP['mode']['ipv6'] == 'true' %} +iface eth0 inet6 dhcp + up sysctl net.ipv6.conf.eth0.accept_ra=1 + down sysctl net.ipv6.conf.eth0.accept_ra=0 +{% endif %} + +{% if ZTP['mode']['inband'] == 'true' %} +{% for port in PORT %} + +# ZTP in-band interface {{ port }} +auto {{ port }} +allow-hotplug {{ port }} +{% if PORT_DATA['PORT_TABLE:'+port] is defined and PORT_DATA['PORT_TABLE:'+port]['value']['oper_status'] == 'up' %} +{% if ZTP['mode']['ipv4'] == 'true' %} +iface {{ port }} inet dhcp +{% endif %} +{% if ZTP['mode']['ipv6'] == 'true' %} +iface {{ port }} inet6 dhcp +{% endif %} +{% endif %} +{% endfor %} +{% endif %} + +{% else %} {% if MGMT_INTERFACE %} {% for (name, prefix) in MGMT_INTERFACE|pfx_filter %} iface eth0 {{ 'inet' if prefix | ipv4 else 'inet6' }} static @@ -70,6 +102,10 @@ iface eth0 inet dhcp up cgset -r l3mdev.master-device=mgmt mgmt down cgdelete -g l3mdev:mgmt {% endif %} +iface eth0 inet6 dhcp + up sysctl net.ipv6.conf.eth0.accept_ra=1 + down sysctl net.ipv6.conf.eth0.accept_ra=0 +{% endif %} {% endif %} # source /etc/network/interfaces.d/* From cc2d497aa4487351175d44892b911626c520e29c Mon Sep 17 00:00:00 2001 From: Abhishek Dosi Date: Wed, 4 Mar 2020 10:46:45 -0800 Subject: [PATCH 094/178] Fixing Bad Cherry-pick --- files/image_config/interfaces/interfaces-config.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/files/image_config/interfaces/interfaces-config.sh b/files/image_config/interfaces/interfaces-config.sh index 8dddc215bbd9..7cb92b3c946e 100755 --- a/files/image_config/interfaces/interfaces-config.sh +++ b/files/image_config/interfaces/interfaces-config.sh @@ -38,4 +38,3 @@ systemctl restart networking # Clean-up created files rm -f /tmp/ztp_input.json /tmp/ztp_port_data.json -ifdown lo && ifup lo From 42e3996a2a87e007da7d511ba6abf108cc15fd7c Mon Sep 17 00:00:00 2001 From: Abhishek Dosi Date: Wed, 4 Mar 2020 10:53:51 -0800 Subject: [PATCH 095/178] [Submodule-Update] sonic-swss. Following changes: Enable m_isCombinedMirrorV6Table for BFN platform (#1212) [vnet]: Update VNET route table size to 40K for BITMAP implementation (#1132) Default action for Egress ACL Table not poulated. (#1208) Add/Del lag_name_map item according to lag adding and removing (#1124) Increase ip2me CIR/CBR for faster in-band file transfers (#1000) --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index a92df1912151..69f5fc9c8e58 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit a92df1912151bc152f5629148ae16e7d1ad42371 +Subproject commit 69f5fc9c8e5861d19cba71a19f77e746fad8d772 From d6abe354e3acb70f0b6e2181ace893a1a555a212 Mon Sep 17 00:00:00 2001 From: Abhishek Dosi Date: Wed, 4 Mar 2020 10:58:33 -0800 Subject: [PATCH 096/178] [Submodule Update] sonic-Utilities with following changes: [fwutil]: Set default socket timeout for FW download to 30 sec. (#821) Update config/show to include PFC Watchdog commands (#736) --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index eeb312d85e8d..a2ca28d1e3be 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit eeb312d85e8d044573521e574bd09889ffa744b9 +Subproject commit a2ca28d1e3be76e85127bd8dc4098fda719e1582 From bf4a282a4114708733797b1708f57c42994df8a2 Mon Sep 17 00:00:00 2001 From: lguohan Date: Wed, 4 Mar 2020 11:58:41 -0800 Subject: [PATCH 097/178] [libteam]: Disregard current state when considering port enablement (#4215) --- ...current-state-when-considering-port-.patch | 67 +++++++++++++++++++ src/libteam/patch/series | 1 + 2 files changed, 68 insertions(+) create mode 100644 src/libteam/patch/0012-teamd-Disregard-current-state-when-considering-port-.patch diff --git a/src/libteam/patch/0012-teamd-Disregard-current-state-when-considering-port-.patch b/src/libteam/patch/0012-teamd-Disregard-current-state-when-considering-port-.patch new file mode 100644 index 000000000000..1673c4e4a9d1 --- /dev/null +++ b/src/libteam/patch/0012-teamd-Disregard-current-state-when-considering-port-.patch @@ -0,0 +1,67 @@ +From b9bde92fcc0586b327c577c41304e2ef938cff10 Mon Sep 17 00:00:00 2001 +From: Petr Machata +Date: Wed, 13 Nov 2019 13:26:47 +0000 +Subject: [PATCH] teamd: Disregard current state when considering port + enablement + +On systems where carrier is gained very quickly, there is a race between +teamd and the kernel that sometimes leads to all team slaves being stuck in +enabled=false state. + +When a port is enslaved to a team device, the kernel sends a netlink +message marking the port as enabled. teamd's lb_event_watch_port_added() +calls team_set_port_enabled(false), because link is down at that point. The +kernel responds with a message marking the port as disabled. At this point, +there are two outstanding messages: the initial one marking port as +enabled, and the second one marking it as disabled. teamd has not processed +either of these. + +Next teamd gets the netlink message that sets enabled=true, and updates its +internal cache accordingly. If at this point ethtool link-watch wakes up, +teamd considers (in teamd_port_check_enable()) enabling the port. After +consulting the cache, it concludes the port is already up, and neglects to +do so. Only then does teamd get the netlink message informing it of setting +enabled=false. + +The problem is that the teamd cache is not synchronous with respect to the +kernel state. If the carrier takes a while to come up (as is normally the +case), this is not a problem, because teamd caches up quickly enough. But +this may not always be the case, and particularly on a simulated system, +the carrier is gained almost immediately. + +Fix this by not suppressing the enablement message. + +Signed-off-by: Petr Machata +Signed-off-by: Jiri Pirko +--- + teamd/teamd_per_port.c | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +diff --git a/teamd/teamd_per_port.c b/teamd/teamd_per_port.c +index d10cfb2..8c63fec 100644 +--- a/teamd/teamd_per_port.c ++++ b/teamd/teamd_per_port.c +@@ -448,18 +448,14 @@ int teamd_port_check_enable(struct teamd_context *ctx, + bool should_enable, bool should_disable) + { + bool new_enabled_state; +- bool curr_enabled_state; + int err; + + if (!teamd_port_present(ctx, tdport)) + return 0; +- err = teamd_port_enabled(ctx, tdport, &curr_enabled_state); +- if (err) +- return err; + +- if (!curr_enabled_state && should_enable) ++ if (should_enable) + new_enabled_state = true; +- else if (curr_enabled_state && should_disable) ++ else if (should_disable) + new_enabled_state = false; + else + return 0; +-- +2.17.1.windows.2 + diff --git a/src/libteam/patch/series b/src/libteam/patch/series index 62c39e780f1a..966be75fda8a 100644 --- a/src/libteam/patch/series +++ b/src/libteam/patch/series @@ -9,3 +9,4 @@ 0009-Fix-ifinfo_link_with_port-race-condition-with-newlink.patch 0010-When-read-of-timerfd-returned-0-don-t-consider-this-.patch 0011-teamd-fix-possible-race-in-master-ifname-callback.patch +0012-teamd-Disregard-current-state-when-considering-port-.patch From 950926a8370b0b8752515dc04be5439a6618b97a Mon Sep 17 00:00:00 2001 From: byu343 Date: Wed, 11 Mar 2020 13:12:39 -0700 Subject: [PATCH 098/178] [arista]: Add support for Arista Lodoga (#4232) Backport the support of Arista Lodoga to 201911 --- .../Arista-7050CX3-32S-C32/port_config.ini | 35 ++ .../Arista-7050CX3-32S-C32/sai.profile | 1 + .../td3-a7050cx3-32s-32x100G.config.bcm | 503 ++++++++++++++++++ .../x86_64-arista_7050cx3_32s/default_sku | 1 + .../x86_64-arista_7050cx3_32s/fancontrol | 10 + .../x86_64-arista_7050cx3_32s/platform_reboot | 1 + .../arista/x86_64-arista_7050cx3_32s/plugins | 1 + .../x86_64-arista_7050cx3_32s/sensors.conf | 39 ++ files/Aboot/boot0.j2 | 5 + .../barefoot/sonic-platform-modules-arista | 2 +- .../broadcom/sonic-platform-modules-arista | 2 +- 11 files changed, 598 insertions(+), 2 deletions(-) create mode 100644 device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/port_config.ini create mode 100644 device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/sai.profile create mode 100644 device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/td3-a7050cx3-32s-32x100G.config.bcm create mode 100644 device/arista/x86_64-arista_7050cx3_32s/default_sku create mode 100644 device/arista/x86_64-arista_7050cx3_32s/fancontrol create mode 100644 device/arista/x86_64-arista_7050cx3_32s/platform_reboot create mode 100644 device/arista/x86_64-arista_7050cx3_32s/plugins create mode 100644 device/arista/x86_64-arista_7050cx3_32s/sensors.conf diff --git a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/port_config.ini b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/port_config.ini new file mode 100644 index 000000000000..d3d339076a59 --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/port_config.ini @@ -0,0 +1,35 @@ +# name lanes alias index +Ethernet0 1,2,3,4 Ethernet1/1 1 +Ethernet4 5,6,7,8 Ethernet2/1 2 +Ethernet8 9,10,11,12 Ethernet3/1 3 +Ethernet12 13,14,15,16 Ethernet4/1 4 +Ethernet16 21,22,23,24 Ethernet5/1 5 +Ethernet20 17,18,19,20 Ethernet6/1 6 +Ethernet24 25,26,27,28 Ethernet7/1 7 +Ethernet28 29,30,31,32 Ethernet8/1 8 +Ethernet32 37,38,39,40 Ethernet9/1 9 +Ethernet36 33,34,35,36 Ethernet10/1 10 +Ethernet40 41,42,43,44 Ethernet11/1 11 +Ethernet44 45,46,47,48 Ethernet12/1 12 +Ethernet48 53,54,55,56 Ethernet13/1 13 +Ethernet52 49,50,51,52 Ethernet14/1 14 +Ethernet56 57,58,59,60 Ethernet15/1 15 +Ethernet60 61,62,63,64 Ethernet16/1 16 +Ethernet64 69,70,71,72 Ethernet17/1 17 +Ethernet68 65,66,67,68 Ethernet18/1 18 +Ethernet72 73,74,75,76 Ethernet19/1 19 +Ethernet76 77,78,79,80 Ethernet20/1 20 +Ethernet80 85,86,87,88 Ethernet21/1 21 +Ethernet84 81,82,83,84 Ethernet22/1 22 +Ethernet88 89,90,91,92 Ethernet23/1 23 +Ethernet92 93,94,95,96 Ethernet24/1 24 +Ethernet96 101,102,103,104 Ethernet25/1 25 +Ethernet100 97,98,99,100 Ethernet26/1 26 +Ethernet104 105,106,107,108 Ethernet27/1 27 +Ethernet108 109,110,111,112 Ethernet28/1 28 +Ethernet112 117,118,119,120 Ethernet29/1 29 +Ethernet116 113,114,115,116 Ethernet30/1 30 +Ethernet120 121,122,123,124 Ethernet31/1 31 +Ethernet124 125,126,127,128 Ethernet32/1 32 +Ethernet128 129 Ethernet33 33 +Ethernet132 128 Ethernet34 34 diff --git a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/sai.profile b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/sai.profile new file mode 100644 index 000000000000..d359ffc15cba --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-a7050cx3-32s-32x100G.config.bcm diff --git a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/td3-a7050cx3-32s-32x100G.config.bcm b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/td3-a7050cx3-32s-32x100G.config.bcm new file mode 100644 index 000000000000..217d15b4e579 --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/td3-a7050cx3-32s-32x100G.config.bcm @@ -0,0 +1,503 @@ +arl_clean_timeout_usec=15000000 +asf_mem_profile=2 +bcm_num_cos=8 +bcm_stat_flags=1 +bcm_stat_jumbo=9236 +bcm_tunnel_term_compatible_mode=1 +cdma_timeout_usec=15000000 +core_clock_frequency=1525 +dma_desc_timeout_usec=15000000 +dpp_clock_ratio=2:3 +fpem_mem_entries=0 +higig2_hdr_mode=1 +ifp_inports_support_enable=1 +ipv6_lpm_128b_enable=1 +l2_mem_entries=32768 +l2xmsg_mode=1 +l3_alpm_enable=2 +l3_max_ecmp_mode=1 +l3_mem_entries=16384 +max_vp_lags=0 +miim_intr_enable=0 +module_64ports=1 +multicast_l2_range=16383 +multicast_l3_range=0 +os=unix +oversubscribe_mode=1 +pbmp_xport_xe=0x4888888888888888c2222222222222222 +PHY_AN_ALLOW_PLL_CHANGE=1 +phy_an_c37_130=2 +phy_an_c37_66=2 +phy_an_c73=1 +port_flex_enable=1 +port_init_autoneg=0 +port_phy_addr=0xff +robust_hash_disable_egress_vlan=1 +robust_hash_disable_mpls=1 +robust_hash_disable_vlan=1 +sram_scan_enable=0 +stable_size=0x5500000 +tdma_timeout_usec=15000000 +tslam_timeout_usec=15000000 +phy_chain_rx_lane_map_physical{1.0}=0x1302 +phy_chain_rx_lane_map_physical{101.0}=0x0213 +phy_chain_rx_lane_map_physical{105.0}=0x2031 +phy_chain_rx_lane_map_physical{109.0}=0x0213 +phy_chain_rx_lane_map_physical{113.0}=0x2130 +phy_chain_rx_lane_map_physical{117.0}=0x0213 +phy_chain_rx_lane_map_physical{121.0}=0x2031 +phy_chain_rx_lane_map_physical{125.0}=0x0213 +phy_chain_rx_lane_map_physical{129.0}=0x3210 +phy_chain_rx_lane_map_physical{13.0}=0x3120 +phy_chain_rx_lane_map_physical{17.0}=0x1203 +phy_chain_rx_lane_map_physical{21.0}=0x3120 +phy_chain_rx_lane_map_physical{25.0}=0x3120 +phy_chain_rx_lane_map_physical{29.0}=0x3120 +phy_chain_rx_lane_map_physical{33.0}=0x1203 +phy_chain_rx_lane_map_physical{37.0}=0x3120 +phy_chain_rx_lane_map_physical{41.0}=0x3120 +phy_chain_rx_lane_map_physical{45.0}=0x3120 +phy_chain_rx_lane_map_physical{49.0}=0x1203 +phy_chain_rx_lane_map_physical{5.0}=0x3120 +phy_chain_rx_lane_map_physical{53.0}=0x3120 +phy_chain_rx_lane_map_physical{57.0}=0x3120 +phy_chain_rx_lane_map_physical{61.0}=0x3120 +phy_chain_rx_lane_map_physical{65.0}=0x2130 +phy_chain_rx_lane_map_physical{69.0}=0x0213 +phy_chain_rx_lane_map_physical{73.0}=0x2031 +phy_chain_rx_lane_map_physical{77.0}=0x0213 +phy_chain_rx_lane_map_physical{81.0}=0x2130 +phy_chain_rx_lane_map_physical{85.0}=0x0213 +phy_chain_rx_lane_map_physical{89.0}=0x2031 +phy_chain_rx_lane_map_physical{9.0}=0x3120 +phy_chain_rx_lane_map_physical{93.0}=0x0213 +phy_chain_rx_lane_map_physical{97.0}=0x2130 +phy_chain_rx_polarity_flip_physical{100.0}=0x1 +phy_chain_rx_polarity_flip_physical{10.0}=0x0 +phy_chain_rx_polarity_flip_physical{1.0}=0x0 +phy_chain_rx_polarity_flip_physical{101.0}=0x1 +phy_chain_rx_polarity_flip_physical{102.0}=0x0 +phy_chain_rx_polarity_flip_physical{103.0}=0x0 +phy_chain_rx_polarity_flip_physical{104.0}=0x1 +phy_chain_rx_polarity_flip_physical{105.0}=0x1 +phy_chain_rx_polarity_flip_physical{106.0}=0x1 +phy_chain_rx_polarity_flip_physical{107.0}=0x1 +phy_chain_rx_polarity_flip_physical{108.0}=0x0 +phy_chain_rx_polarity_flip_physical{109.0}=0x0 +phy_chain_rx_polarity_flip_physical{110.0}=0x0 +phy_chain_rx_polarity_flip_physical{11.0}=0x1 +phy_chain_rx_polarity_flip_physical{111.0}=0x1 +phy_chain_rx_polarity_flip_physical{112.0}=0x1 +phy_chain_rx_polarity_flip_physical{113.0}=0x1 +phy_chain_rx_polarity_flip_physical{114.0}=0x1 +phy_chain_rx_polarity_flip_physical{115.0}=0x0 +phy_chain_rx_polarity_flip_physical{116.0}=0x1 +phy_chain_rx_polarity_flip_physical{117.0}=0x0 +phy_chain_rx_polarity_flip_physical{118.0}=0x0 +phy_chain_rx_polarity_flip_physical{119.0}=0x1 +phy_chain_rx_polarity_flip_physical{120.0}=0x1 +phy_chain_rx_polarity_flip_physical{12.0}=0x1 +phy_chain_rx_polarity_flip_physical{121.0}=0x1 +phy_chain_rx_polarity_flip_physical{122.0}=0x1 +phy_chain_rx_polarity_flip_physical{123.0}=0x1 +phy_chain_rx_polarity_flip_physical{124.0}=0x0 +phy_chain_rx_polarity_flip_physical{125.0}=0x0 +phy_chain_rx_polarity_flip_physical{126.0}=0x0 +phy_chain_rx_polarity_flip_physical{127.0}=0x1 +phy_chain_rx_polarity_flip_physical{128.0}=0x1 +phy_chain_rx_polarity_flip_physical{129.0}=0x0 +phy_chain_rx_polarity_flip_physical{13.0}=0x1 +phy_chain_rx_polarity_flip_physical{131.0}=0x0 +phy_chain_rx_polarity_flip_physical{14.0}=0x1 +phy_chain_rx_polarity_flip_physical{15.0}=0x0 +phy_chain_rx_polarity_flip_physical{16.0}=0x0 +phy_chain_rx_polarity_flip_physical{17.0}=0x0 +phy_chain_rx_polarity_flip_physical{18.0}=0x0 +phy_chain_rx_polarity_flip_physical{19.0}=0x1 +phy_chain_rx_polarity_flip_physical{20.0}=0x0 +phy_chain_rx_polarity_flip_physical{2.0}=0x0 +phy_chain_rx_polarity_flip_physical{21.0}=0x1 +phy_chain_rx_polarity_flip_physical{22.0}=0x1 +phy_chain_rx_polarity_flip_physical{23.0}=0x0 +phy_chain_rx_polarity_flip_physical{24.0}=0x0 +phy_chain_rx_polarity_flip_physical{25.0}=0x0 +phy_chain_rx_polarity_flip_physical{26.0}=0x1 +phy_chain_rx_polarity_flip_physical{27.0}=0x1 +phy_chain_rx_polarity_flip_physical{28.0}=0x0 +phy_chain_rx_polarity_flip_physical{29.0}=0x1 +phy_chain_rx_polarity_flip_physical{30.0}=0x1 +phy_chain_rx_polarity_flip_physical{3.0}=0x0 +phy_chain_rx_polarity_flip_physical{31.0}=0x0 +phy_chain_rx_polarity_flip_physical{32.0}=0x0 +phy_chain_rx_polarity_flip_physical{33.0}=0x0 +phy_chain_rx_polarity_flip_physical{34.0}=0x0 +phy_chain_rx_polarity_flip_physical{35.0}=0x1 +phy_chain_rx_polarity_flip_physical{36.0}=0x0 +phy_chain_rx_polarity_flip_physical{37.0}=0x1 +phy_chain_rx_polarity_flip_physical{38.0}=0x1 +phy_chain_rx_polarity_flip_physical{39.0}=0x0 +phy_chain_rx_polarity_flip_physical{40.0}=0x0 +phy_chain_rx_polarity_flip_physical{4.0}=0x1 +phy_chain_rx_polarity_flip_physical{41.0}=0x0 +phy_chain_rx_polarity_flip_physical{42.0}=0x0 +phy_chain_rx_polarity_flip_physical{43.0}=0x1 +phy_chain_rx_polarity_flip_physical{44.0}=0x1 +phy_chain_rx_polarity_flip_physical{45.0}=0x1 +phy_chain_rx_polarity_flip_physical{46.0}=0x1 +phy_chain_rx_polarity_flip_physical{47.0}=0x0 +phy_chain_rx_polarity_flip_physical{48.0}=0x0 +phy_chain_rx_polarity_flip_physical{49.0}=0x0 +phy_chain_rx_polarity_flip_physical{50.0}=0x0 +phy_chain_rx_polarity_flip_physical{5.0}=0x0 +phy_chain_rx_polarity_flip_physical{51.0}=0x1 +phy_chain_rx_polarity_flip_physical{52.0}=0x0 +phy_chain_rx_polarity_flip_physical{53.0}=0x1 +phy_chain_rx_polarity_flip_physical{54.0}=0x1 +phy_chain_rx_polarity_flip_physical{55.0}=0x0 +phy_chain_rx_polarity_flip_physical{56.0}=0x0 +phy_chain_rx_polarity_flip_physical{57.0}=0x0 +phy_chain_rx_polarity_flip_physical{58.0}=0x0 +phy_chain_rx_polarity_flip_physical{59.0}=0x1 +phy_chain_rx_polarity_flip_physical{60.0}=0x1 +phy_chain_rx_polarity_flip_physical{6.0}=0x1 +phy_chain_rx_polarity_flip_physical{61.0}=0x1 +phy_chain_rx_polarity_flip_physical{62.0}=0x1 +phy_chain_rx_polarity_flip_physical{63.0}=0x0 +phy_chain_rx_polarity_flip_physical{64.0}=0x0 +phy_chain_rx_polarity_flip_physical{65.0}=0x1 +phy_chain_rx_polarity_flip_physical{66.0}=0x1 +phy_chain_rx_polarity_flip_physical{67.0}=0x0 +phy_chain_rx_polarity_flip_physical{68.0}=0x1 +phy_chain_rx_polarity_flip_physical{69.0}=0x0 +phy_chain_rx_polarity_flip_physical{70.0}=0x0 +phy_chain_rx_polarity_flip_physical{7.0}=0x0 +phy_chain_rx_polarity_flip_physical{71.0}=0x1 +phy_chain_rx_polarity_flip_physical{72.0}=0x1 +phy_chain_rx_polarity_flip_physical{73.0}=0x1 +phy_chain_rx_polarity_flip_physical{74.0}=0x1 +phy_chain_rx_polarity_flip_physical{75.0}=0x1 +phy_chain_rx_polarity_flip_physical{76.0}=0x0 +phy_chain_rx_polarity_flip_physical{77.0}=0x0 +phy_chain_rx_polarity_flip_physical{78.0}=0x0 +phy_chain_rx_polarity_flip_physical{79.0}=0x1 +phy_chain_rx_polarity_flip_physical{80.0}=0x1 +phy_chain_rx_polarity_flip_physical{8.0}=0x0 +phy_chain_rx_polarity_flip_physical{81.0}=0x1 +phy_chain_rx_polarity_flip_physical{82.0}=0x1 +phy_chain_rx_polarity_flip_physical{83.0}=0x0 +phy_chain_rx_polarity_flip_physical{84.0}=0x1 +phy_chain_rx_polarity_flip_physical{85.0}=0x0 +phy_chain_rx_polarity_flip_physical{86.0}=0x0 +phy_chain_rx_polarity_flip_physical{87.0}=0x1 +phy_chain_rx_polarity_flip_physical{88.0}=0x1 +phy_chain_rx_polarity_flip_physical{89.0}=0x1 +phy_chain_rx_polarity_flip_physical{90.0}=0x1 +phy_chain_rx_polarity_flip_physical{9.0}=0x0 +phy_chain_rx_polarity_flip_physical{91.0}=0x1 +phy_chain_rx_polarity_flip_physical{92.0}=0x0 +phy_chain_rx_polarity_flip_physical{93.0}=0x0 +phy_chain_rx_polarity_flip_physical{94.0}=0x0 +phy_chain_rx_polarity_flip_physical{95.0}=0x1 +phy_chain_rx_polarity_flip_physical{96.0}=0x1 +phy_chain_rx_polarity_flip_physical{97.0}=0x1 +phy_chain_rx_polarity_flip_physical{98.0}=0x1 +phy_chain_rx_polarity_flip_physical{99.0}=0x0 +phy_chain_tx_lane_map_physical{1.0}=0x3021 +phy_chain_tx_lane_map_physical{101.0}=0x3120 +phy_chain_tx_lane_map_physical{105.0}=0x1302 +phy_chain_tx_lane_map_physical{109.0}=0x2130 +phy_chain_tx_lane_map_physical{113.0}=0x1302 +phy_chain_tx_lane_map_physical{117.0}=0x3120 +phy_chain_tx_lane_map_physical{121.0}=0x1302 +phy_chain_tx_lane_map_physical{125.0}=0x3120 +phy_chain_tx_lane_map_physical{129.0}=0x3210 +phy_chain_tx_lane_map_physical{13.0}=0x0213 +phy_chain_tx_lane_map_physical{17.0}=0x2031 +phy_chain_tx_lane_map_physical{21.0}=0x0213 +phy_chain_tx_lane_map_physical{25.0}=0x2031 +phy_chain_tx_lane_map_physical{29.0}=0x1203 +phy_chain_tx_lane_map_physical{33.0}=0x2031 +phy_chain_tx_lane_map_physical{37.0}=0x0213 +phy_chain_tx_lane_map_physical{41.0}=0x2031 +phy_chain_tx_lane_map_physical{45.0}=0x1203 +phy_chain_tx_lane_map_physical{49.0}=0x2031 +phy_chain_tx_lane_map_physical{5.0}=0x1203 +phy_chain_tx_lane_map_physical{53.0}=0x0213 +phy_chain_tx_lane_map_physical{57.0}=0x2031 +phy_chain_tx_lane_map_physical{61.0}=0x1203 +phy_chain_tx_lane_map_physical{65.0}=0x1302 +phy_chain_tx_lane_map_physical{69.0}=0x1302 +phy_chain_tx_lane_map_physical{73.0}=0x1302 +phy_chain_tx_lane_map_physical{77.0}=0x2130 +phy_chain_tx_lane_map_physical{81.0}=0x1302 +phy_chain_tx_lane_map_physical{85.0}=0x3120 +phy_chain_tx_lane_map_physical{89.0}=0x1302 +phy_chain_tx_lane_map_physical{9.0}=0x0213 +phy_chain_tx_lane_map_physical{93.0}=0x2130 +phy_chain_tx_lane_map_physical{97.0}=0x1302 +phy_chain_tx_polarity_flip_physical{100.0}=0x1 +phy_chain_tx_polarity_flip_physical{10.0}=0x1 +phy_chain_tx_polarity_flip_physical{1.0}=0x1 +phy_chain_tx_polarity_flip_physical{101.0}=0x0 +phy_chain_tx_polarity_flip_physical{102.0}=0x1 +phy_chain_tx_polarity_flip_physical{103.0}=0x1 +phy_chain_tx_polarity_flip_physical{104.0}=0x0 +phy_chain_tx_polarity_flip_physical{105.0}=0x1 +phy_chain_tx_polarity_flip_physical{106.0}=0x0 +phy_chain_tx_polarity_flip_physical{107.0}=0x0 +phy_chain_tx_polarity_flip_physical{108.0}=0x0 +phy_chain_tx_polarity_flip_physical{109.0}=0x1 +phy_chain_tx_polarity_flip_physical{110.0}=0x1 +phy_chain_tx_polarity_flip_physical{11.0}=0x0 +phy_chain_tx_polarity_flip_physical{111.0}=0x0 +phy_chain_tx_polarity_flip_physical{112.0}=0x0 +phy_chain_tx_polarity_flip_physical{113.0}=0x0 +phy_chain_tx_polarity_flip_physical{114.0}=0x0 +phy_chain_tx_polarity_flip_physical{115.0}=0x0 +phy_chain_tx_polarity_flip_physical{116.0}=0x0 +phy_chain_tx_polarity_flip_physical{117.0}=0x1 +phy_chain_tx_polarity_flip_physical{118.0}=0x1 +phy_chain_tx_polarity_flip_physical{119.0}=0x0 +phy_chain_tx_polarity_flip_physical{120.0}=0x0 +phy_chain_tx_polarity_flip_physical{12.0}=0x0 +phy_chain_tx_polarity_flip_physical{121.0}=0x1 +phy_chain_tx_polarity_flip_physical{122.0}=0x0 +phy_chain_tx_polarity_flip_physical{123.0}=0x0 +phy_chain_tx_polarity_flip_physical{124.0}=0x0 +phy_chain_tx_polarity_flip_physical{125.0}=0x1 +phy_chain_tx_polarity_flip_physical{126.0}=0x1 +phy_chain_tx_polarity_flip_physical{127.0}=0x0 +phy_chain_tx_polarity_flip_physical{128.0}=0x0 +phy_chain_tx_polarity_flip_physical{129.0}=0x0 +phy_chain_tx_polarity_flip_physical{13.0}=0x1 +phy_chain_tx_polarity_flip_physical{131.0}=0x0 +phy_chain_tx_polarity_flip_physical{14.0}=0x1 +phy_chain_tx_polarity_flip_physical{15.0}=0x0 +phy_chain_tx_polarity_flip_physical{16.0}=0x1 +phy_chain_tx_polarity_flip_physical{17.0}=0x0 +phy_chain_tx_polarity_flip_physical{18.0}=0x0 +phy_chain_tx_polarity_flip_physical{19.0}=0x0 +phy_chain_tx_polarity_flip_physical{20.0}=0x0 +phy_chain_tx_polarity_flip_physical{2.0}=0x1 +phy_chain_tx_polarity_flip_physical{21.0}=0x1 +phy_chain_tx_polarity_flip_physical{22.0}=0x1 +phy_chain_tx_polarity_flip_physical{23.0}=0x0 +phy_chain_tx_polarity_flip_physical{24.0}=0x0 +phy_chain_tx_polarity_flip_physical{25.0}=0x0 +phy_chain_tx_polarity_flip_physical{26.0}=0x0 +phy_chain_tx_polarity_flip_physical{27.0}=0x1 +phy_chain_tx_polarity_flip_physical{28.0}=0x0 +phy_chain_tx_polarity_flip_physical{29.0}=0x0 +phy_chain_tx_polarity_flip_physical{30.0}=0x0 +phy_chain_tx_polarity_flip_physical{3.0}=0x0 +phy_chain_tx_polarity_flip_physical{31.0}=0x1 +phy_chain_tx_polarity_flip_physical{32.0}=0x1 +phy_chain_tx_polarity_flip_physical{33.0}=0x1 +phy_chain_tx_polarity_flip_physical{34.0}=0x1 +phy_chain_tx_polarity_flip_physical{35.0}=0x1 +phy_chain_tx_polarity_flip_physical{36.0}=0x1 +phy_chain_tx_polarity_flip_physical{37.0}=0x0 +phy_chain_tx_polarity_flip_physical{38.0}=0x0 +phy_chain_tx_polarity_flip_physical{39.0}=0x1 +phy_chain_tx_polarity_flip_physical{40.0}=0x1 +phy_chain_tx_polarity_flip_physical{4.0}=0x0 +phy_chain_tx_polarity_flip_physical{41.0}=0x0 +phy_chain_tx_polarity_flip_physical{42.0}=0x1 +phy_chain_tx_polarity_flip_physical{43.0}=0x1 +phy_chain_tx_polarity_flip_physical{44.0}=0x1 +phy_chain_tx_polarity_flip_physical{45.0}=0x0 +phy_chain_tx_polarity_flip_physical{46.0}=0x0 +phy_chain_tx_polarity_flip_physical{47.0}=0x1 +phy_chain_tx_polarity_flip_physical{48.0}=0x1 +phy_chain_tx_polarity_flip_physical{49.0}=0x1 +phy_chain_tx_polarity_flip_physical{50.0}=0x1 +phy_chain_tx_polarity_flip_physical{5.0}=0x1 +phy_chain_tx_polarity_flip_physical{51.0}=0x1 +phy_chain_tx_polarity_flip_physical{52.0}=0x1 +phy_chain_tx_polarity_flip_physical{53.0}=0x0 +phy_chain_tx_polarity_flip_physical{54.0}=0x0 +phy_chain_tx_polarity_flip_physical{55.0}=0x1 +phy_chain_tx_polarity_flip_physical{56.0}=0x1 +phy_chain_tx_polarity_flip_physical{57.0}=0x0 +phy_chain_tx_polarity_flip_physical{58.0}=0x1 +phy_chain_tx_polarity_flip_physical{59.0}=0x1 +phy_chain_tx_polarity_flip_physical{60.0}=0x1 +phy_chain_tx_polarity_flip_physical{6.0}=0x1 +phy_chain_tx_polarity_flip_physical{61.0}=0x0 +phy_chain_tx_polarity_flip_physical{62.0}=0x0 +phy_chain_tx_polarity_flip_physical{63.0}=0x1 +phy_chain_tx_polarity_flip_physical{64.0}=0x1 +phy_chain_tx_polarity_flip_physical{65.0}=0x1 +phy_chain_tx_polarity_flip_physical{66.0}=0x1 +phy_chain_tx_polarity_flip_physical{67.0}=0x1 +phy_chain_tx_polarity_flip_physical{68.0}=0x1 +phy_chain_tx_polarity_flip_physical{69.0}=0x0 +phy_chain_tx_polarity_flip_physical{70.0}=0x1 +phy_chain_tx_polarity_flip_physical{7.0}=0x0 +phy_chain_tx_polarity_flip_physical{71.0}=0x1 +phy_chain_tx_polarity_flip_physical{72.0}=0x1 +phy_chain_tx_polarity_flip_physical{73.0}=0x0 +phy_chain_tx_polarity_flip_physical{74.0}=0x1 +phy_chain_tx_polarity_flip_physical{75.0}=0x1 +phy_chain_tx_polarity_flip_physical{76.0}=0x1 +phy_chain_tx_polarity_flip_physical{77.0}=0x0 +phy_chain_tx_polarity_flip_physical{78.0}=0x0 +phy_chain_tx_polarity_flip_physical{79.0}=0x1 +phy_chain_tx_polarity_flip_physical{80.0}=0x1 +phy_chain_tx_polarity_flip_physical{8.0}=0x1 +phy_chain_tx_polarity_flip_physical{81.0}=0x1 +phy_chain_tx_polarity_flip_physical{82.0}=0x1 +phy_chain_tx_polarity_flip_physical{83.0}=0x1 +phy_chain_tx_polarity_flip_physical{84.0}=0x1 +phy_chain_tx_polarity_flip_physical{85.0}=0x0 +phy_chain_tx_polarity_flip_physical{86.0}=0x0 +phy_chain_tx_polarity_flip_physical{87.0}=0x1 +phy_chain_tx_polarity_flip_physical{88.0}=0x1 +phy_chain_tx_polarity_flip_physical{89.0}=0x0 +phy_chain_tx_polarity_flip_physical{90.0}=0x1 +phy_chain_tx_polarity_flip_physical{9.0}=0x1 +phy_chain_tx_polarity_flip_physical{91.0}=0x1 +phy_chain_tx_polarity_flip_physical{92.0}=0x1 +phy_chain_tx_polarity_flip_physical{93.0}=0x0 +phy_chain_tx_polarity_flip_physical{94.0}=0x0 +phy_chain_tx_polarity_flip_physical{95.0}=0x1 +phy_chain_tx_polarity_flip_physical{96.0}=0x1 +phy_chain_tx_polarity_flip_physical{97.0}=0x1 +phy_chain_tx_polarity_flip_physical{98.0}=0x1 +phy_chain_tx_polarity_flip_physical{99.0}=0x1 +portmap_103=101:100 +portmap_107=105:100 +portmap_1=1:100 +portmap_111=109:100 +portmap_115=113:100 +portmap_119=117:100 +portmap_123=121:100 +portmap_127=125:100 +portmap_130=128:10:m +portmap_13=13:100 +portmap_17=17:100 +portmap_21=21:100 +portmap_25=25:100 +portmap_29=29:100 +portmap_33=33:100 +portmap_37=37:100 +portmap_41=41:100 +portmap_45=45:100 +portmap_49=49:100 +portmap_53=53:100 +portmap_5=5:100 +portmap_57=57:100 +portmap_61=61:100 +portmap_66=129:10:m +portmap_67=65:100 +portmap_71=69:100 +portmap_75=73:100 +portmap_79=77:100 +portmap_83=81:100 +portmap_87=85:100 +portmap_91=89:100 +portmap_95=93:100 +portmap_9=9:100 +portmap_99=97:100 +serdes_core_rx_polarity_flip_physical{101}=0x9 +serdes_core_rx_polarity_flip_physical{105}=0x7 +serdes_core_rx_polarity_flip_physical{109}=0xc +serdes_core_rx_polarity_flip_physical{1}=0x8 +serdes_core_rx_polarity_flip_physical{113}=0xb +serdes_core_rx_polarity_flip_physical{117}=0xc +serdes_core_rx_polarity_flip_physical{121}=0x7 +serdes_core_rx_polarity_flip_physical{125}=0xc +serdes_core_rx_polarity_flip_physical{129}=0x0 +serdes_core_rx_polarity_flip_physical{13}=0x3 +serdes_core_rx_polarity_flip_physical{17}=0x4 +serdes_core_rx_polarity_flip_physical{21}=0x3 +serdes_core_rx_polarity_flip_physical{25}=0x6 +serdes_core_rx_polarity_flip_physical{29}=0x3 +serdes_core_rx_polarity_flip_physical{33}=0x4 +serdes_core_rx_polarity_flip_physical{37}=0x3 +serdes_core_rx_polarity_flip_physical{41}=0xc +serdes_core_rx_polarity_flip_physical{45}=0x3 +serdes_core_rx_polarity_flip_physical{49}=0x4 +serdes_core_rx_polarity_flip_physical{5}=0x2 +serdes_core_rx_polarity_flip_physical{53}=0x3 +serdes_core_rx_polarity_flip_physical{57}=0xc +serdes_core_rx_polarity_flip_physical{61}=0x3 +serdes_core_rx_polarity_flip_physical{65}=0xb +serdes_core_rx_polarity_flip_physical{69}=0xc +serdes_core_rx_polarity_flip_physical{73}=0x7 +serdes_core_rx_polarity_flip_physical{77}=0xc +serdes_core_rx_polarity_flip_physical{81}=0xb +serdes_core_rx_polarity_flip_physical{85}=0xc +serdes_core_rx_polarity_flip_physical{89}=0x7 +serdes_core_rx_polarity_flip_physical{9}=0xc +serdes_core_rx_polarity_flip_physical{93}=0xc +serdes_core_rx_polarity_flip_physical{97}=0xb +serdes_core_tx_polarity_flip_physical{101}=0x6 +serdes_core_tx_polarity_flip_physical{105}=0x1 +serdes_core_tx_polarity_flip_physical{109}=0x3 +serdes_core_tx_polarity_flip_physical{1}=0x3 +serdes_core_tx_polarity_flip_physical{113}=0x0 +serdes_core_tx_polarity_flip_physical{117}=0x3 +serdes_core_tx_polarity_flip_physical{121}=0x1 +serdes_core_tx_polarity_flip_physical{125}=0x3 +serdes_core_tx_polarity_flip_physical{129}=0x0 +serdes_core_tx_polarity_flip_physical{13}=0xb +serdes_core_tx_polarity_flip_physical{17}=0x0 +serdes_core_tx_polarity_flip_physical{21}=0x3 +serdes_core_tx_polarity_flip_physical{25}=0x4 +serdes_core_tx_polarity_flip_physical{29}=0xc +serdes_core_tx_polarity_flip_physical{33}=0xf +serdes_core_tx_polarity_flip_physical{37}=0xc +serdes_core_tx_polarity_flip_physical{41}=0xe +serdes_core_tx_polarity_flip_physical{45}=0xc +serdes_core_tx_polarity_flip_physical{49}=0xf +serdes_core_tx_polarity_flip_physical{5}=0xb +serdes_core_tx_polarity_flip_physical{53}=0xc +serdes_core_tx_polarity_flip_physical{57}=0xe +serdes_core_tx_polarity_flip_physical{61}=0xc +serdes_core_tx_polarity_flip_physical{65}=0xf +serdes_core_tx_polarity_flip_physical{69}=0xe +serdes_core_tx_polarity_flip_physical{73}=0xe +serdes_core_tx_polarity_flip_physical{77}=0xc +serdes_core_tx_polarity_flip_physical{81}=0xf +serdes_core_tx_polarity_flip_physical{85}=0xc +serdes_core_tx_polarity_flip_physical{89}=0xe +serdes_core_tx_polarity_flip_physical{9}=0x3 +serdes_core_tx_polarity_flip_physical{93}=0xc +serdes_core_tx_polarity_flip_physical{97}=0xf +serdes_preemphasis_1=0x14410a +serdes_preemphasis_5=0x14410a +serdes_preemphasis_9=0x14410a +serdes_preemphasis_13=0x14410a +serdes_preemphasis_17=0x14410a +serdes_preemphasis_21=0x14410a +serdes_preemphasis_25=0x14410a +serdes_preemphasis_29=0x14410a +serdes_preemphasis_33=0x14410a +serdes_preemphasis_37=0x14410a +serdes_preemphasis_41=0x14410a +serdes_preemphasis_45=0x14410a +serdes_preemphasis_49=0xf5005 +serdes_preemphasis_53=0xf5005 +serdes_preemphasis_57=0xf5005 +serdes_preemphasis_61=0xf5005 +serdes_driver_current_66=0xe +serdes_preemphasis_66=0x102804 +serdes_preemphasis_67=0xf5005 +serdes_preemphasis_71=0xf5005 +serdes_preemphasis_75=0xf5005 +serdes_preemphasis_79=0xf5005 +serdes_preemphasis_83=0x14410a +serdes_preemphasis_87=0x14410a +serdes_preemphasis_91=0x14410a +serdes_preemphasis_95=0x14410a +serdes_preemphasis_99=0x14410a +serdes_preemphasis_103=0x14410a +serdes_preemphasis_107=0x14410a +serdes_preemphasis_111=0x14410a +serdes_preemphasis_115=0x14410a +serdes_preemphasis_119=0x14410a +serdes_preemphasis_123=0x14410a +serdes_preemphasis_127=0x14410a +serdes_driver_current_130=0xe +serdes_preemphasis_130=0x102804 diff --git a/device/arista/x86_64-arista_7050cx3_32s/default_sku b/device/arista/x86_64-arista_7050cx3_32s/default_sku new file mode 100644 index 000000000000..bff7a549cb2c --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/default_sku @@ -0,0 +1 @@ +Arista-7050CX3-32S-C32 t1 diff --git a/device/arista/x86_64-arista_7050cx3_32s/fancontrol b/device/arista/x86_64-arista_7050cx3_32s/fancontrol new file mode 100644 index 000000000000..913075f73d12 --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/fancontrol @@ -0,0 +1,10 @@ +INTERVAL=5 +DEVPATH=hwmon4=devices/pci0000:00/0000:00:02.2/0000:02:00.0/i2c-11/11-004c hwmon3=devices/pci0000:00/0000:00:02.2/0000:02:00.0/i2c-2/2-0060 +DEVNAME=hwmon4=max6658 hwmon3=crow_cpld +FCTEMPS=hwmon3/pwm4=hwmon4/temp1_input hwmon3/pwm3=hwmon4/temp1_input hwmon3/pwm2=hwmon4/temp1_input hwmon3/pwm1=hwmon4/temp1_input +FCFANS=hwmon3/pwm4=hwmon3/fan4_input hwmon3/pwm3=hwmon3/fan3_input hwmon3/pwm2=hwmon3/fan2_input hwmon3/pwm1=hwmon3/fan1_input +MINTEMP=hwmon3/pwm4=40 hwmon3/pwm3=40 hwmon3/pwm2=40 hwmon3/pwm1=40 +MINPWM=hwmon3/pwm4=179 hwmon3/pwm3=179 hwmon3/pwm2=179 hwmon3/pwm1=179 +MAXTEMP=hwmon3/pwm4=50 hwmon3/pwm3=50 hwmon3/pwm2=50 hwmon3/pwm1=50 +MINSTART=hwmon3/pwm4=179 hwmon3/pwm3=179 hwmon3/pwm2=179 hwmon3/pwm1=179 +MINSTOP=hwmon3/pwm4=179 hwmon3/pwm3=179 hwmon3/pwm2=179 hwmon3/pwm1=179 diff --git a/device/arista/x86_64-arista_7050cx3_32s/platform_reboot b/device/arista/x86_64-arista_7050cx3_32s/platform_reboot new file mode 100644 index 000000000000..7f94a49e38b0 --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/platform_reboot @@ -0,0 +1 @@ +../x86_64-arista_common/platform_reboot \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050cx3_32s/plugins b/device/arista/x86_64-arista_7050cx3_32s/plugins new file mode 100644 index 000000000000..789a45fcace9 --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/plugins @@ -0,0 +1 @@ +../x86_64-arista_common/plugins \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050cx3_32s/sensors.conf b/device/arista/x86_64-arista_7050cx3_32s/sensors.conf new file mode 100644 index 000000000000..c63a526124d0 --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/sensors.conf @@ -0,0 +1,39 @@ +# libsensors configuration file for DCS-7050CX3-32S +# ------------------------------------------------ +# + +bus "i2c-2" "SCD 0000:02:00.0 SMBus master 0 bus 0" +bus "i2c-11" "SCD 0000:02:00.0 SMBus master 1 bus 1" +bus "i2c-13" "SCD 0000:02:00.0 SMBus master 1 bus 3" +bus "i2c-14" "SCD 0000:02:00.0 SMBus master 1 bus 4" + +chip "k10temp-pci-00c3" + label temp1 "Cpu temp sensor" + +chip "max6658-i2c-2-4c" + label temp1 "Cpu board temp sensor" + set temp1_max 75 + set temp1_crit 80 + + label temp2 "Back panel temp sensor" + set temp2_max 75 + set temp2_crit 85 + +chip "max6658-i2c-11-4c" + label temp1 "Board temp sensor" + set temp1_max 75 + set temp1_crit 85 + + label temp2 "Front panel temp sensor" + set temp2_max 60 + set temp2_crit 65 + +chip "pmbus-i2c-13-58" + label temp1 "Power supply 1 hotspot sensor" + label temp2 "Power supply 1 inlet temp sensor" + label temp3 "Power supply 1 sensor" + +chip "pmbus-i2c-14-58" + label temp1 "Power supply 2 hotspot sensor" + label temp2 "Power supply 2 inlet temp sensor" + label temp3 "Power supply 2 sensor" diff --git a/files/Aboot/boot0.j2 b/files/Aboot/boot0.j2 index 88931b3dac39..9ac100cc4248 100644 --- a/files/Aboot/boot0.j2 +++ b/files/Aboot/boot0.j2 @@ -272,6 +272,11 @@ platform_specific() { aboot_machine=arista_7280cr3_32d4 flash_size=7382 fi + if [ "$sid" = "Lodoga" ] || [ "$sid" = "LodogaSsd" ]; then + aboot_machine=arista_7050cx3_32s + flash_size=3700 + echo "amd_iommu=off" >> /tmp/append + fi if [ "$platform" = "rook" ] || [ "$platform" = "magpie" ] || [ "$platform" = "woodpecker" ]; then echo "tsc=reliable pcie_ports=native" >>/tmp/append diff --git a/platform/barefoot/sonic-platform-modules-arista b/platform/barefoot/sonic-platform-modules-arista index 10750325b6cf..e9cabadb4272 160000 --- a/platform/barefoot/sonic-platform-modules-arista +++ b/platform/barefoot/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit 10750325b6cfc7a1dc1a8b0734008bde1bb3ac06 +Subproject commit e9cabadb42725d3c86eb93c3d766cfb5d58e6d29 diff --git a/platform/broadcom/sonic-platform-modules-arista b/platform/broadcom/sonic-platform-modules-arista index 390d5e22f9c6..e9cabadb4272 160000 --- a/platform/broadcom/sonic-platform-modules-arista +++ b/platform/broadcom/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit 390d5e22f9c6c1a007ed325f6b0bd050a79aa5b1 +Subproject commit e9cabadb42725d3c86eb93c3d766cfb5d58e6d29 From a6533a593f3f173b70da8ad05aea4392fb5c7c3e Mon Sep 17 00:00:00 2001 From: rlhui Date: Sat, 14 Mar 2020 13:32:44 -0700 Subject: [PATCH 099/178] fix build error in sonic-mgmt-framework --- src/sonic-mgmt-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-mgmt-framework b/src/sonic-mgmt-framework index 00410e5516ec..a4f1650d505c 160000 --- a/src/sonic-mgmt-framework +++ b/src/sonic-mgmt-framework @@ -1 +1 @@ -Subproject commit 00410e5516ec4dce957c6bb1fdd0258ef47bfafa +Subproject commit a4f1650d505c14d94872bd216f218e7c752de05c From 774487badc02baf36657be702a9f62ee9e3fc64b Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Thu, 12 Mar 2020 04:44:18 +0800 Subject: [PATCH 100/178] [Mellanox] Calculate the buffer size based on the latest excel and with gearbox considered (#4239) --- .../ACS-MSN3800/buffers_defaults_t0.j2 | 105 +++++++++++++++++- .../ACS-MSN3800/buffers_defaults_t1.j2 | 105 +++++++++++++++++- .../ACS-MSN3800/pg_profile_lookup.ini | 24 +++- .../buffers_defaults_t0.j2 | 2 +- .../buffers_defaults_t1.j2 | 2 +- .../pg_profile_lookup.ini | 2 +- 6 files changed, 234 insertions(+), 6 deletions(-) mode change 120000 => 100644 device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_defaults_t0.j2 mode change 120000 => 100644 device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_defaults_t1.j2 mode change 120000 => 100644 device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/pg_profile_lookup.ini diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_defaults_t0.j2 deleted file mode 120000 index 85f0b6b6b354..000000000000 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_defaults_t0.j2 +++ /dev/null @@ -1 +0,0 @@ -../../x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t0.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..d69a0cc13835 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_defaults_t0.j2 @@ -0,0 +1,104 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '28196784' %} +{% set ingress_lossy_pool_size = '28196784' %} +{% set egress_lossless_pool_size = '34340832' %} +{% set egress_lossy_pool_size = '28196784' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0, 32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "ingress_lossy_pool": { + "size": "{{ ingress_lossy_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"0" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_profile_lists(port_names) %} + "BUFFER_PORT_INGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile],[BUFFER_PROFILE|ingress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + }, + "BUFFER_PORT_EGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { +{% for port in port_names.split(',') %} + "{{ port }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|0-2": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|5-6": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_defaults_t1.j2 deleted file mode 120000 index 3bb496a5103b..000000000000 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_defaults_t1.j2 +++ /dev/null @@ -1 +0,0 @@ -../../x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t1.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..78d43455a424 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/buffers_defaults_t1.j2 @@ -0,0 +1,104 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '17891280' %} +{% set ingress_lossy_pool_size = '17891280' %} +{% set egress_lossless_pool_size = '34340832' %} +{% set egress_lossy_pool_size = '17891280' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0, 32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "ingress_lossy_pool": { + "size": "{{ ingress_lossy_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"0" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_profile_lists(port_names) %} + "BUFFER_PORT_INGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile],[BUFFER_PROFILE|ingress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + }, + "BUFFER_PORT_EGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { +{% for port in port_names.split(',') %} + "{{ port }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|0-2": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|5-6": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/pg_profile_lookup.ini deleted file mode 120000 index 252ae8d4149b..000000000000 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/pg_profile_lookup.ini +++ /dev/null @@ -1 +0,0 @@ -../../x86_64-mlnx_msn3700-r0/ACS-MSN3700/pg_profile_lookup.ini \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/pg_profile_lookup.ini new file mode 100644 index 000000000000..7c28e4c0d500 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/ACS-MSN3800/pg_profile_lookup.ini @@ -0,0 +1,23 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold + 1000 5m 32768 18432 14336 0 + 10000 5m 34816 18432 16384 0 + 25000 5m 38912 18432 20480 0 + 40000 5m 41984 18432 23552 0 + 50000 5m 44032 18432 25600 0 + 100000 5m 55296 18432 36864 0 + 200000 5m 77824 18432 59392 0 + 1000 40m 33792 18432 15360 0 + 10000 40m 36864 18432 18432 0 + 25000 40m 43008 18432 24576 0 + 40000 40m 49152 18432 30720 0 + 50000 40m 53248 18432 34816 0 + 100000 40m 72704 18432 54272 0 + 200000 40m 112640 18432 94208 0 + 1000 300m 34816 18432 16384 0 + 10000 300m 50176 18432 31744 0 + 25000 300m 75776 18432 57344 0 + 40000 300m 101376 18432 82944 0 + 50000 300m 117760 18432 99328 0 + 100000 300m 202752 18432 184320 0 + 200000 300m 373760 18432 355328 0 diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t0.j2 index 85f0b6b6b354..0987f6724863 120000 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t0.j2 +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t0.j2 @@ -1 +1 @@ -../../x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t0.j2 \ No newline at end of file +../ACS-MSN3800/buffers_defaults_t0.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t1.j2 index 3bb496a5103b..119460bfa556 120000 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t1.j2 +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/buffers_defaults_t1.j2 @@ -1 +1 @@ -../../x86_64-mlnx_msn3700-r0/ACS-MSN3700/buffers_defaults_t1.j2 \ No newline at end of file +../ACS-MSN3800/buffers_defaults_t1.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/pg_profile_lookup.ini index 252ae8d4149b..db2f74508aad 120000 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/pg_profile_lookup.ini +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/pg_profile_lookup.ini @@ -1 +1 @@ -../../x86_64-mlnx_msn3700-r0/ACS-MSN3700/pg_profile_lookup.ini \ No newline at end of file +../ACS-MSN3800/pg_profile_lookup.ini \ No newline at end of file From c7001271017dab15cac02e0560270f39c9f41be0 Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Tue, 10 Mar 2020 03:36:56 +0800 Subject: [PATCH 101/178] [Mellanox]Take advantage of sdk variable to customize the location where sdk_socket exists. (#4223) Take advantage of an SDK environment variable to customize the location where sdk_socket exists. In the latest SDK sdk_socket has been moved from /tmp to /var/run which is a better place to contain this kind of file. However, this prevents the subdirs under /var/run from being mapped to different volumes. To resolve this, we take advantage of an SDK variable to designate the location of sdk_socket. This requires every process that requires to access sdk_socket have this environment variable defined. However, to define environment variable for each process is less scalable. We take advantage of the docker scope environment variable to avoid that. It depends on PR 4227 --- files/build_templates/docker_image_ctl.j2 | 8 ++++++-- platform/mellanox/docker-syncd-mlnx-rpc/Dockerfile.j2 | 2 ++ platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 | 2 ++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 2777a26c8edf..9357ae58d4a1 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -231,11 +231,15 @@ start() { {%- if sonic_asic_platform == "mellanox" %} {%- if docker_container_name == "syncd" %} -v /var/log/mellanox/sniffer:/var/log/mellanox/sniffer:rw \ - -v mlnx_sdk_socket:/tmp \ + -v mlnx_sdk_socket:/var/run/sx_sdk \ + -v mlnx_sdk_ready:/tmp \ -v /dev/shm:/dev/shm:rw \ + -e SX_API_SOCKET_FILE=/var/run/sx_sdk/sx_api.sock \ {%- elif docker_container_name == "pmon" %} -v /var/run/hw-management:/var/run/hw-management:rw \ - -v mlnx_sdk_socket:/tmp \ + -v mlnx_sdk_socket:/var/run/sx_sdk \ + -v mlnx_sdk_ready:/tmp \ + -e SX_API_SOCKET_FILE=/var/run/sx_sdk/sx_api.sock \ -v /dev/shm:/dev/shm:rw \ {%- else %} --tmpfs /tmp \ diff --git a/platform/mellanox/docker-syncd-mlnx-rpc/Dockerfile.j2 b/platform/mellanox/docker-syncd-mlnx-rpc/Dockerfile.j2 index d9b86e782531..3f6225c96bd3 100644 --- a/platform/mellanox/docker-syncd-mlnx-rpc/Dockerfile.j2 +++ b/platform/mellanox/docker-syncd-mlnx-rpc/Dockerfile.j2 @@ -4,6 +4,8 @@ FROM docker-syncd-mlnx ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive +RUN mkdir -p /var/run/sx_sdk + RUN apt-get purge -y syncd {% if docker_syncd_mlnx_rpc_debs.strip() -%} diff --git a/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 b/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 index 4d22335ec783..6953933735fa 100755 --- a/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 +++ b/platform/mellanox/docker-syncd-mlnx/Dockerfile.j2 @@ -4,6 +4,8 @@ FROM docker-config-engine-stretch ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf +RUN mkdir -p /var/run/sx_sdk + ## Make apt-get non-interactive ENV DEBIAN_FRONTEND=noninteractive From 102cb8309715ad6dd1779eec977196d649411749 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Thu, 5 Mar 2020 15:27:21 -0800 Subject: [PATCH 102/178] [Services] Restart NAT service upon unexpected critical process exit. (#4208) --- dockers/docker-nat/Dockerfile.j2 | 2 ++ dockers/docker-nat/critical_processes | 2 ++ dockers/docker-nat/supervisord.conf | 8 +++++++- files/build_templates/nat.service.j2 | 4 ++++ rules/docker-nat.mk | 3 ++- 5 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 dockers/docker-nat/critical_processes diff --git a/dockers/docker-nat/Dockerfile.j2 b/dockers/docker-nat/Dockerfile.j2 index 3cfbd99e95e1..a74147cc26fd 100644 --- a/dockers/docker-nat/Dockerfile.j2 +++ b/dockers/docker-nat/Dockerfile.j2 @@ -38,6 +38,8 @@ RUN apt-get update \ COPY ["start.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] COPY ["restore_nat_entries.py", "/usr/bin/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor"] RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y RUN rm -rf /debs diff --git a/dockers/docker-nat/critical_processes b/dockers/docker-nat/critical_processes new file mode 100644 index 000000000000..d442976143f1 --- /dev/null +++ b/dockers/docker-nat/critical_processes @@ -0,0 +1,2 @@ +natmgrd +natsyncd diff --git a/dockers/docker-nat/supervisord.conf b/dockers/docker-nat/supervisord.conf index bb42d23fe355..839d6f59ab3c 100644 --- a/dockers/docker-nat/supervisord.conf +++ b/dockers/docker-nat/supervisord.conf @@ -3,6 +3,12 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener --container-name nat +events=PROCESS_STATE_EXITED +autostart=true +autorestart=unexpected + [program:start.sh] command=/usr/bin/start.sh priority=1 @@ -15,7 +21,7 @@ stderr_logfile=syslog command=/usr/sbin/rsyslogd -n priority=2 autostart=false -autorestart=false +autorestart=unexpected stdout_logfile=syslog stderr_logfile=syslog diff --git a/files/build_templates/nat.service.j2 b/files/build_templates/nat.service.j2 index 2e3e17439ef7..79a56f67ca89 100644 --- a/files/build_templates/nat.service.j2 +++ b/files/build_templates/nat.service.j2 @@ -3,12 +3,16 @@ Description=NAT container Requires=updategraph.service swss.service After=updategraph.service swss.service syncd.service Before=ntp-config.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 [Service] User={{ sonicadmin_user }} ExecStartPre=/usr/bin/{{docker_container_name}}.sh start ExecStart=/usr/bin/{{docker_container_name}}.sh wait ExecStop=/usr/bin/{{docker_container_name}}.sh stop +Restart=always +RestartSec=30 [Install] WantedBy=multi-user.target swss.service diff --git a/rules/docker-nat.mk b/rules/docker-nat.mk index dcccc24ba2ff..eb6bd16ccd46 100644 --- a/rules/docker-nat.mk +++ b/rules/docker-nat.mk @@ -30,5 +30,6 @@ $(DOCKER_NAT)_RUN_OPT += --privileged -t $(DOCKER_NAT)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro $(DOCKER_NAT)_RUN_OPT += -v /host/warmboot:/var/warmboot -$(DOCKER_NAT)_BASE_IMAGE_FILES += natctl:/usr/bin/natctl +$(DOCKER_NAT)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) +$(DOCKER_NAT)_BASE_IMAGE_FILES += natctl:/usr/bin/natctl From bcfc3d17458500ba7fc7ffa6f4e6c341b00397f0 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Wed, 4 Mar 2020 19:15:12 -0800 Subject: [PATCH 103/178] [Mellanox]the port index in port_config.ini should starts from 0 (#4152) --- .../Mellanox-SN2700-C28D8/port_config.ini | 74 ++++++------ .../Mellanox-SN2700-D48C8/port_config.ini | 114 +++++++++--------- 2 files changed, 94 insertions(+), 94 deletions(-) diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/port_config.ini b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/port_config.ini index 345e6a206731..8bc48269d163 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/port_config.ini +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/port_config.ini @@ -1,37 +1,37 @@ -# name lanes speed alias index -Ethernet0 0,1,2,3 100000 etp1 1 -Ethernet4 4,5,6,7 100000 etp2 2 -Ethernet8 8,9,10,11 100000 etp3 3 -Ethernet12 12,13,14,15 100000 etp4 4 -Ethernet16 16,17,18,19 100000 etp5 5 -Ethernet20 20,21,22,23 100000 etp6 6 -Ethernet24 24,25,26,27 100000 etp7 7 -Ethernet28 28,29,30,31 100000 etp8 8 -Ethernet32 32,33,34,35 100000 etp9 9 -Ethernet36 36,37,38,39 100000 etp10 10 -Ethernet40 40,41,42,43 100000 etp11 11 -Ethernet44 44,45,46,47 100000 etp12 12 -Ethernet48 48,49,50,51 100000 etp13 13 -Ethernet52 52,53,54,55 100000 etp14 14 -Ethernet56 56,57,58,59 100000 etp15 15 -Ethernet60 60,61,62,63 100000 etp16 16 -Ethernet64 64,65,66,67 100000 etp17 17 -Ethernet68 68,69,70,71 100000 etp18 18 -Ethernet72 72,73,74,75 100000 etp19 19 -Ethernet76 76,77,78,79 100000 etp20 20 -Ethernet80 80,81,82,83 100000 etp21 21 -Ethernet84 84,85,86,87 100000 etp22 22 -Ethernet88 88,89,90,91 100000 etp23 23 -Ethernet92 92,93,94,95 100000 etp24 24 -Ethernet96 96,97,98,99 100000 etp25 25 -Ethernet100 100,101,102,103 100000 etp26 26 -Ethernet104 104,105,106,107 100000 etp27 27 -Ethernet108 108,109,110,111 100000 etp28 28 -Ethernet112 112,113 50000 etp29a 29 -Ethernet114 114,115 50000 etp29b 29 -Ethernet116 116,117 50000 etp30a 30 -Ethernet118 118,119 50000 etp30b 30 -Ethernet120 120,121 50000 etp31a 31 -Ethernet122 122,123 50000 etp31b 31 -Ethernet124 124,125 50000 etp32a 32 -Ethernet126 126,127 50000 etp32b 32 \ No newline at end of file +# name lanes alias index speed +Ethernet0 0,1,2,3 etp1 0 100000 +Ethernet4 4,5,6,7 etp2 1 100000 +Ethernet8 8,9,10,11 etp3 2 100000 +Ethernet12 12,13,14,15 etp4 3 100000 +Ethernet16 16,17,18,19 etp5 4 100000 +Ethernet20 20,21,22,23 etp6 5 100000 +Ethernet24 24,25,26,27 etp7 6 100000 +Ethernet28 28,29,30,31 etp8 7 100000 +Ethernet32 32,33,34,35 etp9 8 100000 +Ethernet36 36,37,38,39 etp10 9 100000 +Ethernet40 40,41,42,43 etp11 10 100000 +Ethernet44 44,45,46,47 etp12 11 100000 +Ethernet48 48,49,50,51 etp13 12 100000 +Ethernet52 52,53,54,55 etp14 13 100000 +Ethernet56 56,57,58,59 etp15 14 100000 +Ethernet60 60,61,62,63 etp16 15 100000 +Ethernet64 64,65,66,67 etp17 16 100000 +Ethernet68 68,69,70,71 etp18 17 100000 +Ethernet72 72,73,74,75 etp19 18 100000 +Ethernet76 76,77,78,79 etp20 19 100000 +Ethernet80 80,81,82,83 etp21 20 100000 +Ethernet84 84,85,86,87 etp22 21 100000 +Ethernet88 88,89,90,91 etp23 22 100000 +Ethernet92 92,93,94,95 etp24 23 100000 +Ethernet96 96,97,98,99 etp25 24 100000 +Ethernet100 100,101,102,103 etp26 25 100000 +Ethernet104 104,105,106,107 etp27 26 100000 +Ethernet108 108,109,110,111 etp28 27 100000 +Ethernet112 112,113 etp29a 28 50000 +Ethernet114 114,115 etp29b 28 50000 +Ethernet116 116,117 etp30a 29 50000 +Ethernet118 118,119 etp30b 29 50000 +Ethernet120 120,121 etp31a 30 50000 +Ethernet122 122,123 etp31b 30 50000 +Ethernet124 124,125 etp32a 31 50000 +Ethernet126 126,127 etp32b 31 50000 diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/port_config.ini b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/port_config.ini index 9e01da79f449..f9f465f1a3ea 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/port_config.ini +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/port_config.ini @@ -1,57 +1,57 @@ -# name lanes speed alias index -Ethernet0 0,1 50000 etp1a 1 -Ethernet2 2,3 50000 etp1b 1 -Ethernet4 4,5 50000 etp2a 2 -Ethernet6 6,7 50000 etp2b 2 -Ethernet8 8,9 50000 etp3a 3 -Ethernet10 10,11 50000 etp3b 3 -Ethernet12 12,13 50000 etp4a 4 -Ethernet14 14,15 50000 etp4b 4 -Ethernet16 16,17 50000 etp5a 5 -Ethernet18 18,19 50000 etp5b 5 -Ethernet20 20,21 50000 etp6a 6 -Ethernet22 22,23 50000 etp6b 6 -Ethernet24 24,25,26,27 100000 etp7 7 -Ethernet28 28,29,30,31 100000 etp8 8 -Ethernet32 32,33,34,35 100000 etp9 9 -Ethernet36 36,37,38,39 100000 etp10 10 -Ethernet40 40,41 50000 etp11a 11 -Ethernet42 42,43 50000 etp11b 11 -Ethernet44 44,45 50000 etp12a 12 -Ethernet46 46,47 50000 etp12b 12 -Ethernet48 48,49 50000 etp13a 13 -Ethernet50 50,51 50000 etp13b 13 -Ethernet52 52,53 50000 etp14a 14 -Ethernet54 54,55 50000 etp14b 14 -Ethernet56 56,57 50000 etp15a 15 -Ethernet58 58,59 50000 etp15b 15 -Ethernet60 60,61 50000 etp16a 16 -Ethernet62 62,63 50000 etp16b 16 -Ethernet64 64,65 50000 etp17a 17 -Ethernet66 66,67 50000 etp17b 17 -Ethernet68 68,69 50000 etp18a 18 -Ethernet70 70,71 50000 etp18b 18 -Ethernet72 72,73 50000 etp19a 19 -Ethernet74 74,75 50000 etp19b 19 -Ethernet76 76,77 50000 etp20a 20 -Ethernet78 78,79 50000 etp20b 20 -Ethernet80 80,81 50000 etp21a 21 -Ethernet82 82,83 50000 etp21b 21 -Ethernet84 84,85 50000 etp22a 22 -Ethernet86 86,87 50000 etp22b 22 -Ethernet88 88,89,90,91 100000 etp23 23 -Ethernet92 92,93,94,95 100000 etp24 24 -Ethernet96 96,97,98,99 100000 etp25 25 -Ethernet100 100,101,102,103 100000 etp26 26 -Ethernet104 104,105 50000 etp27a 27 -Ethernet106 106,107 50000 etp27b 27 -Ethernet108 108,109 50000 etp28a 28 -Ethernet110 110,111 50000 etp28b 28 -Ethernet112 112,113 50000 etp29a 29 -Ethernet114 114,115 50000 etp29b 29 -Ethernet116 116,117 50000 etp30a 30 -Ethernet118 118,119 50000 etp30b 30 -Ethernet120 120,121 50000 etp31a 31 -Ethernet122 122,123 50000 etp31b 31 -Ethernet124 124,125 50000 etp32a 32 -Ethernet126 126,127 50000 etp32b 32 +# name lanes alias index speed +Ethernet0 0,1 etp1a 0 50000 +Ethernet2 2,3 etp1b 0 50000 +Ethernet4 4,5 etp2a 1 50000 +Ethernet6 6,7 etp2b 1 50000 +Ethernet8 8,9 etp3a 2 50000 +Ethernet10 10,11 etp3b 2 50000 +Ethernet12 12,13 etp4a 3 50000 +Ethernet14 14,15 etp4b 3 50000 +Ethernet16 16,17 etp5a 4 50000 +Ethernet18 18,19 etp5b 4 50000 +Ethernet20 20,21 etp6a 5 50000 +Ethernet22 22,23 etp6b 5 50000 +Ethernet24 24,25,26,27 etp7 6 100000 +Ethernet28 28,29,30,31 etp8 7 100000 +Ethernet32 32,33,34,35 etp9 8 100000 +Ethernet36 36,37,38,39 etp10 9 100000 +Ethernet40 40,41 etp11a 10 50000 +Ethernet42 42,43 etp11b 10 50000 +Ethernet44 44,45 etp12a 11 50000 +Ethernet46 46,47 etp12b 11 50000 +Ethernet48 48,49 etp13a 12 50000 +Ethernet50 50,51 etp13b 12 50000 +Ethernet52 52,53 etp14a 13 50000 +Ethernet54 54,55 etp14b 13 50000 +Ethernet56 56,57 etp15a 14 50000 +Ethernet58 58,59 etp15b 14 50000 +Ethernet60 60,61 etp16a 15 50000 +Ethernet62 62,63 etp16b 15 50000 +Ethernet64 64,65 etp17a 16 50000 +Ethernet66 66,67 etp17b 16 50000 +Ethernet68 68,69 etp18a 17 50000 +Ethernet70 70,71 etp18b 17 50000 +Ethernet72 72,73 etp19a 18 50000 +Ethernet74 74,75 etp19b 18 50000 +Ethernet76 76,77 etp20a 19 50000 +Ethernet78 78,79 etp20b 19 50000 +Ethernet80 80,81 etp21a 20 50000 +Ethernet82 82,83 etp21b 20 50000 +Ethernet84 84,85 etp22a 21 50000 +Ethernet86 86,87 etp22b 21 50000 +Ethernet88 88,89,90,91 etp23 22 100000 +Ethernet92 92,93,94,95 etp24 23 100000 +Ethernet96 96,97,98,99 etp25 24 100000 +Ethernet100 100,101,102,103 etp26 25 100000 +Ethernet104 104,105 etp27a 26 50000 +Ethernet106 106,107 etp27b 26 50000 +Ethernet108 108,109 etp28a 27 50000 +Ethernet110 110,111 etp28b 27 50000 +Ethernet112 112,113 etp29a 28 50000 +Ethernet114 114,115 etp29b 28 50000 +Ethernet116 116,117 etp30a 29 50000 +Ethernet118 118,119 etp30b 29 50000 +Ethernet120 120,121 etp31a 30 50000 +Ethernet122 122,123 etp31b 30 50000 +Ethernet124 124,125 etp32a 31 50000 +Ethernet126 126,127 etp32b 31 50000 From 53eb0bc59b57164a6177d3c4dda7138d91417c28 Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> Date: Mon, 9 Mar 2020 23:58:49 +0800 Subject: [PATCH 104/178] [Mellanox] Add sdk 4.4.0542 (#4227) * [Mellanox] Add sdk 4.4.0542 * fix typo --- platform/mellanox/fw.mk | 20 +++++++++++++++---- platform/mellanox/mlnx-fw-upgrade.j2 | 7 +++++++ platform/mellanox/mlnx-sai.mk | 2 +- platform/mellanox/mlnx-sai/SAI-Implementation | 2 +- platform/mellanox/one-image.mk | 2 +- .../sdk-src/sx-kernel/Switch-SDK-drivers | 2 +- platform/mellanox/sdk.mk | 2 +- 7 files changed, 28 insertions(+), 9 deletions(-) diff --git a/platform/mellanox/fw.mk b/platform/mellanox/fw.mk index 97ff9d93d486..dc8243be1e83 100644 --- a/platform/mellanox/fw.mk +++ b/platform/mellanox/fw.mk @@ -11,20 +11,27 @@ else FW_FROM_URL = n endif -MLNX_SPC_FW_VERSION = 13.2000.3298 +MLNX_SPC_FW_VERSION = 13.2007.0322 MLNX_SPC_FW_FILE = fw-SPC-rel-$(subst .,_,$(MLNX_SPC_FW_VERSION))-EVB.mfa $(MLNX_SPC_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC_FW_FILE) -MLNX_SPC2_FW_VERSION = 29.2000.3298 +MLNX_SPC2_FW_VERSION = 29.2007.0322 MLNX_SPC2_FW_FILE = fw-SPC2-rel-$(subst .,_,$(MLNX_SPC2_FW_VERSION))-EVB.mfa $(MLNX_SPC2_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC2_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC2_FW_FILE) +MLNX_SPC3_FW_VERSION = 30.2007.0322 +MLNX_SPC3_FW_FILE = fw-SPC3-rel-$(subst .,_,$(MLNX_SPC3_FW_VERSION))-EVB.mfa +$(MLNX_SPC3_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) +$(MLNX_SPC3_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC3_FW_FILE) + +MLNX_FW_FILES = $(MLNX_SPC_FW_FILE) $(MLNX_SPC2_FW_FILE) $(MLNX_SPC3_FW_FILE) + ifeq ($(FW_FROM_URL),n) -SONIC_COPY_FILES += $(MLNX_SPC_FW_FILE) $(MLNX_SPC2_FW_FILE) +SONIC_COPY_FILES += $(MLNX_FW_FILES) else -SONIC_ONLINE_FILES += $(MLNX_SPC_FW_FILE) $(MLNX_SPC2_FW_FILE) +SONIC_ONLINE_FILES += $(MLNX_FW_FILES) endif export MLNX_SPC_FW_VERSION @@ -32,3 +39,8 @@ export MLNX_SPC_FW_FILE export MLNX_SPC2_FW_VERSION export MLNX_SPC2_FW_FILE + +export MLNX_SPC3_FW_VERSION +export MLNX_SPC3_FW_FILE + +export MLNX_FW_FILES diff --git a/platform/mellanox/mlnx-fw-upgrade.j2 b/platform/mellanox/mlnx-fw-upgrade.j2 index 3857244a1504..d0f69c35e0bc 100755 --- a/platform/mellanox/mlnx-fw-upgrade.j2 +++ b/platform/mellanox/mlnx-fw-upgrade.j2 @@ -25,15 +25,18 @@ declare -r QUERY_FILE="/tmp/mlxfwmanager-query.log" declare -r SPC1_ASIC="spc1" declare -r SPC2_ASIC="spc2" +declare -r SPC3_ASIC="spc3" declare -r UNKN_ASIC="unknown" declare -rA FW_FILE_MAP=( \ [$SPC1_ASIC]="/etc/mlnx/fw-SPC.mfa" \ [$SPC2_ASIC]="/etc/mlnx/fw-SPC2.mfa" \ + [$SPC3_ASIC]="/etc/mlnx/fw-SPC3.mfa" \ ) declare -rA FW_REQUIRED_MAP=( \ [$SPC1_ASIC]="{{ MLNX_SPC_FW_VERSION }}" \ [$SPC2_ASIC]="{{ MLNX_SPC2_FW_VERSION }}" \ + [$SPC3_ASIC]="{{ MLNX_SPC3_FW_VERSION }}" \ ) IMAGE_UPGRADE="${NO_PARAM}" @@ -135,6 +138,7 @@ function GetAsicType() { local -r SPC1_PRODUCT_ID="cb84" local -r SPC2_PRODUCT_ID="cf6c" + local -r SPC3_PRODUCT_ID="cf70" if lspci -n | grep "${VENDOR_ID}:${SPC1_PRODUCT_ID}" &>/dev/null; then echo "${SPC1_ASIC}" @@ -142,6 +146,9 @@ function GetAsicType() { elif lspci -n | grep "${VENDOR_ID}:${SPC2_PRODUCT_ID}" &>/dev/null; then echo "${SPC2_ASIC}" exit "${EXIT_SUCCESS}" + elif lspci -n | grep "${VENDOR_ID}:${SPC3_PRODUCT_ID}" &>/dev/null; then + echo "${SPC3_ASIC}" + exit "${EXIT_SUCCESS}" fi echo "${UNKN_ASIC}" diff --git a/platform/mellanox/mlnx-sai.mk b/platform/mellanox/mlnx-sai.mk index 419598a6a776..4f9e3b292465 100644 --- a/platform/mellanox/mlnx-sai.mk +++ b/platform/mellanox/mlnx-sai.mk @@ -1,6 +1,6 @@ # Mellanox SAI -MLNX_SAI_VERSION = SAIRel1.16.0-master +MLNX_SAI_VERSION = SAIRel1.16.1-master export MLNX_SAI_VERSION diff --git a/platform/mellanox/mlnx-sai/SAI-Implementation b/platform/mellanox/mlnx-sai/SAI-Implementation index df052a406255..ef47a5592190 160000 --- a/platform/mellanox/mlnx-sai/SAI-Implementation +++ b/platform/mellanox/mlnx-sai/SAI-Implementation @@ -1 +1 @@ -Subproject commit df052a4062556e0f3a1e695fa73efccf81d32a9d +Subproject commit ef47a5592190c08d2f127d3fe8fa5a77ee4087ba diff --git a/platform/mellanox/one-image.mk b/platform/mellanox/one-image.mk index d30e44690991..e4723c3bd1b0 100644 --- a/platform/mellanox/one-image.mk +++ b/platform/mellanox/one-image.mk @@ -11,5 +11,5 @@ $(SONIC_ONE_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.g else $(SONIC_ONE_IMAGE)_DOCKERS = $(SONIC_INSTALL_DOCKER_IMAGES) endif -$(SONIC_ONE_IMAGE)_FILES += $(MLNX_SPC_FW_FILE) $(MLNX_SPC2_FW_FILE) $(MLNX_FFB_SCRIPT) $(ISSU_VERSION_FILE) $(ONIE_FW_UPDATE) +$(SONIC_ONE_IMAGE)_FILES += $(MLNX_FW_FILES) $(MLNX_FFB_SCRIPT) $(ISSU_VERSION_FILE) $(ONIE_FW_UPDATE) SONIC_INSTALLERS += $(SONIC_ONE_IMAGE) diff --git a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers index fa26ae9d24b4..07425a0957d1 160000 --- a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers +++ b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers @@ -1 +1 @@ -Subproject commit fa26ae9d24b4d1ff162f56d83d944c2fc2bcea0b +Subproject commit 07425a0957d100405e3781f8bb633c462f37a92c diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index 649422429771..f2af75cccf2b 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -1,5 +1,5 @@ MLNX_SDK_BASE_PATH = $(PLATFORM_PATH)/sdk-src/sx-kernel/Switch-SDK-drivers/bin/ -MLNX_SDK_VERSION = 4.3.3052 +MLNX_SDK_VERSION = 4.4.0542 MLNX_SDK_ISSU_VERSION = 101 MLNX_SDK_DEB_VERSION = $(subst _,.,$(MLNX_SDK_VERSION)) From a8baca0d6ef94410b4a97a6af6299e090b3096a6 Mon Sep 17 00:00:00 2001 From: Olivier Singla <47356901+olivier-singla@users.noreply.github.com> Date: Wed, 12 Feb 2020 20:41:58 -0500 Subject: [PATCH 105/178] [kernel]: security kernel update to 4.9.189 (#3913) This patch upgrade the kernel from version 4.9.0-9-2 (4.9.168-1+deb9u3) to 4.9.0-11-2 (4.9.189-3+deb9u2) Co-authored-by: rajendra-dendukuri <47423477+rajendra-dendukuri@users.noreply.github.com> --- build_debian.sh | 2 +- .../build_templates/single_instance/swss.service.j2 | 2 +- .../build_templates/single_instance/syncd.service.j2 | 4 ++-- installer/x86_64/install.sh | 4 ++-- platform/barefoot/bfn-modules/debian/control | 2 +- .../debian/control | 2 +- .../debian/control | 2 +- .../sonic-platform-modules-bfn/debian/control | 2 +- platform/broadcom/sai-modules.mk | 2 +- platform/broadcom/saibcm-modules/debian/control | 2 +- .../saibcm-modules/debian/opennsl-modules.dirs | 2 +- .../saibcm-modules/debian/opennsl-modules.install | 10 +++++----- platform/broadcom/saibcm-modules/debian/rules | 6 +++--- .../debian/control | 4 ++-- .../sonic-platform-modules-cel/debian/control | 6 +++--- .../sonic-platform-modules-dell/debian/control | 12 ++++++------ .../sonic-platform-modules-delta/debian/control | 10 +++++----- .../debian/platform-modules-et-6248brb.init | 2 +- .../et-6248brb/scripts/led_status.sh | 2 +- .../d6356/utils/inventec_d6356_util.py | 2 +- .../sonic-platform-modules-inventec/debian/control | 12 ++++++------ .../sonic-platform-modules-e582/debian/control | 4 ++-- .../sonic-platform-modules-cel/debian/control | 2 +- .../sonic-platform-modules-delta/debian/control | 2 +- platform/marvell-armhf/linux-kernel-armhf.mk | 2 +- platform/nephos/nephos-modules.mk | 2 +- platform/nephos/nephos-modules/debian/control | 2 +- .../modules/init.d/nps-modules-4.9.0-9-2-amd64 | 2 +- .../service/nps-modules-4.9.0-9-2-amd64.service | 4 ++-- .../sonic-platform-modules-accton/debian/control | 4 ++-- rules/linux-kernel.mk | 6 +++--- src/sonic-linux-kernel | 2 +- 32 files changed, 62 insertions(+), 62 deletions(-) diff --git a/build_debian.sh b/build_debian.sh index 7583942b23c3..69b3a10ec881 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -37,7 +37,7 @@ if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then else DOCKER_VERSION=5:18.09.8~3-0~debian-stretch fi -LINUX_KERNEL_VERSION=4.9.0-9-2 +LINUX_KERNEL_VERSION=4.9.0-11-2 ## Working directory to prepare the file system FILESYSTEM_ROOT=./fsroot diff --git a/files/build_templates/single_instance/swss.service.j2 b/files/build_templates/single_instance/swss.service.j2 index b7a6396749bd..44206b08ebce 100644 --- a/files/build_templates/single_instance/swss.service.j2 +++ b/files/build_templates/single_instance/swss.service.j2 @@ -4,7 +4,7 @@ Requires=database.service updategraph.service {% if sonic_asic_platform == 'broadcom' %} Requires=opennsl-modules.service {% elif sonic_asic_platform == 'nephos' %} -Requires=nps-modules-4.9.0-9-2-amd64.service +Requires=nps-modules-4.9.0-11-2-amd64.service {% endif %} After=database.service updategraph.service After=interfaces-config.service diff --git a/files/build_templates/single_instance/syncd.service.j2 b/files/build_templates/single_instance/syncd.service.j2 index b52772e9b114..7a7d27114b07 100644 --- a/files/build_templates/single_instance/syncd.service.j2 +++ b/files/build_templates/single_instance/syncd.service.j2 @@ -4,14 +4,14 @@ Requires=database.service updategraph.service {% if sonic_asic_platform == 'broadcom' %} Requires=opennsl-modules.service {% elif sonic_asic_platform == 'nephos' %} -Requires=nps-modules-4.9.0-9-2-amd64.service +Requires=nps-modules-4.9.0-11-2-amd64.service {% endif %} After=database.service updategraph.service After=interfaces-config.service {% if sonic_asic_platform == 'broadcom' %} After=opennsl-modules.service {% elif sonic_asic_platform == 'nephos' %} -After=nps-modules-4.9.0-9-2-amd64.service +After=nps-modules-4.9.0-11-2-amd64.service {% endif %} After=swss.service Before=ntp-config.service diff --git a/installer/x86_64/install.sh b/installer/x86_64/install.sh index 78e8e2f4623b..d0aa7818df9b 100755 --- a/installer/x86_64/install.sh +++ b/installer/x86_64/install.sh @@ -606,12 +606,12 @@ menuentry '$demo_grub_entry' { if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi insmod part_msdos insmod ext2 - linux /$image_dir/boot/vmlinuz-4.9.0-9-2-amd64 root=$grub_cfg_root rw $GRUB_CMDLINE_LINUX \ + linux /$image_dir/boot/vmlinuz-4.9.0-11-2-amd64 root=$grub_cfg_root rw $GRUB_CMDLINE_LINUX \ net.ifnames=0 biosdevname=0 \ loop=$image_dir/$FILESYSTEM_SQUASHFS loopfstype=squashfs \ apparmor=1 security=apparmor varlog_size=$VAR_LOG_SIZE usbcore.autosuspend=-1 $ONIE_PLATFORM_EXTRA_CMDLINE_LINUX echo 'Loading $demo_volume_label $demo_type initial ramdisk ...' - initrd /$image_dir/boot/initrd.img-4.9.0-9-2-amd64 + initrd /$image_dir/boot/initrd.img-4.9.0-11-2-amd64 } EOF diff --git a/platform/barefoot/bfn-modules/debian/control b/platform/barefoot/bfn-modules/debian/control index c9a53ec1d08b..d6f7a991107d 100644 --- a/platform/barefoot/bfn-modules/debian/control +++ b/platform/barefoot/bfn-modules/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: bfn-modules Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for bfn asic for mmap diff --git a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control index 192da9dab95c..e3f5356f22db 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control +++ b/platform/barefoot/sonic-platform-modules-bfn-montara/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: sonic-platform-modules-bfn-montara Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control index edbc5b890c58..bc6c990efebb 100644 --- a/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control +++ b/platform/barefoot/sonic-platform-modules-bfn-newport/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: sonic-platform-modules-bfn-newport Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel module for bfn platform fpga and scripts for the devices such as fan, led, sfp diff --git a/platform/barefoot/sonic-platform-modules-bfn/debian/control b/platform/barefoot/sonic-platform-modules-bfn/debian/control index 04d4c598e9d9..cca87831f1f1 100644 --- a/platform/barefoot/sonic-platform-modules-bfn/debian/control +++ b/platform/barefoot/sonic-platform-modules-bfn/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: sonic-platform-modules-bfn Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sai-modules.mk b/platform/broadcom/sai-modules.mk index 1d559d0ad320..93132c2287bd 100644 --- a/platform/broadcom/sai-modules.mk +++ b/platform/broadcom/sai-modules.mk @@ -1,6 +1,6 @@ # Broadcom SAI modules -KVERSION = 4.9.0-9-2-amd64 +KVERSION = 4.9.0-11-2-amd64 BRCM_OPENNSL_KERNEL_VERSION = 3.7.3.3-1 BRCM_OPENNSL_KERNEL = opennsl-modules_$(BRCM_OPENNSL_KERNEL_VERSION)_amd64.deb diff --git a/platform/broadcom/saibcm-modules/debian/control b/platform/broadcom/saibcm-modules/debian/control index 75b77c8a2f00..fafe7dfb9299 100644 --- a/platform/broadcom/saibcm-modules/debian/control +++ b/platform/broadcom/saibcm-modules/debian/control @@ -10,5 +10,5 @@ Standards-Version: 3.9.3 Package: opennsl-modules Architecture: amd64 Section: main -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for broadcom SAI diff --git a/platform/broadcom/saibcm-modules/debian/opennsl-modules.dirs b/platform/broadcom/saibcm-modules/debian/opennsl-modules.dirs index 38af58a5c5ee..a32540eadcf5 100644 --- a/platform/broadcom/saibcm-modules/debian/opennsl-modules.dirs +++ b/platform/broadcom/saibcm-modules/debian/opennsl-modules.dirs @@ -1 +1 @@ -lib/modules/4.9.0-9-2-amd64/extra +lib/modules/4.9.0-11-2-amd64/extra diff --git a/platform/broadcom/saibcm-modules/debian/opennsl-modules.install b/platform/broadcom/saibcm-modules/debian/opennsl-modules.install index e16980dc2c0d..9802d2f2443a 100644 --- a/platform/broadcom/saibcm-modules/debian/opennsl-modules.install +++ b/platform/broadcom/saibcm-modules/debian/opennsl-modules.install @@ -1,6 +1,6 @@ -systems/linux/user/x86-smp_generic_64-2_6/linux-bcm-knet.ko lib/modules/4.9.0-9-2-amd64/extra -systems/linux/user/x86-smp_generic_64-2_6/linux-kernel-bde.ko lib/modules/4.9.0-9-2-amd64/extra -systems/linux/user/x86-smp_generic_64-2_6/linux-user-bde.ko lib/modules/4.9.0-9-2-amd64/extra -systems/linux/user/x86-smp_generic_64-2_6/linux-knet-cb.ko lib/modules/4.9.0-9-2-amd64/extra -systems/linux/user/x86-smp_generic_64-2_6/psample.ko lib/modules/4.9.0-9-2-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/linux-bcm-knet.ko lib/modules/4.9.0-11-2-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/linux-kernel-bde.ko lib/modules/4.9.0-11-2-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/linux-user-bde.ko lib/modules/4.9.0-11-2-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/linux-knet-cb.ko lib/modules/4.9.0-11-2-amd64/extra +systems/linux/user/x86-smp_generic_64-2_6/psample.ko lib/modules/4.9.0-11-2-amd64/extra systemd/opennsl-modules.service lib/systemd/system diff --git a/platform/broadcom/saibcm-modules/debian/rules b/platform/broadcom/saibcm-modules/debian/rules index 0092cc1a1027..636874251aa9 100755 --- a/platform/broadcom/saibcm-modules/debian/rules +++ b/platform/broadcom/saibcm-modules/debian/rules @@ -60,7 +60,7 @@ kdist_config: prep-deb-files kdist_clean: clean dh_testdir dh_clean - SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 KERNDIR=/usr/src/linux-headers-4.9.0-9-2-amd64 KERNEL_SRC=/usr/src/linux-headers-4.9.0-9-2-amd64 $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 clean + SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 KERNDIR=/usr/src/linux-headers-4.9.0-11-2-amd64 KERNEL_SRC=/usr/src/linux-headers-4.9.0-11-2-amd64 $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 clean # rm -f driver/*.o driver/*.ko # ### end KERNEL SETUP @@ -78,7 +78,7 @@ build-arch-stamp: dh_testdir # Add here command to compile/build the package. - SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 KERNDIR=/usr/src/linux-headers-4.9.0-9-2-amd64 KERNEL_SRC=/usr/src/linux-headers-4.9.0-9-2-amd64 $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 + SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 KERNDIR=/usr/src/linux-headers-4.9.0-11-2-amd64 KERNEL_SRC=/usr/src/linux-headers-4.9.0-11-2-amd64 $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 touch $@ @@ -103,7 +103,7 @@ clean: rm -f build-arch-stamp build-indep-stamp configure-stamp # Add here commands to clean up after the build process. - SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 KERNDIR=/usr/src/linux-headers-4.9.0-9-2-amd64 KERNEL_SRC=/usr/src/linux-headers-4.9.0-9-2-amd64 $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 clean + SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 KERNDIR=/usr/src/linux-headers-4.9.0-11-2-amd64 KERNEL_SRC=/usr/src/linux-headers-4.9.0-11-2-amd64 $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 clean dh_clean diff --git a/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control b/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control index 9a53b9823222..beba5b5f4e62 100644 --- a/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control +++ b/platform/broadcom/sonic-platform-modules-alphanetworks/debian/control @@ -7,11 +7,11 @@ Standards-Version: 3.9.3 Package: sonic-platform-alphanetworks-snh60a0-320fv2 Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: sonic-platform-alphanetworks-snh60b0-640f Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/control b/platform/broadcom/sonic-platform-modules-cel/debian/control index 2e9b578872fa..4fe6d626eb1c 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/control +++ b/platform/broadcom/sonic-platform-modules-cel/debian/control @@ -7,16 +7,16 @@ Standards-Version: 3.9.3 Package: platform-modules-dx010 Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-haliburton Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-silverstone Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as led, sfp. diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/control b/platform/broadcom/sonic-platform-modules-dell/debian/control index f32fa7244acc..0b9514687ce8 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/control +++ b/platform/broadcom/sonic-platform-modules-dell/debian/control @@ -7,30 +7,30 @@ Standards-Version: 3.9.3 Package: platform-modules-s6000 Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-z9100 Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-s6100 Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-z9264f Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-s5232f Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-s5248f Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/broadcom/sonic-platform-modules-delta/debian/control b/platform/broadcom/sonic-platform-modules-delta/debian/control index 65b01234b4ec..e2e9883f9b2b 100644 --- a/platform/broadcom/sonic-platform-modules-delta/debian/control +++ b/platform/broadcom/sonic-platform-modules-delta/debian/control @@ -7,25 +7,25 @@ Standards-Version: 3.9.3 Package: platform-modules-ag9032v1 Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-ag9064 Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-ag5648 Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-et-6248brb Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-ag9032v2a Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as syseeprom, sfp diff --git a/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-et-6248brb.init b/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-et-6248brb.init index 64361ced6b6c..58681208ef6c 100755 --- a/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-et-6248brb.init +++ b/platform/broadcom/sonic-platform-modules-delta/debian/platform-modules-et-6248brb.init @@ -25,7 +25,7 @@ start) modprobe dni_gpio modprobe delta_et-6248brb_platform - if [ `uname -a | awk '{print $3}'` = "4.9.0-9-2-amd64" ]; then + if [ `uname -a | awk '{print $3}'` = "4.9.0-11-2-amd64" ]; then echo "453" > "/sys/class/gpio/export" echo "454" > "/sys/class/gpio/export" echo "455" > "/sys/class/gpio/export" diff --git a/platform/broadcom/sonic-platform-modules-delta/et-6248brb/scripts/led_status.sh b/platform/broadcom/sonic-platform-modules-delta/et-6248brb/scripts/led_status.sh index 734a44a6ca95..573af2156661 100644 --- a/platform/broadcom/sonic-platform-modules-delta/et-6248brb/scripts/led_status.sh +++ b/platform/broadcom/sonic-platform-modules-delta/et-6248brb/scripts/led_status.sh @@ -7,7 +7,7 @@ FAN2_RPM="/sys/bus/i2c/devices/0-002e/fan2_input" FAN_TRAY1_LED="/sys/devices/platform/delta-et6248brb-gpio.0/FAN/fan1_led_ag" FAN_TRAY2_LED="/sys/devices/platform/delta-et6248brb-gpio.0/FAN/fan2_led_ag" -if [ `uname -a | awk '{print $3}'` = "4.9.0-9-2-amd64" ]; then +if [ `uname -a | awk '{print $3}'` = "4.9.0-11-2-amd64" ]; then SYS_LED_G="/sys/class/gpio/gpio453/value" SYS_LED_R="/sys/class/gpio/gpio454/value" PWR_LED_G="/sys/class/gpio/gpio455/value" diff --git a/platform/broadcom/sonic-platform-modules-inventec/d6356/utils/inventec_d6356_util.py b/platform/broadcom/sonic-platform-modules-inventec/d6356/utils/inventec_d6356_util.py index 890973cb8356..10fcb001b0c2 100755 --- a/platform/broadcom/sonic-platform-modules-inventec/d6356/utils/inventec_d6356_util.py +++ b/platform/broadcom/sonic-platform-modules-inventec/d6356/utils/inventec_d6356_util.py @@ -141,7 +141,7 @@ def system_install(): status, output = exec_cmd("rmmod lpc_ich ", 1) #insert extra module - status, output = exec_cmd("insmod /lib/modules/4.9.0-9-2-amd64/kernel/drivers/gpio/gpio-ich.ko gpiobase=0",1) + status, output = exec_cmd("insmod /lib/modules/4.9.0-11-2-amd64/kernel/drivers/gpio/gpio-ich.ko gpiobase=0",1) #install drivers for i in range(0,len(drivers)): diff --git a/platform/broadcom/sonic-platform-modules-inventec/debian/control b/platform/broadcom/sonic-platform-modules-inventec/debian/control index 6cb61630823f..86f7e7b20f65 100644 --- a/platform/broadcom/sonic-platform-modules-inventec/debian/control +++ b/platform/broadcom/sonic-platform-modules-inventec/debian/control @@ -7,30 +7,30 @@ Standards-Version: 3.9.3 Package: platform-modules-d7032q28b Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led Package: platform-modules-d7054q28b Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led Package: platform-modules-d6254qs Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led Package: platform-modules-d6556 Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led Package: platform-modules-d6356 Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led Package: platform-modules-d7264q28b Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led diff --git a/platform/centec/sonic-platform-modules-e582/debian/control b/platform/centec/sonic-platform-modules-e582/debian/control index ba30e04f0388..c449246b2823 100644 --- a/platform/centec/sonic-platform-modules-e582/debian/control +++ b/platform/centec/sonic-platform-modules-e582/debian/control @@ -7,11 +7,11 @@ Standards-Version: 3.9.3 Package: platform-modules-e582-48x2q4z Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-e582-48x6q Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/innovium/sonic-platform-modules-cel/debian/control b/platform/innovium/sonic-platform-modules-cel/debian/control index 48ef777a99a6..543d381ab6f7 100755 --- a/platform/innovium/sonic-platform-modules-cel/debian/control +++ b/platform/innovium/sonic-platform-modules-cel/debian/control @@ -7,5 +7,5 @@ Standards-Version: 3.9.3 Package: platform-modules-midstone-200i Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices diff --git a/platform/innovium/sonic-platform-modules-delta/debian/control b/platform/innovium/sonic-platform-modules-delta/debian/control index 71c403387f80..3fe3ffc9f526 100644 --- a/platform/innovium/sonic-platform-modules-delta/debian/control +++ b/platform/innovium/sonic-platform-modules-delta/debian/control @@ -7,7 +7,7 @@ Standards-Version: 3.9.3 Package: platform-modules-et-c032if Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for platform devices such as fan, led, sfp diff --git a/platform/marvell-armhf/linux-kernel-armhf.mk b/platform/marvell-armhf/linux-kernel-armhf.mk index 32e8ea3c604a..4d52beac49d9 100644 --- a/platform/marvell-armhf/linux-kernel-armhf.mk +++ b/platform/marvell-armhf/linux-kernel-armhf.mk @@ -1,7 +1,7 @@ # linux kernel package for marvell armhf # Add platform specific DTB -LINUX_KERNEL_DTB = linux-image-4.9.168-armhf.deb +LINUX_KERNEL_DTB = linux-image-4.9.189-armhf.deb $(LINUX_KERNEL_DTB)_URL = https://github.com/Marvell-switching/sonic-marvell-binaries/raw/master/armhf/kernel/$(LINUX_KERNEL_DTB) SONIC_ONLINE_DEBS += $(LINUX_KERNEL_DTB) SONIC_STRETCH_DEBS += $(LINUX_KERNEL_DTB) diff --git a/platform/nephos/nephos-modules.mk b/platform/nephos/nephos-modules.mk index b76141b40663..ebd696217b8e 100644 --- a/platform/nephos/nephos-modules.mk +++ b/platform/nephos/nephos-modules.mk @@ -9,7 +9,7 @@ SDK_FROM_LOCAL = n endif SDK_VERSION = 3.0.0 -LINUX_VER = 4.9.0-9-2 +LINUX_VER = 4.9.0-11-2 SDK_COMMIT_ID = 529202 ifeq ($(SAI_FROM_LOCAL), y) diff --git a/platform/nephos/nephos-modules/debian/control b/platform/nephos/nephos-modules/debian/control index f5e6e00d13c0..246b89eab477 100644 --- a/platform/nephos/nephos-modules/debian/control +++ b/platform/nephos/nephos-modules/debian/control @@ -7,6 +7,6 @@ Standards-Version: 3.9.3 Package: nephos-modules Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 +Depends: linux-image-4.9.0-11-2-amd64 Description: kernel modules for nephos asic diff --git a/platform/nephos/nephos-modules/modules/init.d/nps-modules-4.9.0-9-2-amd64 b/platform/nephos/nephos-modules/modules/init.d/nps-modules-4.9.0-9-2-amd64 index 366ca6b08456..a6deb4217a95 100755 --- a/platform/nephos/nephos-modules/modules/init.d/nps-modules-4.9.0-9-2-amd64 +++ b/platform/nephos/nephos-modules/modules/init.d/nps-modules-4.9.0-9-2-amd64 @@ -45,7 +45,7 @@ force-reload|restart) ;; *) - echo "Usage: /etc/init.d/nps-modules-4.9.0-9-2-amd64.init {start|stop}" + echo "Usage: /etc/init.d/nps-modules-4.9.0-11-2-amd64.init {start|stop}" exit 1 ;; esac diff --git a/platform/nephos/nephos-modules/modules/service/nps-modules-4.9.0-9-2-amd64.service b/platform/nephos/nephos-modules/modules/service/nps-modules-4.9.0-9-2-amd64.service index 246226ea9d40..9acdeb30a44c 100644 --- a/platform/nephos/nephos-modules/modules/service/nps-modules-4.9.0-9-2-amd64.service +++ b/platform/nephos/nephos-modules/modules/service/nps-modules-4.9.0-9-2-amd64.service @@ -5,8 +5,8 @@ Before=syncd.service [Service] Type=oneshot -ExecStart=-/etc/init.d/nps-modules-4.9.0-9-2-amd64 start -ExecStop=-/etc/init.d/nps-modules-4.9.0-9-2-amd64 stop +ExecStart=-/etc/init.d/nps-modules-4.9.0-11-2-amd64 start +ExecStop=-/etc/init.d/nps-modules-4.9.0-11-2-amd64 stop RemainAfterExit=yes [Install] diff --git a/platform/nephos/sonic-platform-modules-accton/debian/control b/platform/nephos/sonic-platform-modules-accton/debian/control index 8f7258ebdd6a..639534f3edcc 100755 --- a/platform/nephos/sonic-platform-modules-accton/debian/control +++ b/platform/nephos/sonic-platform-modules-accton/debian/control @@ -7,5 +7,5 @@ Standards-Version: 3.9.3 Package: sonic-platform-accton-as7116-54x Architecture: amd64 -Depends: linux-image-4.9.0-9-2-amd64 -Description: kernel modules for platform devices such as fan, led, sfp \ No newline at end of file +Depends: linux-image-4.9.0-11-2-amd64 +Description: kernel modules for platform devices such as fan, led, sfp diff --git a/rules/linux-kernel.mk b/rules/linux-kernel.mk index 5250f8b97e8f..e6742bdf14cf 100644 --- a/rules/linux-kernel.mk +++ b/rules/linux-kernel.mk @@ -1,9 +1,9 @@ # linux kernel package -KVERSION_SHORT = 4.9.0-9-2 +KVERSION_SHORT = 4.9.0-11-2 KVERSION = $(KVERSION_SHORT)-$(CONFIGURED_ARCH) -KERNEL_VERSION = 4.9.168 -KERNEL_SUBVERSION = 1+deb9u5 +KERNEL_VERSION = 4.9.189 +KERNEL_SUBVERSION = 3+deb9u2 ifeq ($(CONFIGURED_ARCH), armhf) # Override kernel version for ARMHF as it uses arm MP (multi-platform) for short version KVERSION = $(KVERSION_SHORT)-armmp diff --git a/src/sonic-linux-kernel b/src/sonic-linux-kernel index 6650d4eb8d8c..3d97fcd5667e 160000 --- a/src/sonic-linux-kernel +++ b/src/sonic-linux-kernel @@ -1 +1 @@ -Subproject commit 6650d4eb8d8c1ea4007145e5ffe17c3821298da2 +Subproject commit 3d97fcd5667ebb8351977956437f6662920f368e From 8e36068237380954e749a629e145821f8015e661 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Thu, 5 Mar 2020 15:35:35 -0800 Subject: [PATCH 106/178] [sonic-cfggen] Loading the configuration from init_cfg.json and then from config_db.json (#4148) --- files/build_templates/docker_image_ctl.j2 | 8 ++++++-- files/scripts/configdb-load.sh | 8 ++++++-- platform/p4/docker-sonic-p4/start.sh | 2 +- platform/vs/docker-sonic-vs/start.sh | 2 +- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 9357ae58d4a1..a15546a1e59e 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -106,9 +106,13 @@ function postStartAction() if [[ ("$BOOT_TYPE" == "warm" || "$BOOT_TYPE" == "fastfast") && -f $WARM_DIR/dump.rdb ]]; then rm -f $WARM_DIR/dump.rdb else - # If there is a config db dump file, load it + # If there is a config_db.json dump file, load it. if [ -r /etc/sonic/config_db.json ]; then - sonic-cfggen -j /etc/sonic/config_db.json --write-to-db + if [ -r /etc/sonic/init_cfg.json ]; then + sonic-cfggen -j /etc/sonic/init_cfg.json -j /etc/sonic/config_db.json --write-to-db + else + sonic-cfggen -j /etc/sonic/config_db.json --write-to-db + fi fi if [[ "$BOOT_TYPE" == "fast" ]]; then diff --git a/files/scripts/configdb-load.sh b/files/scripts/configdb-load.sh index e7080eb40f3d..b1bf761371bf 100755 --- a/files/scripts/configdb-load.sh +++ b/files/scripts/configdb-load.sh @@ -5,9 +5,13 @@ until [[ $(redis-cli ping | grep -c PONG) -gt 0 ]]; do sleep 1; done -# If there is a config db dump file, load it +# If there is a config_db.json dump file, load it. if [ -r /etc/sonic/config_db.json ]; then - sonic-cfggen -j /etc/sonic/config_db.json --write-to-db + if [ -r /etc/sonic/init_cfg.json ]; then + sonic-cfggen -j /etc/sonic/init_cfg.json -j /etc/sonic/config_db.json --write-to-db + else + sonic-cfggen -j /etc/sonic/config_db.json --write-to-db + fi fi sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" diff --git a/platform/p4/docker-sonic-p4/start.sh b/platform/p4/docker-sonic-p4/start.sh index c9cf4528bedd..e3251bb2f4e5 100755 --- a/platform/p4/docker-sonic-p4/start.sh +++ b/platform/p4/docker-sonic-p4/start.sh @@ -11,7 +11,7 @@ SYSTEM_MAC_ADDRESS=$(ip link show eth0 | grep ether | awk '{print $2}') sonic-cfggen -a '{"DEVICE_METADATA":{"localhost": {"mac": "'$SYSTEM_MAC_ADDRESS'"}}}' --print-data > /etc/sonic/init_cfg.json if [ -f /etc/sonic/config_db.json ]; then - sonic-cfggen -j /etc/sonic/config_db.json -j /etc/sonic/init_cfg.json --print-data > /tmp/config_db.json + sonic-cfggen -j /etc/sonic/init_cfg.json -j /etc/sonic/config_db.json --print-data > /tmp/config_db.json mv /tmp/config_db.json /etc/sonic/config_db.json else sonic-cfggen -j /etc/sonic/init_cfg.json --print-data > /etc/sonic/config_db.json diff --git a/platform/vs/docker-sonic-vs/start.sh b/platform/vs/docker-sonic-vs/start.sh index dd9fee4deb3d..f8fcf974b65c 100755 --- a/platform/vs/docker-sonic-vs/start.sh +++ b/platform/vs/docker-sonic-vs/start.sh @@ -13,7 +13,7 @@ SYSTEM_MAC_ADDRESS=$(ip link show eth0 | grep ether | awk '{print $2}') sonic-cfggen -a '{"DEVICE_METADATA":{"localhost": {"mac": "'$SYSTEM_MAC_ADDRESS'"}}}' --print-data > /etc/sonic/init_cfg.json if [ -f /etc/sonic/config_db.json ]; then - sonic-cfggen -j /etc/sonic/config_db.json -j /etc/sonic/init_cfg.json --print-data > /tmp/config_db.json + sonic-cfggen -j /etc/sonic/init_cfg.json -j /etc/sonic/config_db.json --print-data > /tmp/config_db.json mv /tmp/config_db.json /etc/sonic/config_db.json else # generate and merge buffers configuration into config file From 9eb3a1b89f875dfab3f732c54960e354a5924075 Mon Sep 17 00:00:00 2001 From: lguohan Date: Wed, 4 Mar 2020 10:02:55 -0800 Subject: [PATCH 107/178] [Mellanox]Integrate hw-mgmt 7.0000.3012 and advance the linux kernel (#4193) * [Mellanox]Integrate hw-mgmt 7.0000.3012 * [sonic-linux-kernel]Advance the submodule head Advance the sonic-linux-kernel [sFlow]: Patch to fix skb_over_panic in psample driver (#120) Added support in the kernel for fullcone 3-tuple unique nat. (#100) Adding support to compile ARM architecture (#102) [ixgbe] Support bcm54616s external phy in ixgbe (#122) Fix i2c ISMT DMA buffer alignment issue (#123) [mellanox]: Add SN4700 patches. (#126) --- platform/mellanox/hw-management.mk | 2 +- platform/mellanox/hw-management/hw-mgmt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/mellanox/hw-management.mk b/platform/mellanox/hw-management.mk index ff1ea207572d..692a816a0f4f 100644 --- a/platform/mellanox/hw-management.mk +++ b/platform/mellanox/hw-management.mk @@ -1,6 +1,6 @@ # Mellanox HW Management -MLNX_HW_MANAGEMENT_VERSION = 7.0000.2308 +MLNX_HW_MANAGEMENT_VERSION = 7.0000.3012 export MLNX_HW_MANAGEMENT_VERSION diff --git a/platform/mellanox/hw-management/hw-mgmt b/platform/mellanox/hw-management/hw-mgmt index 28d83cdb3565..2f659142ab3b 160000 --- a/platform/mellanox/hw-management/hw-mgmt +++ b/platform/mellanox/hw-management/hw-mgmt @@ -1 +1 @@ -Subproject commit 28d83cdb3565d3b0352cc718fe82a14cacd1d4a5 +Subproject commit 2f659142ab3b4deb58989a2ca38b0b1671600509 From 9f2664e4c1db29682d1137bcc2c430585cba0977 Mon Sep 17 00:00:00 2001 From: Abhishek Dosi Date: Sun, 15 Mar 2020 09:19:27 -0700 Subject: [PATCH 108/178] [Submodule-Update] sonic-swss with following changes: Multi-Db changes for NAT feature. (#1202) [cfgmgr] clear loopback and vrf in kernel if not warmstart (#1141) upon cold reboot, skip remove mgmt vrf table from the kernel (#1214) --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index 69f5fc9c8e58..fcdd17e995e8 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 69f5fc9c8e5861d19cba71a19f77e746fad8d772 +Subproject commit fcdd17e995e8e804890b7076a496ec71365f4495 From 505d4bfb6576750f1569eb1518af1f2394cf6b55 Mon Sep 17 00:00:00 2001 From: Abhishek Dosi Date: Sun, 15 Mar 2020 09:33:58 -0700 Subject: [PATCH 109/178] [Submodule-Update] sonic-swss with following changes: Multi-Db changes for NAT feature. (#1202) [cfgmgr] clear loopback and vrf in kernel if not warmstart (#1141) upon cold reboot, skip remove mgmt vrf table from the kernel (#1214) --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index fcdd17e995e8..71bd8558e20e 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit fcdd17e995e8e804890b7076a496ec71365f4495 +Subproject commit 71bd8558e20e36ab20e2579786645580feb0def2 From 055d7cd19d7d827037e6ce39dc011fc72eb24f36 Mon Sep 17 00:00:00 2001 From: Andriy Kokhan <43479230+akokhan@users.noreply.github.com> Date: Mon, 16 Mar 2020 19:14:43 +0200 Subject: [PATCH 110/178] [BFN] Updated Barefoot DEBs to 20200205 (#4261) Signed-off-by: Andriy Kokhan --- platform/barefoot/bfn-platform.mk | 4 ++-- platform/barefoot/bfn-sai.mk | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/platform/barefoot/bfn-platform.mk b/platform/barefoot/bfn-platform.mk index 854026b52949..622563e09853 100644 --- a/platform/barefoot/bfn-platform.mk +++ b/platform/barefoot/bfn-platform.mk @@ -1,5 +1,5 @@ -BFN_PLATFORM = bfnplatform_20191115_deb9.deb -$(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/bfnplatform_20191115_deb9.deb" +BFN_PLATFORM = bfnplatform_20200205_deb9.deb +$(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/$(BFN_PLATFORM)" SONIC_ONLINE_DEBS += $(BFN_PLATFORM) $(BFN_SAI_DEV)_DEPENDS += $(BFN_PLATFORM) diff --git a/platform/barefoot/bfn-sai.mk b/platform/barefoot/bfn-sai.mk index 6f413d50c11e..2f2429845f5d 100644 --- a/platform/barefoot/bfn-sai.mk +++ b/platform/barefoot/bfn-sai.mk @@ -1,5 +1,8 @@ -BFN_SAI = bfnsdk_20191115_deb9.deb -$(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/bfnsdk_20191115_deb9.deb" +BFN_SAI = bfnsdk_20200205_deb9.deb +$(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/$(BFN_SAI)" + +$(BFN_SAI)_DEPENDS += $(LIBNL_GENL3_DEV) +$(BFN_SAI)_RDEPENDS += $(LIBNL_GENL3) SONIC_ONLINE_DEBS += $(BFN_SAI) $(BFN_SAI_DEV)_DEPENDS += $(BFN_SAI) From ba42bde9f4fb037ce1ecd5ffa4e1702f191996da Mon Sep 17 00:00:00 2001 From: byu343 Date: Thu, 19 Mar 2020 02:54:36 -0700 Subject: [PATCH 111/178] [arista]: Fix symbolic links for arista lodoga (#4283) Symbolic links are used in device plugins for Arista Lodoga, but some mistake is made on them in the last pull request: https://github.com/Azure/sonic-buildimage/pull/4232.patch. This change is supposed to fix it. --- device/arista/x86_64-arista_7050cx3_32s/platform_reboot | 0 device/arista/x86_64-arista_7050cx3_32s/plugins | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 120000 device/arista/x86_64-arista_7050cx3_32s/platform_reboot mode change 100644 => 120000 device/arista/x86_64-arista_7050cx3_32s/plugins diff --git a/device/arista/x86_64-arista_7050cx3_32s/platform_reboot b/device/arista/x86_64-arista_7050cx3_32s/platform_reboot deleted file mode 100644 index 7f94a49e38b0..000000000000 --- a/device/arista/x86_64-arista_7050cx3_32s/platform_reboot +++ /dev/null @@ -1 +0,0 @@ -../x86_64-arista_common/platform_reboot \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050cx3_32s/platform_reboot b/device/arista/x86_64-arista_7050cx3_32s/platform_reboot new file mode 120000 index 000000000000..7f94a49e38b0 --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/platform_reboot @@ -0,0 +1 @@ +../x86_64-arista_common/platform_reboot \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050cx3_32s/plugins b/device/arista/x86_64-arista_7050cx3_32s/plugins deleted file mode 100644 index 789a45fcace9..000000000000 --- a/device/arista/x86_64-arista_7050cx3_32s/plugins +++ /dev/null @@ -1 +0,0 @@ -../x86_64-arista_common/plugins \ No newline at end of file diff --git a/device/arista/x86_64-arista_7050cx3_32s/plugins b/device/arista/x86_64-arista_7050cx3_32s/plugins new file mode 120000 index 000000000000..789a45fcace9 --- /dev/null +++ b/device/arista/x86_64-arista_7050cx3_32s/plugins @@ -0,0 +1 @@ +../x86_64-arista_common/plugins \ No newline at end of file From 39889a3c358df4d9eb867529378ac1fea021c638 Mon Sep 17 00:00:00 2001 From: Andriy Kokhan <43479230+akokhan@users.noreply.github.com> Date: Fri, 13 Mar 2020 01:11:15 +0200 Subject: [PATCH 112/178] [Service] Added NAT entry into CONTAINER_FEATURE. Fixes #4247. (#4250) * [Service] Added NAT entry into CONTAINER_FEATURE. Fixes #4247. Signed-off-by: Andriy Kokhan --- files/build_templates/init_cfg.json.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/build_templates/init_cfg.json.j2 b/files/build_templates/init_cfg.json.j2 index 17617ee1a3cb..c187e02762b8 100644 --- a/files/build_templates/init_cfg.json.j2 +++ b/files/build_templates/init_cfg.json.j2 @@ -25,7 +25,7 @@ {% endfor %} }, "CONTAINER_FEATURE": { -{%- for container in ["bgp", "database", "dhcp_relay", "lldp", "pmon", "radv", "restapi", "sflow", +{%- for container in ["bgp", "database", "dhcp_relay", "lldp", "nat", "pmon", "radv", "restapi", "sflow", "snmp", "swss", "syncd", "teamd", "telemetry"] %} "{{container}}": { "auto_restart": "disabled", From 444c450aa31a2a638550affd3a7d420241bad9f0 Mon Sep 17 00:00:00 2001 From: Mykola F <37578614+mykolaf@users.noreply.github.com> Date: Wed, 18 Mar 2020 20:59:39 +0200 Subject: [PATCH 113/178] [syncd-rpc.mk] install ptf dependancy (#4279) Signed-off-by: Mykola Faryma --- platform/barefoot/docker-syncd-bfn-rpc.mk | 2 +- platform/broadcom/docker-syncd-brcm-rpc.mk | 2 +- platform/cavium/docker-syncd-cavm-rpc.mk | 2 +- platform/centec/docker-syncd-centec-rpc.mk | 2 +- platform/innovium/docker-syncd-invm-rpc.mk | 2 +- platform/marvell-arm64/docker-syncd-mrvl-rpc.mk | 2 +- platform/marvell-armhf/docker-syncd-mrvl-rpc.mk | 2 +- platform/marvell/docker-syncd-mrvl-rpc.mk | 2 +- platform/mellanox/docker-syncd-mlnx-rpc.mk | 2 +- platform/nephos/docker-syncd-nephos-rpc.mk | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/platform/barefoot/docker-syncd-bfn-rpc.mk b/platform/barefoot/docker-syncd-bfn-rpc.mk index d9cb0b5d6172..11b70a3a774f 100644 --- a/platform/barefoot/docker-syncd-bfn-rpc.mk +++ b/platform/barefoot/docker-syncd-bfn-rpc.mk @@ -2,7 +2,7 @@ DOCKER_SYNCD_BFN_RPC = docker-syncd-bfn-rpc.gz $(DOCKER_SYNCD_BFN_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-bfn-rpc -$(DOCKER_SYNCD_BFN_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) +$(DOCKER_SYNCD_BFN_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(PTF) $(DOCKER_SYNCD_BFN_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_BFN_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ diff --git a/platform/broadcom/docker-syncd-brcm-rpc.mk b/platform/broadcom/docker-syncd-brcm-rpc.mk index bd2ef01c5eed..355d7e0f1f8c 100644 --- a/platform/broadcom/docker-syncd-brcm-rpc.mk +++ b/platform/broadcom/docker-syncd-brcm-rpc.mk @@ -2,7 +2,7 @@ DOCKER_SYNCD_BRCM_RPC = docker-syncd-brcm-rpc.gz $(DOCKER_SYNCD_BRCM_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-brcm-rpc -$(DOCKER_SYNCD_BRCM_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) +$(DOCKER_SYNCD_BRCM_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(PTF) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_BRCM_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ $(LIBSWSSCOMMON_DBG) \ diff --git a/platform/cavium/docker-syncd-cavm-rpc.mk b/platform/cavium/docker-syncd-cavm-rpc.mk index e57370fce5ca..ebe614b3c183 100644 --- a/platform/cavium/docker-syncd-cavm-rpc.mk +++ b/platform/cavium/docker-syncd-cavm-rpc.mk @@ -2,7 +2,7 @@ DOCKER_SYNCD_CAVM_RPC = docker-syncd-cavm-rpc.gz $(DOCKER_SYNCD_CAVM_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-cavm-rpc -$(DOCKER_SYNCD_CAVM_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(CAVM_LIBSAI) $(XP_TOOLS) $(REDIS_TOOLS) +$(DOCKER_SYNCD_CAVM_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(CAVM_LIBSAI) $(XP_TOOLS) $(REDIS_TOOLS) $(PTF) $(DOCKER_SYNCD_CAVM_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_CAVM_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ diff --git a/platform/centec/docker-syncd-centec-rpc.mk b/platform/centec/docker-syncd-centec-rpc.mk index 71c8ef7753c1..47c672dd93de 100644 --- a/platform/centec/docker-syncd-centec-rpc.mk +++ b/platform/centec/docker-syncd-centec-rpc.mk @@ -2,7 +2,7 @@ DOCKER_SYNCD_CENTEC_RPC = docker-syncd-centec-rpc.gz $(DOCKER_SYNCD_CENTEC_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-centec-rpc -$(DOCKER_SYNCD_CENTEC_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) +$(DOCKER_SYNCD_CENTEC_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(PTF) $(DOCKER_SYNCD_CENTEC_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_CENTEC_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ diff --git a/platform/innovium/docker-syncd-invm-rpc.mk b/platform/innovium/docker-syncd-invm-rpc.mk index 313f0d12ac20..62d6891bbc21 100755 --- a/platform/innovium/docker-syncd-invm-rpc.mk +++ b/platform/innovium/docker-syncd-invm-rpc.mk @@ -2,7 +2,7 @@ DOCKER_SYNCD_INVM_RPC = docker-syncd-invm-rpc.gz $(DOCKER_SYNCD_INVM_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-invm-rpc -$(DOCKER_SYNCD_INVM_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(INVM_LIBSAI) +$(DOCKER_SYNCD_INVM_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(INVM_LIBSAI) $(PTF) $(DOCKER_SYNCD_INVM_RPC)_LOAD_DOCKERS += $(DOCKER_SYNCD_BASE) SONIC_DOCKER_IMAGES += $(DOCKER_SYNCD_INVM_RPC) ifeq ($(ENABLE_SYNCD_RPC),y) diff --git a/platform/marvell-arm64/docker-syncd-mrvl-rpc.mk b/platform/marvell-arm64/docker-syncd-mrvl-rpc.mk index 0e1b65f2fd5d..c3ce6c10119c 100644 --- a/platform/marvell-arm64/docker-syncd-mrvl-rpc.mk +++ b/platform/marvell-arm64/docker-syncd-mrvl-rpc.mk @@ -2,7 +2,7 @@ DOCKER_SYNCD_MRVL_RPC = docker-syncd-mrvl-rpc.gz $(DOCKER_SYNCD_MRVL_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-mrvl-rpc -$(DOCKER_SYNCD_MRVL_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) +$(DOCKER_SYNCD_MRVL_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(PTF) $(DOCKER_SYNCD_MRVL_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_MRVL_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ diff --git a/platform/marvell-armhf/docker-syncd-mrvl-rpc.mk b/platform/marvell-armhf/docker-syncd-mrvl-rpc.mk index 0e1b65f2fd5d..c3ce6c10119c 100644 --- a/platform/marvell-armhf/docker-syncd-mrvl-rpc.mk +++ b/platform/marvell-armhf/docker-syncd-mrvl-rpc.mk @@ -2,7 +2,7 @@ DOCKER_SYNCD_MRVL_RPC = docker-syncd-mrvl-rpc.gz $(DOCKER_SYNCD_MRVL_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-mrvl-rpc -$(DOCKER_SYNCD_MRVL_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) +$(DOCKER_SYNCD_MRVL_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(PTF) $(DOCKER_SYNCD_MRVL_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_MRVL_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ diff --git a/platform/marvell/docker-syncd-mrvl-rpc.mk b/platform/marvell/docker-syncd-mrvl-rpc.mk index 5b1968bde39c..92d616fa2cab 100644 --- a/platform/marvell/docker-syncd-mrvl-rpc.mk +++ b/platform/marvell/docker-syncd-mrvl-rpc.mk @@ -2,7 +2,7 @@ DOCKER_SYNCD_MRVL_RPC = docker-syncd-mrvl-rpc.gz $(DOCKER_SYNCD_MRVL_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-mrvl-rpc -$(DOCKER_SYNCD_MRVL_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) +$(DOCKER_SYNCD_MRVL_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(PTF) $(DOCKER_SYNCD_MRVL_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_MRVL_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ diff --git a/platform/mellanox/docker-syncd-mlnx-rpc.mk b/platform/mellanox/docker-syncd-mlnx-rpc.mk index ed9eea9ae8f8..ef2aec3333ac 100644 --- a/platform/mellanox/docker-syncd-mlnx-rpc.mk +++ b/platform/mellanox/docker-syncd-mlnx-rpc.mk @@ -2,7 +2,7 @@ DOCKER_SYNCD_MLNX_RPC = docker-syncd-mlnx-rpc.gz $(DOCKER_SYNCD_MLNX_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-mlnx-rpc -$(DOCKER_SYNCD_MLNX_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) +$(DOCKER_SYNCD_MLNX_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(PTF) $(DOCKER_SYNCD_MLNX_RPC)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_MLNX_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ diff --git a/platform/nephos/docker-syncd-nephos-rpc.mk b/platform/nephos/docker-syncd-nephos-rpc.mk index dafc43b3e7e3..39240c1913e4 100644 --- a/platform/nephos/docker-syncd-nephos-rpc.mk +++ b/platform/nephos/docker-syncd-nephos-rpc.mk @@ -2,7 +2,7 @@ DOCKER_SYNCD_NEPHOS_RPC = docker-syncd-nephos-rpc.gz $(DOCKER_SYNCD_NEPHOS_RPC)_PATH = $(PLATFORM_PATH)/docker-syncd-nephos-rpc -$(DOCKER_SYNCD_NEPHOS_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) +$(DOCKER_SYNCD_NEPHOS_RPC)_DEPENDS += $(SYNCD_RPC) $(LIBTHRIFT) $(PTF) ifeq ($(INSTALL_DEBUG_TOOLS), y) $(DOCKER_SYNCD_NEPHOS_RPC)_DEPENDS += $(SYNCD_RPC_DBG) \ $(LIBSWSSCOMMON_DBG) \ From d97051d7fe4647e312b0d5cde7981f27cd83fe72 Mon Sep 17 00:00:00 2001 From: Partha Dutta <51353699+dutta-partha@users.noreply.github.com> Date: Fri, 14 Feb 2020 03:17:16 +0530 Subject: [PATCH 114/178] [mgmt-framework]: Removing explicit libyang plugin path settings (#4144) Removing explicit libyang plugin path settings. Libyang debian package installs the extensions in standard location. Libyang debian package installs the extensions in standard location as per build time configuration (install prefix is set in patch/libyang.patch). If plugin directory is not set, libyang explicitly searches the plugins in LYEXT_PLUGINS_DIR which is populated during build. The plugins are installed in LYEXT_PLUGINS_DIR itself through debian package installation. $ grep -nr LYEXT_PLUGINS_DIR src/ src/plugin_config.h.in:18:#define LYEXT_PLUGINS_DIR "@EXTENSIONS_PLUGINS_DIR_MACRO@" /**< directory with YANG extension plugins */ src/plugins.c:420: pluginsdir = LYEXT_PLUGINS_DIR; --- dockers/docker-sonic-mgmt-framework/rest-server.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/dockers/docker-sonic-mgmt-framework/rest-server.sh b/dockers/docker-sonic-mgmt-framework/rest-server.sh index f2a29c9b1ed2..e450f707dfd1 100755 --- a/dockers/docker-sonic-mgmt-framework/rest-server.sh +++ b/dockers/docker-sonic-mgmt-framework/rest-server.sh @@ -46,7 +46,5 @@ echo "REST_SERVER_ARGS = $REST_SERVER_ARGS" export CVL_SCHEMA_PATH=/usr/sbin/schema -export LIBYANG_EXTENSIONS_PLUGINS_DIR=/usr/lib/x86_64-linux-gnu/libyang/extensions -export LIBYANG_USER_TYPES_PLUGINS_DIR=/usr/lib/x86_64-linux-gnu/libyang/user_types exec /usr/sbin/rest_server ${REST_SERVER_ARGS} From 7c1220eabd968f2e19941d9d08a3b21c58ec338f Mon Sep 17 00:00:00 2001 From: Mykola F <37578614+mykolaf@users.noreply.github.com> Date: Sat, 21 Mar 2020 23:20:48 +0200 Subject: [PATCH 115/178] [Mellanox] update hw-mgmt patch (#4288) Master and 201911 use the same version of hw-mgmt 2f65914 , but the hw-mgmt patch was cherry-picked to 201911 badly, the file contents have some diff, and it does not apply on 201911 Signed-off-by: Mykola Faryma --- .../0001-Make-hw-mgmt-SimX-compatiable.patch | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/platform/mellanox/hw-management/0001-Make-hw-mgmt-SimX-compatiable.patch b/platform/mellanox/hw-management/0001-Make-hw-mgmt-SimX-compatiable.patch index ff792af02beb..a72c94473e88 100644 --- a/platform/mellanox/hw-management/0001-Make-hw-mgmt-SimX-compatiable.patch +++ b/platform/mellanox/hw-management/0001-Make-hw-mgmt-SimX-compatiable.patch @@ -1,4 +1,4 @@ -From 6aecc8fed8cc78c1fb5c6b52bdfa3d07ca66e652 Mon Sep 17 00:00:00 2001 +From ebb17bd1f6996f73cb67313846a63c789e74c4f4 Mon Sep 17 00:00:00 2001 From: Mykola Faryma Date: Fri, 21 Feb 2020 12:28:54 +0200 Subject: [PATCH 1/1] Make hw-mgmt SimX compatiable @@ -9,35 +9,35 @@ Signed-off-by: Mykola Faryma 1 file changed, 29 insertions(+) diff --git a/usr/usr/bin/hw-management.sh b/usr/usr/bin/hw-management.sh -index cff10fe..7f3c295 100755 +index 1b5b18a..3dfd4b1 100755 --- a/usr/usr/bin/hw-management.sh +++ b/usr/usr/bin/hw-management.sh -@@ -646,6 +646,35 @@ do_chip_down() +@@ -943,6 +943,35 @@ do_chip_down() /usr/bin/hw-management-thermal-events.sh change hotplug_asic down %S %p } +handle_simx() +{ -+ local -r onie_platform="$(cat /host/machine.conf | grep onie_platform | cut -d= -f2)" ++ local -r onie_platform="$(cat /host/machine.conf | grep onie_platform | cut -d= -f2)" + -+ local -r syseeprom_cache_path="/var/cache/sonic/decode-syseeprom/syseeprom_cache" -+ local -r syseeprom_hex_path="/usr/share/sonic/device/${onie_platform}/syseeprom.hex" -+ local -r syseeprom_vpd_path="/var/run/hw-management/eeprom/vpd_info" ++ local -r syseeprom_cache_path="/var/cache/sonic/decode-syseeprom/syseeprom_cache" ++ local -r syseeprom_hex_path="/usr/share/sonic/device/${onie_platform}/syseeprom.hex" ++ local -r syseeprom_vpd_path="/var/run/hw-management/eeprom/vpd_info" + -+ case $ACTION in -+ start) -+ /bin/bash -c "/bin/rm -f ${syseeprom_cache_path}" -+ /bin/bash -c "/bin/mkdir -p ${eeprom_path}" -+ /bin/bash -c "/usr/bin/xxd -r -p ${syseeprom_hex_path} ${syseeprom_vpd_path}" -+ ;; -+ stop) -+ /bin/bash -c "/bin/rm -fr ${hw_management_path}" -+ ;; -+ *) -+ echo "Usage: `basename $0` {start|stop}" -+ exit 1 -+ ;; -+ esac ++ case $ACTION in ++ start) ++ /bin/bash -c "/bin/rm -f ${syseeprom_cache_path}" ++ /bin/bash -c "/bin/mkdir -p ${eeprom_path}" ++ /bin/bash -c "/usr/bin/xxd -r -p ${syseeprom_hex_path} ${syseeprom_vpd_path}" ++ ;; ++ stop) ++ /bin/bash -c "/bin/rm -fr ${hw_management_path}" ++ ;; ++ *) ++ echo "Usage: `basename $0` {start|stop}" ++ exit 1 ++ ;; ++ esac +} + +if [[ "$(cat /sys/devices/virtual/dmi/id/sys_vendor)" = "QEMU" ]]; then @@ -47,7 +47,7 @@ index cff10fe..7f3c295 100755 + case $ACTION in start) - do_start + if [ -d /var/run/hw-management ]; then -- 1.9.1 From de2afc494702977a72affdfe49343c726214a24d Mon Sep 17 00:00:00 2001 From: Renuka Manavalan <47282725+renukamanavalan@users.noreply.github.com> Date: Fri, 20 Mar 2020 18:08:46 -0700 Subject: [PATCH 116/178] [mgmt-framework]: Update submodule to take build break fix. (#4302) Brief: The community code for has been updated, which mismatched with the existing sonic-mgmt-framework. Hence it broke the build. Submodule-PR: #43 Details: The SONiC mgmt Framework, pulls down the community modules in two steps. Pull the existing; This does a transparent compile too. Then checkout the specific commit-id for each and do the final compile. The community code change broke in the compilation phase of step-1. Fix: For the two affected modules, do download only. Proper fix: As part of the next phase of changes, the mgmt-framework is moving go-submodule mode, which will ensure the download happens for the assigned commit-ids only. e.g. Refer go.mod in sonic-telemetry --- src/sonic-mgmt-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-mgmt-framework b/src/sonic-mgmt-framework index a4f1650d505c..3b177823d406 160000 --- a/src/sonic-mgmt-framework +++ b/src/sonic-mgmt-framework @@ -1 +1 @@ -Subproject commit a4f1650d505c14d94872bd216f218e7c752de05c +Subproject commit 3b177823d406f8ff188a9770ff0f34f4820c75fc From 358570324bd841bbcc009835bee768f637c39190 Mon Sep 17 00:00:00 2001 From: yozhao101 <56170650+yozhao101@users.noreply.github.com> Date: Thu, 19 Mar 2020 14:14:47 -0700 Subject: [PATCH 117/178] [Monit] Delay start of monitoring for 5 minutes (#4281) --- files/image_config/monit/monitrc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/files/image_config/monit/monitrc b/files/image_config/monit/monitrc index 3c3714882dcc..74068f12d3f8 100644 --- a/files/image_config/monit/monitrc +++ b/files/image_config/monit/monitrc @@ -17,8 +17,9 @@ ## Start Monit in the background (run as a daemon): # set daemon 60 # check services at 1-minute intervals -# with start delay 240 # optional: delay the first check by 4-minutes (by -# # default Monit check immediately after Monit start) + with start delay 300 # we delay Monit to start monitoring for 5 minutes + # intentionally such that all containers and processes + # have ample time to start up. # # ## Set syslog logging. If you want to log to a standalone log file instead, From 384055a314090ae223b8b87b0096607a62e17a29 Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Thu, 19 Mar 2020 08:50:26 -0700 Subject: [PATCH 118/178] [NTP] Revert change in PR 2598 (#4265) We believe that the supervisord issue in face of clock rolling backwards has been addressed. Therefore reverting change 2598 to allow ntp sync to right clock at the start up time. Signed-off-by: Ying Xie --- build_debian.sh | 4 ---- 1 file changed, 4 deletions(-) diff --git a/build_debian.sh b/build_debian.sh index 69b3a10ec881..51154cc073bc 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -317,10 +317,6 @@ fi ## Disable kexec supported reboot which was installed by default sudo sed -i 's/LOAD_KEXEC=true/LOAD_KEXEC=false/' $FILESYSTEM_ROOT/etc/default/kexec -## Modifty ntp default configuration: disable initial jump (add -x), and disable -## jump when time difference is greater than 1000 seconds (remove -g). -sudo sed -i "s/NTPD_OPTS='-g'/NTPD_OPTS='-x'/" $FILESYSTEM_ROOT/etc/default/ntp - ## Remove sshd host keys, and will regenerate on first sshd start sudo rm -f $FILESYSTEM_ROOT/etc/ssh/ssh_host_*_key* sudo cp files/sshd/host-ssh-keygen.sh $FILESYSTEM_ROOT/usr/local/bin/ From 7b4b1245bdc29fd47de8f5f4f5fb2b86eebe3fdf Mon Sep 17 00:00:00 2001 From: SuvarnaMeenakshi <50386592+SuvarnaMeenakshi@users.noreply.github.com> Date: Sat, 21 Mar 2020 18:50:12 -0700 Subject: [PATCH 119/178] [ntp]: Add "tinker panic 0" in ntp.conf to avoid ntpd from panic (#4263) - What I did Add configuration to avoid ntpd from panic and exit if the drift between new time and current system time is large. - How I did it Added "tinker panic 0" in ntp.conf file. - How to verify it [this assumes that there is a valid NTP server IP in config_db/ntp.conf] Change the current system time to a bad time with a large drift from time in ntp server; drift should be greater than 1000s. Reboot the device. Before the fix: 3. upon reboot, ntp-config service comes up fine, ntp service goes to active(exited) state without any error message. This is because the offset between new time (from ntp server) and the current system time is very large, ntpd goes to panic mode and exits. The system continues to show the bad time. After the fix: 3. Upon reboot, ntp-config comes up fine, ntp services comes up from and stays in active (running) state. The system clock gets synced with the ntp server time. --- files/image_config/ntp/ntp.conf.j2 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/files/image_config/ntp/ntp.conf.j2 b/files/image_config/ntp/ntp.conf.j2 index cef6527fc28f..dbde694432e6 100644 --- a/files/image_config/ntp/ntp.conf.j2 +++ b/files/image_config/ntp/ntp.conf.j2 @@ -5,6 +5,10 @@ # /etc/ntp.conf, configuration for ntpd; see ntp.conf(5) for help +# To avoid ntpd from panic and exit if the drift between new time and +# current system time is large. +tinker panic 0 + driftfile /var/lib/ntp/ntp.drift From d793cc8fb0131cdc6493e40a763b82df633f29b4 Mon Sep 17 00:00:00 2001 From: Danny Allen Date: Sun, 15 Mar 2020 13:54:05 -0700 Subject: [PATCH 120/178] [vs] Add dependencies for NAT to docker-sonic-vs (#4259) I added dependencies to support the NAT feature on the virtual switch. Signed-off-by: Danny Allen --- platform/vs/docker-sonic-vs/Dockerfile.j2 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/platform/vs/docker-sonic-vs/Dockerfile.j2 b/platform/vs/docker-sonic-vs/Dockerfile.j2 index 7cc6f98921ff..ee3858aca647 100644 --- a/platform/vs/docker-sonic-vs/Dockerfile.j2 +++ b/platform/vs/docker-sonic-vs/Dockerfile.j2 @@ -51,7 +51,9 @@ RUN apt-get install -y net-tools \ apt-utils \ psmisc \ tcpdump \ - python-scapy + python-scapy \ + conntrack \ + iptables RUN pip install setuptools RUN pip install py2_ipaddress From d0bae822474b846d5328b8b54d1b262742161bea Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Thu, 19 Mar 2020 23:31:25 -0700 Subject: [PATCH 121/178] [minigraph.py] Add support for 'OutAcl' keyword and attaching ACLs to VLAN interfaces (#4229) - Support parsing egress ACLs from minigraph file specified by the "OutAcl" element - Support attaching ACLs to VLAN interfaces --- src/sonic-config-engine/minigraph.py | 15 ++++++++++++--- src/sonic-config-engine/tests/t0-sample-graph.xml | 7 ++++++- src/sonic-config-engine/tests/test_cfggen.py | 15 ++++++++------- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 3ba6362c6ff0..0f2cbfc60522 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -257,7 +257,14 @@ def parse_dpg(dpg, hname): aclintfs = child.find(str(QName(ns, "AclInterfaces"))) acls = {} for aclintf in aclintfs.findall(str(QName(ns, "AclInterface"))): - aclname = aclintf.find(str(QName(ns, "InAcl"))).text.upper().replace(" ", "_").replace("-", "_") + if aclintf.find(str(QName(ns, "InAcl"))) is not None: + aclname = aclintf.find(str(QName(ns, "InAcl"))).text.upper().replace(" ", "_").replace("-", "_") + stage = "ingress" + elif aclintf.find(str(QName(ns, "OutAcl"))) is not None: + aclname = aclintf.find(str(QName(ns, "OutAcl"))).text.upper().replace(" ", "_").replace("-", "_") + stage = "egress" + else: + system.exit("Error: 'AclInterface' must contain either an 'InAcl' or 'OutAcl' subelement.") aclattach = aclintf.find(str(QName(ns, "AttachTo"))).text.split(';') acl_intfs = [] is_mirror = False @@ -274,7 +281,7 @@ def parse_dpg(dpg, hname): # to LAG will be applied to all the LAG members internally by SAI/SDK acl_intfs.append(member) elif vlans.has_key(member): - print >> sys.stderr, "Warning: ACL " + aclname + " is attached to a Vlan interface, which is currently not supported" + acl_intfs.append(member) elif port_alias_map.has_key(member): acl_intfs.append(port_alias_map[member]) # Give a warning if trying to attach ACL to a LAG member interface, correct way is to attach ACL to the LAG interface @@ -297,13 +304,14 @@ def parse_dpg(dpg, hname): break if acl_intfs: acls[aclname] = {'policy_desc': aclname, + 'stage': stage, 'ports': acl_intfs} if is_mirror: acls[aclname]['type'] = 'MIRROR' elif is_mirror_v6: acls[aclname]['type'] = 'MIRRORV6' else: - acls[aclname]['type'] = 'L3' + acls[aclname]['type'] = 'L3V6' if 'v6' in aclname.lower() else 'L3' else: # This ACL has no interfaces to attach to -- consider this a control plane ACL try: @@ -321,6 +329,7 @@ def parse_dpg(dpg, hname): else: acls[aclname] = {'policy_desc': aclname, 'type': 'CTRLPLANE', + 'stage': stage, 'services': [aclservice]} except: print >> sys.stderr, "Warning: Ignoring Control Plane ACL %s without type" % aclname diff --git a/src/sonic-config-engine/tests/t0-sample-graph.xml b/src/sonic-config-engine/tests/t0-sample-graph.xml index 0c641107da06..47985f870e50 100644 --- a/src/sonic-config-engine/tests/t0-sample-graph.xml +++ b/src/sonic-config-engine/tests/t0-sample-graph.xml @@ -305,7 +305,12 @@ PortChannel01;PortChannel02;PortChannel03;PortChannel04 - DataAcl + DataAclIngress + DataPlane + + + PortChannel01;PortChannel02 + DataAclEgress DataPlane diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index 8288b729584c..2ae28946a905 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -104,13 +104,14 @@ def test_minigraph_acl(self): self.assertEqual(output.strip(), "Warning: Ignoring Control Plane ACL NTP_ACL without type\n" "Warning: ignore interface 'fortyGigE0/2' as it is not in the port_config.ini\n" "Warning: ignore interface 'fortyGigE0/2' in DEVICE_NEIGHBOR as it is not in the port_config.ini\n" - "{'DATAACL': {'type': 'L3', 'policy_desc': 'DATAACL', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04']}, " - "'NTP_ACL': {'services': ['NTP'], 'type': 'CTRLPLANE', 'policy_desc': 'NTP_ACL'}, " - "'EVERFLOW': {'type': 'MIRROR', 'policy_desc': 'EVERFLOW', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4']}, " - "'ROUTER_PROTECT': {'services': ['SSH', 'SNMP'], 'type': 'CTRLPLANE', 'policy_desc': 'ROUTER_PROTECT'}, " - "'SNMP_ACL': {'services': ['SNMP'], 'type': 'CTRLPLANE', 'policy_desc': 'SNMP_ACL'}, " - "'SSH_ACL': {'services': ['SSH'], 'type': 'CTRLPLANE', 'policy_desc': 'SSH_ACL'}, " - "'EVERFLOWV6': {'type': 'MIRRORV6', 'policy_desc': 'EVERFLOWV6', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4']}}") + "{'NTP_ACL': {'services': ['NTP'], 'type': 'CTRLPLANE', 'policy_desc': 'NTP_ACL', 'stage': 'ingress'}, " + "'EVERFLOW': {'stage': 'ingress', 'type': 'MIRROR', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4'], 'policy_desc': 'EVERFLOW'}, " + "'ROUTER_PROTECT': {'services': ['SSH', 'SNMP'], 'type': 'CTRLPLANE', 'policy_desc': 'ROUTER_PROTECT', 'stage': 'ingress'}, " + "'DATAACLINGRESS': {'stage': 'ingress', 'type': 'L3', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04'], 'policy_desc': 'DATAACLINGRESS'}, " + "'SNMP_ACL': {'services': ['SNMP'], 'type': 'CTRLPLANE', 'policy_desc': 'SNMP_ACL', 'stage': 'ingress'}, " + "'SSH_ACL': {'services': ['SSH'], 'type': 'CTRLPLANE', 'policy_desc': 'SSH_ACL', 'stage': 'ingress'}, " + "'DATAACLEGRESS': {'stage': 'egress', 'type': 'L3', 'ports': ['PortChannel01', 'PortChannel02'], 'policy_desc': 'DATAACLEGRESS'}, " + "'EVERFLOWV6': {'stage': 'ingress', 'type': 'MIRRORV6', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4'], 'policy_desc': 'EVERFLOWV6'}}") # everflow portion is not used # def test_minigraph_everflow(self): From fcb5b41e3346ea12aa0cdb74248babf088e9d9d7 Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Tue, 17 Mar 2020 10:14:59 -0700 Subject: [PATCH 122/178] [arista] Update platform drivers submodules (#4200) * Build Arista drivers using DPKG_DEB * Update arista platform submodule --- platform/barefoot/platform-modules-arista.mk | 2 +- platform/broadcom/platform-modules-arista.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/barefoot/platform-modules-arista.mk b/platform/barefoot/platform-modules-arista.mk index 480aa0cf8396..28c893b80713 100644 --- a/platform/barefoot/platform-modules-arista.mk +++ b/platform/barefoot/platform-modules-arista.mk @@ -7,7 +7,7 @@ export ARISTA_PLATFORM_MODULE_VERSION ARISTA_PLATFORM_MODULE = sonic-platform-arista_$(ARISTA_PLATFORM_MODULE_VERSION)_amd64.deb $(ARISTA_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-arista $(ARISTA_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) -SONIC_MAKE_DEBS += $(ARISTA_PLATFORM_MODULE) +SONIC_DPKG_DEBS += $(ARISTA_PLATFORM_MODULE) ARISTA_PLATFORM_MODULE_PYTHON2 = python-sonic-platform-arista_$(ARISTA_PLATFORM_MODULE_VERSION)_all.deb $(eval $(call add_extra_package,$(ARISTA_PLATFORM_MODULE),$(ARISTA_PLATFORM_MODULE_PYTHON2))) diff --git a/platform/broadcom/platform-modules-arista.mk b/platform/broadcom/platform-modules-arista.mk index 480aa0cf8396..28c893b80713 100644 --- a/platform/broadcom/platform-modules-arista.mk +++ b/platform/broadcom/platform-modules-arista.mk @@ -7,7 +7,7 @@ export ARISTA_PLATFORM_MODULE_VERSION ARISTA_PLATFORM_MODULE = sonic-platform-arista_$(ARISTA_PLATFORM_MODULE_VERSION)_amd64.deb $(ARISTA_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-arista $(ARISTA_PLATFORM_MODULE)_DEPENDS += $(LINUX_HEADERS) $(LINUX_HEADERS_COMMON) -SONIC_MAKE_DEBS += $(ARISTA_PLATFORM_MODULE) +SONIC_DPKG_DEBS += $(ARISTA_PLATFORM_MODULE) ARISTA_PLATFORM_MODULE_PYTHON2 = python-sonic-platform-arista_$(ARISTA_PLATFORM_MODULE_VERSION)_all.deb $(eval $(call add_extra_package,$(ARISTA_PLATFORM_MODULE),$(ARISTA_PLATFORM_MODULE_PYTHON2))) From ee84dca683de81534233829bfcdbe523b5bc120f Mon Sep 17 00:00:00 2001 From: Stepan Blyshchak <38952541+stepanblyschak@users.noreply.github.com> Date: Wed, 26 Feb 2020 10:56:54 +0200 Subject: [PATCH 123/178] [docker_image_ctl.j2] Share UTS namespace with host OS (#4169) Instead of updating hostname manualy on Config DB hostname change, simply share containers UTS namespace with host OS. Ideally, instead of setting `--uts=host` for every container in SONiC, this setting can be set per container if feature requires. One behaviour change is introduced in this commit, when `--privileged` or `--cap-add=CAP_SYS_ADMIN` and `--uts=host` are combined, container has privilege to change host OS and every other container hostname. Such privilege should be fixed by limiting containers capabilities. Signed-off-by: Stepan Blyschak --- files/build_templates/docker_image_ctl.j2 | 48 ++------------------- files/image_config/hostcfgd/hostcfgd | 51 +---------------------- 2 files changed, 5 insertions(+), 94 deletions(-) diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index a15546a1e59e..5de892555a1b 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -1,7 +1,7 @@ #!/bin/bash # single instance containers are still supported (even though it might not look like it) -# if no instance number is passed to this script, $DEV will simply be unset, resulting in docker +# if no instance number is passed to this script, $DEV will simply be unset, resulting in docker # commands being sent to the base container name. E.g. `docker start database$DEV` simply starts # the container `database` if no instance number is passed since `$DEV` is not defined @@ -31,32 +31,6 @@ function getMountPoint() echo $1 | python -c "import sys, json, os; mnts = [x for x in json.load(sys.stdin)[0]['Mounts'] if x['Destination'] == '/usr/share/sonic/hwsku']; print '' if len(mnts) == 0 else os.path.basename(mnts[0]['Source'])" 2>/dev/null } -function updateHostName() -{ - HOSTS=/etc/hosts - HOSTS_TMP=/etc/hosts.tmp - - EXEC="docker exec -i {{docker_container_name}}$DEV bash -c" - - NEW_HOSTNAME="$1" - HOSTNAME=`$EXEC "hostname"` - if ! [[ $HOSTNAME =~ ^[a-zA-Z0-9.\-]*$ ]]; then - HOSTNAME=`hostname` - fi - - # copy HOSTS to HOSTS_TMP - $EXEC "cp $HOSTS $HOSTS_TMP" - # remove entry with hostname - $EXEC "sed -i \"/$HOSTNAME$/d\" $HOSTS_TMP" - # add entry with new hostname - $EXEC "echo -e \"127.0.0.1\t$NEW_HOSTNAME\" >> $HOSTS_TMP" - - echo "Set hostname in {{docker_container_name}}$DEV container" - $EXEC "hostname '$NEW_HOSTNAME'" - $EXEC "cat $HOSTS_TMP > $HOSTS" - $EXEC "rm -f $HOSTS_TMP" -} - function getBootType() { # same code snippet in files/scripts/syncd.sh @@ -165,11 +139,7 @@ start() { {%- else %} # Obtain our HWSKU as we will mount directories with these names in each docker HWSKU=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hwsku"]'` - HOSTNAME=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hostname"]'` {%- endif %} - if [ -z "$HOSTNAME" ] || ! [[ $HOSTNAME =~ ^[a-zA-Z0-9.\-]*$ ]]; then - HOSTNAME=`hostname` - fi DOCKERCHECK=`docker inspect --type container {{docker_container_name}}$DEV 2>/dev/null` if [ "$?" -eq "0" ]; then @@ -187,11 +157,6 @@ start() { preStartAction docker start {{docker_container_name}}$DEV postStartAction - CURRENT_HOSTNAME="$(docker exec {{docker_container_name}}$DEV hostname)" - if [ x"$HOSTNAME" != x"$CURRENT_HOSTNAME" ]; then - updateHostName "$HOSTNAME" - fi - updateHostName "$HOSTNAME" exit $? fi @@ -214,7 +179,7 @@ start() { if [ -z "$DEV" ]; then NET="host" else - {%- if docker_container_name == "database" %} + {%- if docker_container_name == "database" %} NET="bridge" {%- else %} NET="container:database$DEV" @@ -226,6 +191,7 @@ start() { {%- endif %} docker create {{docker_image_run_opt}} \ --net=$NET \ + --uts=host \{# W/A: this should be set per-docker, for those dockers which really need host's UTS namespace #} {%- if install_debug_image == "y" %} -v /src:/src:ro -v /debug:/debug:rw \ {%- endif %} @@ -266,7 +232,6 @@ start() { preStartAction docker start {{docker_container_name}} postStartAction - updateHostName "$HOSTNAME" } wait() { @@ -288,13 +253,8 @@ case "$1" in start|wait|stop) $1 ;; - updateHostName) - cmd=$1 - shift 2 - $cmd $@ - ;; *) - echo "Usage: $0 {start namespace(optional)|wait namespace(optional)|stop namespace(optional)|updateHostName namespace(optional) new_hostname}" + echo "Usage: $0 {start namespace(optional)|wait namespace(optional)|stop namespace(optional)}" exit 1 ;; esac diff --git a/files/image_config/hostcfgd/hostcfgd b/files/image_config/hostcfgd/hostcfgd index e10288c0dd37..4ac3be83d06e 100755 --- a/files/image_config/hostcfgd/hostcfgd +++ b/files/image_config/hostcfgd/hostcfgd @@ -2,7 +2,6 @@ # -*- coding: utf-8 -*- import os -import re import sys import subprocess import syslog @@ -24,13 +23,6 @@ TACPLUS_SERVER_TIMEOUT_DEFAULT = "5" TACPLUS_SERVER_AUTH_TYPE_DEFAULT = "pap" -def is_valid_hostname(hostname): - if hostname[-1] == "." or len(hostname) > 253: - return False - allowed = re.compile("(?!-)[A-Z\d-]{1,63}(? Date: Tue, 24 Mar 2020 15:04:59 +0800 Subject: [PATCH 124/178] [platform/nephos] Upgrade nephos-modules from 1.0.0 to 1.0.1 (#4267) (#4297) --- platform/nephos/nephos-modules.mk | 2 +- .../nephos/nephos-modules/debian/changelog | 8 +- platform/nephos/nephos-modules/debian/control | 2 +- ...-4.9.0-9-2-amd64 => nps-modules-4.9-amd64} | 0 ....service => nps-modules-4.9-amd64.service} | 4 +- .../modules/src/hal_tau_pkt_knl.c | 808 +++++++++++------ .../nephos-modules/modules/src/inc/aml.h | 2 +- .../nephos-modules/modules/src/inc/hal_dev.h | 2 +- .../modules/src/inc/hal_tau_pkt_knl.h | 273 +++--- .../nephos-modules/modules/src/inc/netif_nl.h | 104 +++ .../modules/src/inc/netif_osal.h | 2 +- .../modules/src/inc/netif_perf.h | 2 +- .../nephos-modules/modules/src/inc/nps_cfg.h | 2 +- .../modules/src/inc/nps_error.h | 2 +- .../modules/src/inc/nps_types.h | 2 +- .../nephos-modules/modules/src/inc/osal_mdc.h | 12 +- .../modules/src/inc/osal_types.h | 2 +- .../nephos/nephos-modules/modules/src/make.mk | 4 +- .../nephos-modules/modules/src/netif_nl.c | 811 ++++++++++++++++++ .../nephos-modules/modules/src/netif_osal.c | 2 +- .../nephos-modules/modules/src/netif_perf.c | 2 +- .../nephos-modules/modules/src/osal_isymbol.c | 2 +- .../nephos-modules/modules/src/osal_mdc.c | 171 +++- 23 files changed, 1821 insertions(+), 400 deletions(-) rename platform/nephos/nephos-modules/modules/init.d/{nps-modules-4.9.0-9-2-amd64 => nps-modules-4.9-amd64} (100%) rename platform/nephos/nephos-modules/modules/service/{nps-modules-4.9.0-9-2-amd64.service => nps-modules-4.9-amd64.service} (60%) create mode 100755 platform/nephos/nephos-modules/modules/src/inc/netif_nl.h create mode 100755 platform/nephos/nephos-modules/modules/src/netif_nl.c diff --git a/platform/nephos/nephos-modules.mk b/platform/nephos/nephos-modules.mk index ebd696217b8e..50a2d0e5c080 100644 --- a/platform/nephos/nephos-modules.mk +++ b/platform/nephos/nephos-modules.mk @@ -1,6 +1,6 @@ # Nephos Platform modules -VERSION = 1.0.0 +VERSION = 1.0.1 ifneq ($(NEPHOS_SAI_DEB_LOCAL_URL), ) SDK_FROM_LOCAL = y diff --git a/platform/nephos/nephos-modules/debian/changelog b/platform/nephos/nephos-modules/debian/changelog index 3de2bd045efd..94c7aa7d3915 100644 --- a/platform/nephos/nephos-modules/debian/changelog +++ b/platform/nephos/nephos-modules/debian/changelog @@ -1,5 +1,11 @@ +nephos-modules (1.0.1) unstable; urgency=low + + * Upgrade ko version to 3.0.0 + +-- Support Tue, 17 Mar 2020 15:54:00 +0800 + nephos-modules (1.0.0) unstable; urgency=low * Initial release - -- Support Fri, 15 Mar 2019 15:54:00 +0800 +-- Support Fri, 15 Mar 2019 15:54:00 +0800 diff --git a/platform/nephos/nephos-modules/debian/control b/platform/nephos/nephos-modules/debian/control index 246b89eab477..3d06ca971f89 100644 --- a/platform/nephos/nephos-modules/debian/control +++ b/platform/nephos/nephos-modules/debian/control @@ -1,7 +1,7 @@ Source: nephos-modules Section: main Priority: extra -Maintainer: support +Maintainer: support Build-Depends: debhelper (>= 8.0.0), bzip2 Standards-Version: 3.9.3 diff --git a/platform/nephos/nephos-modules/modules/init.d/nps-modules-4.9.0-9-2-amd64 b/platform/nephos/nephos-modules/modules/init.d/nps-modules-4.9-amd64 similarity index 100% rename from platform/nephos/nephos-modules/modules/init.d/nps-modules-4.9.0-9-2-amd64 rename to platform/nephos/nephos-modules/modules/init.d/nps-modules-4.9-amd64 diff --git a/platform/nephos/nephos-modules/modules/service/nps-modules-4.9.0-9-2-amd64.service b/platform/nephos/nephos-modules/modules/service/nps-modules-4.9-amd64.service similarity index 60% rename from platform/nephos/nephos-modules/modules/service/nps-modules-4.9.0-9-2-amd64.service rename to platform/nephos/nephos-modules/modules/service/nps-modules-4.9-amd64.service index 9acdeb30a44c..fc45a597d74c 100644 --- a/platform/nephos/nephos-modules/modules/service/nps-modules-4.9.0-9-2-amd64.service +++ b/platform/nephos/nephos-modules/modules/service/nps-modules-4.9-amd64.service @@ -5,8 +5,8 @@ Before=syncd.service [Service] Type=oneshot -ExecStart=-/etc/init.d/nps-modules-4.9.0-11-2-amd64 start -ExecStop=-/etc/init.d/nps-modules-4.9.0-11-2-amd64 stop +ExecStart=-/etc/init.d/nps-modules-4.9-amd64 start +ExecStop=-/etc/init.d/nps-modules-4.9-amd64 stop RemainAfterExit=yes [Install] diff --git a/platform/nephos/nephos-modules/modules/src/hal_tau_pkt_knl.c b/platform/nephos/nephos-modules/modules/src/hal_tau_pkt_knl.c index b386da63e247..a67b1d5f8868 100755 --- a/platform/nephos/nephos-modules/modules/src/hal_tau_pkt_knl.c +++ b/platform/nephos/nephos-modules/modules/src/hal_tau_pkt_knl.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public @@ -45,6 +45,9 @@ /* netif */ #include #include +#if defined(NETIF_EN_NETLINK) +#include +#endif #include /* nps_sdk */ @@ -69,19 +72,20 @@ /* This flag value will be specified when user inserts kernel module. */ -#define HAL_TAU_PKT_DBG_ERR (0x1 << 0) -#define HAL_TAU_PKT_DBG_TX (0x1 << 1) -#define HAL_TAU_PKT_DBG_RX (0x1 << 2) -#define HAL_TAU_PKT_DBG_INTF (0x1 << 3) -#define HAL_TAU_PKT_DBG_PROFILE (0x1 << 4) -#define HAL_TAU_PKT_DBG_COMMON (0x1 << 5) +#define HAL_TAU_PKT_DBG_ERR (0x1UL << 0) +#define HAL_TAU_PKT_DBG_TX (0x1UL << 1) +#define HAL_TAU_PKT_DBG_RX (0x1UL << 2) +#define HAL_TAU_PKT_DBG_INTF (0x1UL << 3) +#define HAL_TAU_PKT_DBG_PROFILE (0x1UL << 4) +#define HAL_TAU_PKT_DBG_COMMON (0x1UL << 5) +#define HAL_TAU_PKT_DBG_NETLINK (0x1UL << 6) /* Will be set when inserting kernel module */ -static UI32_T dbg_flag = 0; +UI32_T ext_dbg_flag = 0; #define HAL_TAU_PKT_DBG(__flag__, ...) do \ { \ - if (0 != ((__flag__) & (dbg_flag))) \ + if (0 != ((__flag__) & (ext_dbg_flag))) \ { \ osal_printf(__VA_ARGS__); \ } \ @@ -113,15 +117,15 @@ typedef struct static HAL_TAU_PKT_INTR_VEC_T _hal_tau_pkt_intr_vec[] = { - { /* 0: PDMA_ERR */ 1 << 0, 0x0, 0 }, - { /* 1: TX_CH0 */ 1 << 28, 0x0, 0 }, - { /* 2: TX_CH1 */ 1 << 29, 0x0, 0 }, - { /* 3: TX_CH2 */ 1 << 30, 0x0, 0 }, - { /* 4: TX_CH3 */ 1 << 31, 0x0, 0 }, - { /* 5: RX_CH0 */ 1 << 12, 0x0, 0 }, - { /* 6: RX_CH1 */ 1 << 13, 0x0, 0 }, - { /* 7: RX_CH2 */ 1 << 14, 0x0, 0 }, - { /* 8: RX_CH3 */ 1 << 15, 0x0, 0 }, + { /* 0: PDMA_ERR */ 1UL << 0, 0x0, 0 }, + { /* 1: TX_CH0 */ 1UL << 28, 0x0, 0 }, + { /* 2: TX_CH1 */ 1UL << 29, 0x0, 0 }, + { /* 3: TX_CH2 */ 1UL << 30, 0x0, 0 }, + { /* 4: TX_CH3 */ 1UL << 31, 0x0, 0 }, + { /* 5: RX_CH0 */ 1UL << 12, 0x0, 0 }, + { /* 6: RX_CH1 */ 1UL << 13, 0x0, 0 }, + { /* 7: RX_CH2 */ 1UL << 14, 0x0, 0 }, + { /* 8: RX_CH3 */ 1UL << 15, 0x0, 0 }, }; /***************************************************************************** @@ -136,9 +140,10 @@ static HAL_TAU_PKT_INTR_VEC_T _hal_tau_pkt_intr_vec[] = #define HAL_TAU_PKT_ALLOC_MEM_RETRY_SLEEP() osal_sleepThread(1000) /* us */ /* Network Device Definitions */ -#define HAL_TAU_PKT_TX_TIMEOUT (6*HZ) +/* In case that the watchdog alarm during warm-boot if intf isn't killed */ +#define HAL_TAU_PKT_TX_TIMEOUT (30*HZ) #define HAL_TAU_PKT_MAX_ETH_FRAME_SIZE (HAL_TAU_PKT_RX_MAX_LEN) -#define HAL_TAU_PKT_MAX_PORT_NUM (HAL_TAU_PORT_NUM + 1) /* CPU port */ +#define HAL_TAU_PKT_MAX_PORT_NUM (HAL_PORT_NUM + 1) /* CPU port */ #define HAL_TAU_PKT_NET_PROFILE_NUM_MAX (256) @@ -199,10 +204,10 @@ typedef struct NPS_ISRLOCK_ID_T intr_lock; UI32_T intr_bitmap; -#define HAL_TAU_PKT_INIT_DRV (1 << 0) -#define HAL_TAU_PKT_INIT_TASK (1 << 1) -#define HAL_TAU_PKT_INIT_INTR (1 << 2) -#define HAL_TAU_PKT_INIT_RX_START (1 << 3) +#define HAL_TAU_PKT_INIT_DRV (1UL << 0) +#define HAL_TAU_PKT_INIT_TASK (1UL << 1) +#define HAL_TAU_PKT_INIT_INTR (1UL << 2) +#define HAL_TAU_PKT_INIT_RX_START (1UL << 3) /* a bitmap to record the init status */ UI32_T init_flag; @@ -255,6 +260,10 @@ typedef struct BOOL_T running; /* TRUE when Init txTask * FALSE when Destroy txTask */ + /* to block net intf Tx in driver level since netif_tx_disable() + * cannot always prevent intf from Tx in time + */ + BOOL_T net_tx_allowed; } HAL_TAU_PKT_TX_CB_T; @@ -312,6 +321,9 @@ typedef enum { HAL_TAU_PKT_DEST_NETDEV = 0, HAL_TAU_PKT_DEST_SDK, +#if defined(NETIF_EN_NETLINK) + HAL_TAU_PKT_DEST_NETLINK, +#endif HAL_TAU_PKT_DEST_DROP, HAL_TAU_PKT_DEST_LAST } HAL_TAU_PKT_DEST_T; @@ -1215,7 +1227,158 @@ hal_tau_pkt_setPortAttr( return (NPS_E_OK); } +static void +_hal_tau_pkt_lockRxChannelAll( + const UI32_T unit) +{ + UI32_T rch; + HAL_TAU_PKT_RX_PDMA_T *ptr_rx_pdma; + + for (rch = 0; rch < HAL_TAU_PKT_RX_CHANNEL_LAST; rch++) + { + ptr_rx_pdma = HAL_TAU_PKT_GET_RX_PDMA_PTR(unit, rch); + osal_takeSemaphore(&ptr_rx_pdma->sema, NPS_SEMAPHORE_WAIT_FOREVER); + } +} + +static void +_hal_tau_pkt_unlockRxChannelAll( + const UI32_T unit) +{ + UI32_T rch; + HAL_TAU_PKT_RX_PDMA_T *ptr_rx_pdma; + + for (rch = 0; rch < HAL_TAU_PKT_RX_CHANNEL_LAST; rch++) + { + ptr_rx_pdma = HAL_TAU_PKT_GET_RX_PDMA_PTR(unit, rch); + osal_giveSemaphore(&ptr_rx_pdma->sema); + } +} + +#if defined(NETIF_EN_NETLINK) + +static NPS_ERROR_NO_T +_hal_tau_pkt_setIntfProperty( + const UI32_T unit, + HAL_TAU_PKT_NL_IOCTL_COOKIE_T *ptr_cookie) +{ + UI32_T intf_id; + NETIF_NL_INTF_PROPERTY_T property; + UI32_T param0; + UI32_T param1; + NPS_ERROR_NO_T rc; + + osal_io_copyFromUser(&intf_id, &ptr_cookie->intf_id, sizeof(UI32_T)); + osal_io_copyFromUser(&property, &ptr_cookie->property, sizeof(NETIF_NL_INTF_PROPERTY_T)); + osal_io_copyFromUser(¶m0, &ptr_cookie->param0, sizeof(UI32_T)); + osal_io_copyFromUser(¶m1, &ptr_cookie->param1, sizeof(UI32_T)); + + _hal_tau_pkt_lockRxChannelAll(unit); + + rc = netif_nl_setIntfProperty(unit, intf_id, property, param0, param1); + + _hal_tau_pkt_unlockRxChannelAll(unit); + + osal_io_copyToUser(&ptr_cookie->rc, &rc, sizeof(NPS_ERROR_NO_T)); + + return (rc); +} + +static NPS_ERROR_NO_T +_hal_tau_pkt_getIntfProperty( + const UI32_T unit, + HAL_TAU_PKT_NL_IOCTL_COOKIE_T *ptr_cookie) +{ + UI32_T intf_id; + NETIF_NL_INTF_PROPERTY_T property; + UI32_T param0; + UI32_T param1; + NPS_ERROR_NO_T rc; + + osal_io_copyFromUser(&intf_id, &ptr_cookie->intf_id, sizeof(UI32_T)); + osal_io_copyFromUser(&property, &ptr_cookie->property, sizeof(NETIF_NL_INTF_PROPERTY_T)); + osal_io_copyFromUser(¶m0, &ptr_cookie->param0, sizeof(UI32_T)); + + rc = netif_nl_getIntfProperty(unit, intf_id, property, ¶m0, ¶m1); + + osal_io_copyToUser(&ptr_cookie->param0, ¶m0, sizeof(UI32_T)); + osal_io_copyToUser(&ptr_cookie->param1, ¶m1, sizeof(UI32_T)); + osal_io_copyToUser(&ptr_cookie->rc, &rc, sizeof(NPS_ERROR_NO_T)); + + return (rc); +} + +static NPS_ERROR_NO_T +_hal_tau_pkt_createNetlink( + const UI32_T unit, + HAL_TAU_PKT_NL_IOCTL_COOKIE_T *ptr_cookie) +{ + NETIF_NL_NETLINK_T netlink; + UI32_T netlink_id; + NPS_ERROR_NO_T rc; + + osal_io_copyFromUser(&netlink, &ptr_cookie->netlink, sizeof(NETIF_NL_NETLINK_T)); + + _hal_tau_pkt_lockRxChannelAll(unit); + + rc = netif_nl_createNetlink(unit, &netlink, &netlink_id); + + _hal_tau_pkt_unlockRxChannelAll(unit); + + osal_io_copyToUser(&ptr_cookie->netlink.id, &netlink_id, sizeof(UI32_T)); + osal_io_copyToUser(&ptr_cookie->rc, &rc, sizeof(NPS_ERROR_NO_T)); + + return (rc); +} + +static NPS_ERROR_NO_T +_hal_tau_pkt_destroyNetlink( + const UI32_T unit, + HAL_TAU_PKT_NL_IOCTL_COOKIE_T *ptr_cookie) +{ + UI32_T netlink_id; + NPS_ERROR_NO_T rc; + + osal_io_copyFromUser(&netlink_id, &ptr_cookie->netlink.id, sizeof(UI32_T)); + + _hal_tau_pkt_lockRxChannelAll(unit); + + rc = netif_nl_destroyNetlink(unit, netlink_id); + + _hal_tau_pkt_unlockRxChannelAll(unit); + + osal_io_copyToUser(&ptr_cookie->rc, &rc, sizeof(NPS_ERROR_NO_T)); + + return (rc); +} + +static NPS_ERROR_NO_T +_hal_tau_pkt_getNetlink( + const UI32_T unit, + HAL_TAU_PKT_NL_IOCTL_COOKIE_T *ptr_cookie) +{ + UI32_T id; + NETIF_NL_NETLINK_T netlink; + NPS_ERROR_NO_T rc; + osal_io_copyFromUser(&id, &ptr_cookie->netlink.id, sizeof(UI32_T)); + + rc = netif_nl_getNetlink(unit, id, &netlink); + if (NPS_E_OK == rc) + { + osal_io_copyToUser(&ptr_cookie->netlink, &netlink, sizeof(NETIF_NL_NETLINK_T)); + } + else + { + rc = NPS_E_ENTRY_NOT_FOUND; + } + + osal_io_copyToUser(&ptr_cookie->rc, &rc, sizeof(NPS_ERROR_NO_T)); + + return (NPS_E_OK); +} + +#endif /* ----------------------------------------------------------------------------------- independent func */ /* FUNCTION NAME: _hal_tau_pkt_enQueue * PURPOSE: @@ -1877,7 +2040,7 @@ _hal_tau_pkt_rxCheckReason( HAL_TAU_PKT_NETIF_PROFILE_T *ptr_profile, BOOL_T *ptr_hit_prof) { - HAL_TAU_PKT_RX_REASON_BITMAP_T *ptr_reason_bitmap = &ptr_profile->reason_bitmap; + HAL_PKT_RX_REASON_BITMAP_T *ptr_reason_bitmap = &ptr_profile->reason_bitmap; UI32_T bitval = 0; UI32_T bitmap = 0x0; @@ -1888,10 +2051,10 @@ _hal_tau_pkt_rxCheckReason( return; } -#define HAL_TAU_PKT_DI_NON_L3_CPU_MIN (HAL_TAU_EXCPT_CPU_BASE_ID + HAL_TAU_EXCPT_CPU_NON_L3_MIN) -#define HAL_TAU_PKT_DI_NON_L3_CPU_MAX (HAL_TAU_EXCPT_CPU_BASE_ID + HAL_TAU_EXCPT_CPU_NON_L3_MAX) -#define HAL_TAU_PKT_DI_L3_CPU_MIN (HAL_TAU_EXCPT_CPU_BASE_ID + HAL_TAU_EXCPT_CPU_L3_MIN) -#define HAL_TAU_PKT_DI_L3_CPU_MAX (HAL_TAU_EXCPT_CPU_BASE_ID + HAL_TAU_EXCPT_CPU_L3_MAX) +#define HAL_TAU_PKT_DI_NON_L3_CPU_MIN (HAL_EXCPT_CPU_BASE_ID + HAL_EXCPT_CPU_NON_L3_MIN) +#define HAL_TAU_PKT_DI_NON_L3_CPU_MAX (HAL_EXCPT_CPU_BASE_ID + HAL_EXCPT_CPU_NON_L3_MAX) +#define HAL_TAU_PKT_DI_L3_CPU_MIN (HAL_EXCPT_CPU_BASE_ID + HAL_EXCPT_CPU_L3_MIN) +#define HAL_TAU_PKT_DI_L3_CPU_MAX (HAL_EXCPT_CPU_BASE_ID + HAL_EXCPT_CPU_L3_MAX) switch (ptr_rx_gpd->itmh_eth.typ) { @@ -1902,7 +2065,7 @@ _hal_tau_pkt_rxCheckReason( ptr_rx_gpd->itmh_eth.dst_idx <= HAL_TAU_PKT_DI_NON_L3_CPU_MAX) { bitval = ptr_rx_gpd->itmh_eth.dst_idx - HAL_TAU_PKT_DI_NON_L3_CPU_MIN; - bitmap = 1 << (bitval % 32); + bitmap = 1UL << (bitval % 32); if (0 != (ptr_reason_bitmap->ipp_excpt_bitmap[bitval / 32] & bitmap)) { *ptr_hit_prof = TRUE; @@ -1932,7 +2095,7 @@ _hal_tau_pkt_rxCheckReason( /* IPP cp_to_cpu_rsn */ bitval = ptr_rx_gpd->itmh_eth.cp_to_cpu_code; - bitmap = 1 << (bitval % 32); + bitmap = 1UL << (bitval % 32); if (0 != (ptr_reason_bitmap->ipp_rsn_bitmap[bitval / 32] & bitmap)) { *ptr_hit_prof = TRUE; @@ -1950,7 +2113,7 @@ _hal_tau_pkt_rxCheckReason( if (1 == ptr_rx_gpd->etmh_eth.redir) { bitval = ptr_rx_gpd->etmh_eth.excpt_code_mir_bmap; - bitmap = 1 << (bitval % 32); + bitmap = 1UL << (bitval % 32); if (0 != (ptr_reason_bitmap->epp_excpt_bitmap[bitval / 32] & bitmap)) { *ptr_hit_prof = TRUE; @@ -2059,25 +2222,30 @@ static void _hal_tau_pkt_matchUserProfile( volatile HAL_TAU_PKT_RX_GPD_T *ptr_rx_gpd, HAL_TAU_PKT_PROFILE_NODE_T *ptr_profile_list, - BOOL_T *ptr_hit_prof) + HAL_TAU_PKT_NETIF_PROFILE_T **pptr_profile_hit) { HAL_TAU_PKT_PROFILE_NODE_T *ptr_curr_node = ptr_profile_list; + BOOL_T hit; + + *pptr_profile_hit = NULL; while (NULL != ptr_curr_node) { /* 1st match reason */ - _hal_tau_pkt_rxCheckReason(ptr_rx_gpd, ptr_curr_node->ptr_profile, ptr_hit_prof); - if (TRUE == *ptr_hit_prof) + _hal_tau_pkt_rxCheckReason(ptr_rx_gpd, ptr_curr_node->ptr_profile, &hit); + if (TRUE == hit) { HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_PROFILE, "rx prof matched by reason\n"); /* Then, check pattern */ - _hal_tau_pkt_rxCheckPattern(ptr_rx_gpd, ptr_curr_node->ptr_profile, ptr_hit_prof); - if (TRUE == *ptr_hit_prof) + _hal_tau_pkt_rxCheckPattern(ptr_rx_gpd, ptr_curr_node->ptr_profile, &hit); + if (TRUE == hit) { HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_PROFILE, "rx prof matched by pattern\n"); + + *pptr_profile_hit = ptr_curr_node->ptr_profile; break; } } @@ -2090,19 +2258,34 @@ _hal_tau_pkt_matchUserProfile( static void _hal_tau_pkt_getPacketDest( volatile HAL_TAU_PKT_RX_GPD_T *ptr_rx_gpd, - HAL_TAU_PKT_DEST_T *ptr_dest) + HAL_TAU_PKT_DEST_T *ptr_dest, + void **pptr_cookie) { - BOOL_T hit_prof = FALSE; UI32_T port; HAL_TAU_PKT_PROFILE_NODE_T *ptr_profile_list; + HAL_TAU_PKT_NETIF_PROFILE_T *ptr_profile_hit; port = ptr_rx_gpd->itmh_eth.igr_phy_port; ptr_profile_list = HAL_TAU_PKT_GET_PORT_PROFILE_LIST(port); - _hal_tau_pkt_matchUserProfile(ptr_rx_gpd, ptr_profile_list, &hit_prof); - if (TRUE == hit_prof) + _hal_tau_pkt_matchUserProfile(ptr_rx_gpd, + ptr_profile_list, + &ptr_profile_hit); + if (NULL != ptr_profile_hit) { +#if defined(NETIF_EN_NETLINK) + if (HAL_TAU_PKT_NETIF_RX_DST_NETLINK == ptr_profile_hit->dst_type) + { + *ptr_dest = HAL_TAU_PKT_DEST_NETLINK; + *pptr_cookie = (void *)&ptr_profile_hit->netlink; + } + else + { + *ptr_dest = HAL_TAU_PKT_DEST_SDK; + } +#else *ptr_dest = HAL_TAU_PKT_DEST_SDK; +#endif } else { @@ -2134,7 +2317,7 @@ _hal_tau_pkt_rxEnQueue( HAL_TAU_PKT_RX_SW_GPD_T *ptr_sw_first_gpd = ptr_sw_gpd; void *ptr_virt_addr = NULL; NPS_ADDR_T phy_addr = 0; - HAL_TAU_PKT_DEST_T pkt_dest; + HAL_TAU_PKT_DEST_T dest_type; /* skb meta */ UI32_T port = 0, len = 0, total_len = 0; @@ -2142,6 +2325,7 @@ _hal_tau_pkt_rxEnQueue( struct net_device_priv *ptr_priv = NULL; struct sk_buff *ptr_skb = NULL, *ptr_merge_skb = NULL; UI32_T copy_offset; + void *ptr_dest; #if defined(PERF_EN_TEST) /* To verify kernel Rx performance */ @@ -2166,9 +2350,16 @@ _hal_tau_pkt_rxEnQueue( } #endif - _hal_tau_pkt_getPacketDest(&ptr_sw_gpd->rx_gpd, &pkt_dest); - if (HAL_TAU_PKT_DEST_NETDEV == pkt_dest) + _hal_tau_pkt_getPacketDest(&ptr_sw_gpd->rx_gpd, &dest_type, &ptr_dest); + +#if defined(NETIF_EN_NETLINK) + if ((HAL_TAU_PKT_DEST_NETDEV == dest_type) || + (HAL_TAU_PKT_DEST_NETLINK == dest_type)) +#else + if (HAL_TAU_PKT_DEST_NETDEV == dest_type) +#endif { + /* need to encap the packet as skb */ ptr_sw_gpd = ptr_sw_first_gpd; while (NULL != ptr_sw_gpd) { @@ -2205,6 +2396,9 @@ _hal_tau_pkt_rxEnQueue( ptr_sw_gpd = ptr_sw_gpd->ptr_next; } + port = ptr_sw_first_gpd->rx_gpd.itmh_eth.igr_phy_port; + ptr_net_dev = HAL_TAU_PKT_GET_PORT_NETDEV(port); + /* if the packet is composed of multiple gpd (skb), need to merge it into a single skb */ if (NULL != ptr_sw_first_gpd->ptr_next) { @@ -2247,10 +2441,6 @@ _hal_tau_pkt_rxEnQueue( _hal_tau_pkt_freeRxGpdList(unit, ptr_sw_first_gpd, FALSE); } - /* get port and net_device */ - port = ptr_sw_first_gpd->rx_gpd.itmh_eth.igr_phy_port; - ptr_net_dev = HAL_TAU_PKT_GET_PORT_NETDEV(port); - /* if NULL netdev, drop the skb */ if (NULL == ptr_net_dev) { @@ -2265,19 +2455,33 @@ _hal_tau_pkt_rxEnQueue( /* skb handling */ ptr_skb->dev = ptr_net_dev; ptr_skb->pkt_type = PACKET_HOST; /* this packet is for me */ - ptr_skb->protocol = eth_type_trans(ptr_skb, ptr_net_dev); /* skip ethernet header */ ptr_skb->ip_summed = CHECKSUM_UNNECESSARY; /* skip checksum */ /* send to linux */ - osal_skb_recv(ptr_skb); + if (dest_type == HAL_TAU_PKT_DEST_NETDEV) + { + /* skip ethernet header only for Linux net interface*/ + ptr_skb->protocol = eth_type_trans(ptr_skb, ptr_net_dev); + osal_skb_recv(ptr_skb); #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0) - ptr_net_dev->last_rx = jiffies; + ptr_net_dev->last_rx = jiffies; +#endif + ptr_priv = netdev_priv(ptr_net_dev); + ptr_priv->stats.rx_packets++; + ptr_priv->stats.rx_bytes += total_len; + } +#if defined(NETIF_EN_NETLINK) + else + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_PROFILE, + "hit profile dest=netlink, name=%s, mcgrp=%s\n", + ((NETIF_NL_RX_DST_NETLINK_T *)ptr_dest)->name, + ((NETIF_NL_RX_DST_NETLINK_T *)ptr_dest)->mc_group_name); + netif_nl_rxSkb(unit, ptr_skb, ptr_dest); + } #endif - ptr_priv = netdev_priv(ptr_net_dev); - ptr_priv->stats.rx_packets++; - ptr_priv->stats.rx_bytes += total_len; } - else if (HAL_TAU_PKT_DEST_SDK == pkt_dest) + else if (HAL_TAU_PKT_DEST_SDK == dest_type) { while (0 != _hal_tau_pkt_enQueue(&ptr_rx_cb->sw_queue[channel], ptr_sw_gpd)) { @@ -2289,7 +2493,7 @@ _hal_tau_pkt_rxEnQueue( osal_triggerEvent(&ptr_rx_cb->sync_sema); ptr_rx_cb->cnt.channel[channel].trig_event++; } - else if (HAL_TAU_PKT_DEST_DROP == pkt_dest) + else if (HAL_TAU_PKT_DEST_DROP == dest_type) { _hal_tau_pkt_freeRxGpdList(unit, ptr_sw_first_gpd, TRUE); } @@ -2297,10 +2501,34 @@ _hal_tau_pkt_rxEnQueue( { HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_ERR | HAL_TAU_PKT_DBG_RX), "u=%u, rxch=%u, invalid pkt dest=%d\n", - unit, channel, pkt_dest); + unit, channel, dest_type); } } +static NPS_ERROR_NO_T +_hal_tau_pkt_flushRxQueue( + const UI32_T unit, + HAL_TAU_PKT_SW_QUEUE_T *ptr_que) +{ + HAL_TAU_PKT_RX_SW_GPD_T *ptr_sw_gpd_knl = NULL; + NPS_ERROR_NO_T rc; + + while (1) + { + rc = _hal_tau_pkt_deQueue(ptr_que, (void **)&ptr_sw_gpd_knl); + if (NPS_E_OK == rc) + { + _hal_tau_pkt_freeRxGpdList(unit, ptr_sw_gpd_knl, TRUE); + } + else + { + break; + } + } + + return (NPS_E_OK); +} + /* FUNCTION NAME: _hal_tau_pkt_schedRxDeQueue * PURPOSE: * To dequeue the packets based on the configured algorithm. @@ -2335,33 +2563,14 @@ _hal_tau_pkt_schedRxDeQueue( UI32_T buf_len = 0; NPS_ERROR_NO_T rc = NPS_E_OK; - /* get queue and count */ - for (idx = 0; idx < HAL_TAU_PKT_RX_QUEUE_NUM; idx++) - { - /* to gurantee the opportunity where each queue can be handler */ - queue = ((ptr_rx_cb->deque_idx + idx) % HAL_TAU_PKT_RX_QUEUE_NUM); - _hal_tau_pkt_getQueueCount(&ptr_rx_cb->sw_queue[queue], &que_cnt); - if (que_cnt > 0) - { - ptr_rx_cb->deque_idx = ((queue + 1) % HAL_TAU_PKT_RX_QUEUE_NUM); - break; - } - } - - /* If all of the queues are empty, wait rxTask event */ - if (0 == que_cnt) + /* normal process */ + if (TRUE == ptr_rx_cb->running) { - osal_waitEvent(&ptr_rx_cb->sync_sema); - if (FALSE == ptr_rx_cb->running) - { - return (NPS_E_OTHERS); /* deinit */ - } - - ptr_rx_cb->cnt.wait_event++; - - /* re-get queue and count */ - for (queue = 0; queue < HAL_TAU_PKT_RX_QUEUE_NUM; queue++) + /* get queue and count */ + for (idx = 0; idx < HAL_TAU_PKT_RX_QUEUE_NUM; idx++) { + /* to gurantee the opportunity where each queue can be handler */ + queue = ((ptr_rx_cb->deque_idx + idx) % HAL_TAU_PKT_RX_QUEUE_NUM); _hal_tau_pkt_getQueueCount(&ptr_rx_cb->sw_queue[queue], &que_cnt); if (que_cnt > 0) { @@ -2369,68 +2578,87 @@ _hal_tau_pkt_schedRxDeQueue( break; } } - } - /* deque */ - if ((que_cnt > 0) && (queue < HAL_TAU_PKT_RX_QUEUE_NUM)) - { - rc = _hal_tau_pkt_deQueue(&ptr_rx_cb->sw_queue[queue], (void **)&ptr_sw_gpd_knl); - if (NPS_E_OK == rc) + /* If all of the queues are empty, wait rxTask event */ + if (0 == que_cnt) { - ptr_rx_cb->cnt.channel[queue].deque_ok++; - ptr_sw_first_gpd_knl = ptr_sw_gpd_knl; + osal_waitEvent(&ptr_rx_cb->sync_sema); - osal_io_copyFromUser(&ioctl_data, ptr_cookie, sizeof(HAL_TAU_PKT_IOCTL_RX_COOKIE_T)); + ptr_rx_cb->cnt.wait_event++; - while (NULL != ptr_sw_gpd_knl) + /* re-get queue and count */ + for (queue = 0; queue < HAL_TAU_PKT_RX_QUEUE_NUM; queue++) { - /* get the IOCTL GPD from user */ - osal_io_copyFromUser(&ioctl_gpd, - ((void *)((NPS_HUGE_T)ioctl_data.ioctl_gpd_addr)) - + gpd_idx*sizeof(HAL_TAU_PKT_IOCTL_RX_GPD_T), - sizeof(HAL_TAU_PKT_IOCTL_RX_GPD_T)); + _hal_tau_pkt_getQueueCount(&ptr_rx_cb->sw_queue[queue], &que_cnt); + if (que_cnt > 0) + { + ptr_rx_cb->deque_idx = ((queue + 1) % HAL_TAU_PKT_RX_QUEUE_NUM); + break; + } + } + } - /* get knl buf addr */ - ptr_rx_gpd = &ptr_sw_gpd_knl->rx_gpd; - phy_addr = NPS_ADDR_32_TO_64(ptr_rx_gpd->data_buf_addr_hi, ptr_rx_gpd->data_buf_addr_lo); + /* deque */ + if ((que_cnt > 0) && (queue < HAL_TAU_PKT_RX_QUEUE_NUM)) + { + rc = _hal_tau_pkt_deQueue(&ptr_rx_cb->sw_queue[queue], (void **)&ptr_sw_gpd_knl); + if (NPS_E_OK == rc) + { + ptr_rx_cb->cnt.channel[queue].deque_ok++; + ptr_sw_first_gpd_knl = ptr_sw_gpd_knl; - ptr_virt_addr = ptr_sw_gpd_knl->ptr_cookie; - osal_skb_unmapDma(phy_addr, ((struct sk_buff *)ptr_virt_addr)->len, DMA_FROM_DEVICE); + osal_io_copyFromUser(&ioctl_data, ptr_cookie, sizeof(HAL_TAU_PKT_IOCTL_RX_COOKIE_T)); - buf_len = (HAL_TAU_PKT_CH_LAST_GPD == ptr_rx_gpd->ch)? - ptr_rx_gpd->cnsm_buf_len : ptr_rx_gpd->avbl_buf_len; + while (NULL != ptr_sw_gpd_knl) + { + /* get the IOCTL GPD from user */ + osal_io_copyFromUser(&ioctl_gpd, + ((void *)((NPS_HUGE_T)ioctl_data.ioctl_gpd_addr)) + + gpd_idx*sizeof(HAL_TAU_PKT_IOCTL_RX_GPD_T), + sizeof(HAL_TAU_PKT_IOCTL_RX_GPD_T)); + + /* get knl buf addr */ + ptr_rx_gpd = &ptr_sw_gpd_knl->rx_gpd; + phy_addr = NPS_ADDR_32_TO_64(ptr_rx_gpd->data_buf_addr_hi, ptr_rx_gpd->data_buf_addr_lo); + + ptr_virt_addr = ptr_sw_gpd_knl->ptr_cookie; + osal_skb_unmapDma(phy_addr, ((struct sk_buff *)ptr_virt_addr)->len, DMA_FROM_DEVICE); + + buf_len = (HAL_TAU_PKT_CH_LAST_GPD == ptr_rx_gpd->ch)? + ptr_rx_gpd->cnsm_buf_len : ptr_rx_gpd->avbl_buf_len; + + /* overwrite whole rx_gpd to user + * the user should re-assign the correct value to data_buf_addr_hi, data_buf_addr_low + * after this IOCTL returns + */ + osal_io_copyToUser((void *)((NPS_HUGE_T)ioctl_gpd.hw_gpd_addr), + &ptr_sw_gpd_knl->rx_gpd, + sizeof(HAL_TAU_PKT_RX_GPD_T)); + /* copy buf */ + /* DMA buf address allocated by the user is store in ptr_ioctl_data->gpd[idx].cookie */ + osal_io_copyToUser((void *)((NPS_HUGE_T)ioctl_gpd.dma_buf_addr), + ((struct sk_buff *)ptr_virt_addr)->data, buf_len); + ptr_sw_gpd_knl->ptr_cookie = ptr_virt_addr; + + /* next */ + ptr_sw_gpd_knl = ptr_sw_gpd_knl->ptr_next; + gpd_idx++; + } - /* overwrite whole rx_gpd to user - * the user should re-assign the correct value to data_buf_addr_hi, data_buf_addr_low - * after this IOCTL returns - */ - osal_io_copyToUser((void *)((NPS_HUGE_T)ioctl_gpd.hw_gpd_addr), - &ptr_sw_gpd_knl->rx_gpd, - sizeof(HAL_TAU_PKT_RX_GPD_T)); - /* copy buf */ - /* DMA buf address allocated by the user is store in ptr_ioctl_data->gpd[idx].cookie */ - osal_io_copyToUser((void *)((NPS_HUGE_T)ioctl_gpd.dma_buf_addr), - ((struct sk_buff *)ptr_virt_addr)->data, buf_len); - ptr_sw_gpd_knl->ptr_cookie = ptr_virt_addr; - - /* next */ - ptr_sw_gpd_knl = ptr_sw_gpd_knl->ptr_next; - gpd_idx++; + /* Must free kernel sw_gpd */ + _hal_tau_pkt_freeRxGpdList(unit, ptr_sw_first_gpd_knl, TRUE); + } + else + { + ptr_rx_cb->cnt.channel[queue].deque_fail++; } - - /* Must free kernel sw_gpd */ - _hal_tau_pkt_freeRxGpdList(unit, ptr_sw_first_gpd_knl, TRUE); } else { - ptr_rx_cb->cnt.channel[queue].deque_fail++; + /* it means that all queue's are flush -> rx stop flow */ + rc = NPS_E_OTHERS; } } - else - { - /* It may happen at last gpd, return error and do not invoke callback. */ - rc = NPS_E_OTHERS; - } return (rc); } @@ -2547,6 +2775,26 @@ _hal_tau_pkt_suspendAllIntf( return (NPS_E_OK); } +static NPS_ERROR_NO_T +_hal_tau_pkt_stopAllIntf( + const UI32_T unit) +{ + struct net_device *ptr_net_dev = NULL; + UI32_T port; + + /* Unregister net devices by id */ + for (port = 0; port < HAL_TAU_PKT_MAX_PORT_NUM; port++) + { + ptr_net_dev = HAL_TAU_PKT_GET_PORT_NETDEV(port); + if (NULL != ptr_net_dev) + { + netif_tx_disable(ptr_net_dev); + } + } + + return (NPS_E_OK); +} + /* FUNCTION NAME: hal_tau_pkt_sendGpd * PURPOSE: * To perform the packet transmission form CPU to the switch. @@ -2572,85 +2820,94 @@ hal_tau_pkt_sendGpd( HAL_TAU_PKT_TX_PDMA_T *ptr_tx_pdma = HAL_TAU_PKT_GET_TX_PDMA_PTR(unit, channel); volatile HAL_TAU_PKT_TX_GPD_T *ptr_tx_gpd = NULL; HAL_TAU_PKT_TX_SW_GPD_T *ptr_sw_first_gpd = ptr_sw_gpd; - UI32_T used_idx = 0; UI32_T used_gpd_num = ptr_sw_gpd->gpd_num; NPS_IRQ_FLAGS_T irq_flags; + HAL_TAU_PKT_DRV_CB_T *ptr_cb = HAL_TAU_PKT_GET_DRV_CB_PTR(unit); - osal_takeIsrLock(&ptr_tx_pdma->ring_lock, &irq_flags); - - /* If not PDMA error */ - if (FALSE == ptr_tx_pdma->err_flag) + if (0 != (ptr_cb->init_flag & HAL_TAU_PKT_INIT_TASK)) { - /* Make Sure GPD is enough */ - if (ptr_tx_pdma->free_gpd_num >= used_gpd_num) + osal_takeIsrLock(&ptr_tx_pdma->ring_lock, &irq_flags); + + /* If not PDMA error */ + if (FALSE == ptr_tx_pdma->err_flag) { - used_idx = ptr_tx_pdma->used_idx; - while (NULL != ptr_sw_gpd) + /* Make Sure GPD is enough */ + if (ptr_tx_pdma->free_gpd_num >= used_gpd_num) { - ptr_tx_gpd = HAL_TAU_PKT_GET_TX_GPD_PTR(unit, channel, used_idx); - osal_dma_invalidateCache((void *)ptr_tx_gpd, sizeof(HAL_TAU_PKT_TX_GPD_T)); - - if (HAL_TAU_PKT_HWO_HW_OWN == ptr_tx_gpd->hwo) + used_idx = ptr_tx_pdma->used_idx; + while (NULL != ptr_sw_gpd) { - HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_ERR | HAL_TAU_PKT_DBG_TX), - "u=%u, txch=%u, free gpd idx out-of-sync\n", - unit, channel); - rc = NPS_E_TABLE_FULL; - break; - } + ptr_tx_gpd = HAL_TAU_PKT_GET_TX_GPD_PTR(unit, channel, used_idx); + osal_dma_invalidateCache((void *)ptr_tx_gpd, sizeof(HAL_TAU_PKT_TX_GPD_T)); - /* Fill in HW-GPD Ring */ - osal_memcpy((void *)ptr_tx_gpd, &ptr_sw_gpd->tx_gpd, sizeof(HAL_TAU_PKT_TX_GPD_T)); - osal_dma_flushCache((void *)ptr_tx_gpd, sizeof(HAL_TAU_PKT_TX_GPD_T)); + if (HAL_TAU_PKT_HWO_HW_OWN == ptr_tx_gpd->hwo) + { + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_ERR | HAL_TAU_PKT_DBG_TX), + "u=%u, txch=%u, free gpd idx out-of-sync\n", + unit, channel); + rc = NPS_E_TABLE_FULL; + break; + } - /* next */ - used_idx++; - used_idx %= ptr_tx_pdma->gpd_num; - ptr_sw_gpd = ptr_sw_gpd->ptr_next; - } + /* Fill in HW-GPD Ring */ + osal_memcpy((void *)ptr_tx_gpd, &ptr_sw_gpd->tx_gpd, sizeof(HAL_TAU_PKT_TX_GPD_T)); + osal_dma_flushCache((void *)ptr_tx_gpd, sizeof(HAL_TAU_PKT_TX_GPD_T)); - if (HAL_TAU_PKT_TX_WAIT_ASYNC == ptr_tx_cb->wait_mode) - { - /* Fill 1st GPD in SW-GPD Ring */ - ptr_tx_pdma->pptr_sw_gpd_ring[ptr_tx_pdma->used_idx] = ptr_sw_first_gpd; - } + /* next */ + used_idx++; + used_idx %= ptr_tx_pdma->gpd_num; + ptr_sw_gpd = ptr_sw_gpd->ptr_next; + } - /* update Tx PDMA */ - ptr_tx_pdma->used_idx = used_idx; - ptr_tx_pdma->used_gpd_num += used_gpd_num; - ptr_tx_pdma->free_gpd_num -= used_gpd_num; + if (HAL_TAU_PKT_TX_WAIT_ASYNC == ptr_tx_cb->wait_mode) + { + /* Fill 1st GPD in SW-GPD Ring */ + ptr_tx_pdma->pptr_sw_gpd_ring[ptr_tx_pdma->used_idx] = ptr_sw_first_gpd; + } + + /* update Tx PDMA */ + ptr_tx_pdma->used_idx = used_idx; + ptr_tx_pdma->used_gpd_num += used_gpd_num; + ptr_tx_pdma->free_gpd_num -= used_gpd_num; - _hal_tau_pkt_resumeTxChannelReg(unit, channel, used_gpd_num); - ptr_tx_cb->cnt.channel[channel].send_ok++; + _hal_tau_pkt_resumeTxChannelReg(unit, channel, used_gpd_num); + ptr_tx_cb->cnt.channel[channel].send_ok++; - _hal_tau_pkt_waitTxDone(unit, channel, ptr_sw_first_gpd); + _hal_tau_pkt_waitTxDone(unit, channel, ptr_sw_first_gpd); - /* reserve 1 packet buffer for each port in case that the suspension is too late */ -#define HAL_TAU_PKT_KNL_TX_RING_AVBL_GPD_LOW (HAL_TAU_PORT_NUM) - if (ptr_tx_pdma->free_gpd_num < HAL_TAU_PKT_KNL_TX_RING_AVBL_GPD_LOW) + /* reserve 1 packet buffer for each port in case that the suspension is too late */ +#define HAL_TAU_PKT_KNL_TX_RING_AVBL_GPD_LOW (HAL_PORT_NUM) + if (ptr_tx_pdma->free_gpd_num < HAL_TAU_PKT_KNL_TX_RING_AVBL_GPD_LOW) + { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_TX, + "u=%u, txch=%u, tx avbl gpd < %d, suspend all netdev\n", + unit, channel, HAL_TAU_PKT_KNL_TX_RING_AVBL_GPD_LOW); + _hal_tau_pkt_suspendAllIntf(unit); + } + } + else { - HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_TX, - "u=%u, txch=%u, tx avbl gpd < %d, suspend all netdev\n", - unit, channel, HAL_TAU_PKT_KNL_TX_RING_AVBL_GPD_LOW); - _hal_tau_pkt_suspendAllIntf(unit); + rc = NPS_E_TABLE_FULL; } } else { - rc = NPS_E_TABLE_FULL; + HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_ERR | HAL_TAU_PKT_DBG_TX), + "u=%u, txch=%u, pdma hw err\n", + unit, channel); + rc = NPS_E_OTHERS; } + + osal_giveIsrLock(&ptr_tx_pdma->ring_lock, &irq_flags); } else { - HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_ERR | HAL_TAU_PKT_DBG_TX), - "u=%u, txch=%u, pdma hw err\n", - unit, channel); + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_ERR, + "Tx failed, task already deinit\n"); rc = NPS_E_OTHERS; } - osal_giveIsrLock(&ptr_tx_pdma->ring_lock, &irq_flags); - return (rc); } @@ -2662,6 +2919,7 @@ _hal_tau_pkt_rxStop( { NPS_ERROR_NO_T rc = NPS_E_OK; HAL_TAU_PKT_RX_CHANNEL_T channel = 0; + UI32_T idx; HAL_TAU_PKT_RX_CB_T *ptr_rx_cb = HAL_TAU_PKT_GET_RX_CB_PTR(unit); HAL_TAU_PKT_DRV_CB_T *ptr_cb = HAL_TAU_PKT_GET_DRV_CB_PTR(unit); HAL_TAU_PKT_RX_PDMA_T *ptr_rx_pdma = NULL; @@ -2695,6 +2953,14 @@ _hal_tau_pkt_rxStop( osal_giveSemaphore(&ptr_rx_pdma->sema); } + /* flush packets in all queues since Rx task may be blocked in user space + * in this case it won't do ioctl to kernel to handle remaining packets + */ + for (idx = 0; idx < HAL_TAU_PKT_RX_QUEUE_NUM; idx++) + { + _hal_tau_pkt_flushRxQueue(unit, &ptr_rx_cb->sw_queue[idx]); + } + /* Return user thread */ ptr_rx_cb->running = FALSE; ptr_cb->init_flag &= (~HAL_TAU_PKT_INIT_RX_START); @@ -2848,6 +3114,12 @@ hal_tau_pkt_deinitTask( HAL_TAU_PKT_RX_CB_T *ptr_rx_cb = HAL_TAU_PKT_GET_RX_CB_PTR(unit); UI32_T channel = 0; + /* to prevent net intf from Tx packet */ + ptr_tx_cb->net_tx_allowed = FALSE; + + /* In case that some undestroyed net intf keep Tx after task deinit */ + _hal_tau_pkt_stopAllIntf(unit); + if (0 == (ptr_cb->init_flag & HAL_TAU_PKT_INIT_TASK)) { HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_RX | HAL_TAU_PKT_DBG_ERR), @@ -2926,13 +3198,10 @@ _hal_tau_pkt_deinitTxPdma( { HAL_TAU_PKT_TX_CB_T *ptr_tx_cb = HAL_TAU_PKT_GET_TX_CB_PTR(unit); HAL_TAU_PKT_TX_PDMA_T *ptr_tx_pdma = HAL_TAU_PKT_GET_TX_PDMA_PTR(unit, channel); - NPS_IRQ_FLAGS_T irg_flags; _hal_tau_pkt_stopTxChannelReg(unit, channel); /* Free DMA and flush queue */ - osal_takeIsrLock(&ptr_tx_pdma->ring_lock, &irg_flags); - osal_dma_free(ptr_tx_pdma->ptr_gpd_start_addr); if (HAL_TAU_PKT_TX_WAIT_ASYNC == ptr_tx_cb->wait_mode) @@ -2945,8 +3214,6 @@ _hal_tau_pkt_deinitTxPdma( osal_destroySemaphore(&ptr_tx_pdma->sync_intr_sema); } - osal_giveIsrLock(&ptr_tx_pdma->ring_lock, &irg_flags); - osal_destroyIsrLock(&ptr_tx_pdma->ring_lock); return (NPS_E_OK); @@ -3919,6 +4186,7 @@ _hal_tau_pkt_handleRxDoneTask( ptr_sw_gpd->ptr_next = NULL; ptr_sw_first_gpd->rx_complete = FALSE; _hal_tau_pkt_rxEnQueue(unit, channel, ptr_sw_first_gpd); + ptr_sw_first_gpd = NULL; } /* do error recover */ @@ -3956,7 +4224,7 @@ _hal_tau_pkt_handleRxDoneTask( { ptr_rx_cb->cnt.no_memory++; HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_RX | HAL_TAU_PKT_DBG_ERR), - "u=%u, rxch=%u, alloc 1st sw gpd failed, size=%d\n", + "u=%u, rxch=%u, alloc 1st sw gpd failed, size=%zu\n", unit, channel, sizeof(HAL_TAU_PKT_RX_SW_GPD_T)); break; } @@ -3973,7 +4241,7 @@ _hal_tau_pkt_handleRxDoneTask( { ptr_rx_cb->cnt.no_memory++; HAL_TAU_PKT_DBG((HAL_TAU_PKT_DBG_RX | HAL_TAU_PKT_DBG_ERR), - "u=%u, rxch=%u, alloc mid sw gpd failed, size=%d\n", + "u=%u, rxch=%u, alloc mid sw gpd failed, size=%zu\n", unit, channel, sizeof(HAL_TAU_PKT_RX_SW_GPD_T)); break; } @@ -4003,6 +4271,7 @@ _hal_tau_pkt_handleRxDoneTask( ptr_sw_gpd->ptr_next = NULL; ptr_sw_first_gpd->rx_complete = TRUE; _hal_tau_pkt_rxEnQueue(unit, channel, ptr_sw_first_gpd); + ptr_sw_first_gpd = NULL; /* To rebuild the SW GPD link list */ first = TRUE; @@ -4085,8 +4354,8 @@ hal_tau_pkt_initTask( } /* Init handleErrorTask */ - rc = osal_createThread("ERROR", HAL_TAU_PKT_ERROR_ISR_STACK_SIZE, - HAL_TAU_PKT_ERROR_ISR_THREAD_PRI, _hal_tau_pkt_handleErrorTask, + rc = osal_createThread("ERROR", HAL_DFLT_CFG_PKT_ERROR_ISR_THREAD_STACK, + HAL_DFLT_CFG_PKT_ERROR_ISR_THREAD_PRI, _hal_tau_pkt_handleErrorTask, (void *)((NPS_HUGE_T)unit), &ptr_cb->err_task_id); /* Init handleTxDoneTask */ @@ -4095,8 +4364,8 @@ hal_tau_pkt_initTask( ptr_tx_cb->isr_task_cookie[channel].unit = unit; ptr_tx_cb->isr_task_cookie[channel].channel = channel; - rc = osal_createThread("TX_ISR", HAL_TAU_PKT_TX_ISR_STACK_SIZE, - HAL_TAU_PKT_TX_ISR_THREAD_PRI, _hal_tau_pkt_handleTxDoneTask, + rc = osal_createThread("TX_ISR", HAL_DFLT_CFG_PKT_TX_ISR_THREAD_STACK, + HAL_DFLT_CFG_PKT_TX_ISR_THREAD_PRI, _hal_tau_pkt_handleTxDoneTask, (void *)&ptr_tx_cb->isr_task_cookie[channel], &ptr_tx_cb->isr_task_id[channel]); } @@ -4107,8 +4376,8 @@ hal_tau_pkt_initTask( ptr_rx_cb->isr_task_cookie[channel].unit = unit; ptr_rx_cb->isr_task_cookie[channel].channel = channel; - rc = osal_createThread("RX_ISR", HAL_TAU_PKT_RX_ISR_STACK_SIZE, - HAL_TAU_PKT_RX_ISR_THREAD_PRI, _hal_tau_pkt_handleRxDoneTask, + rc = osal_createThread("RX_ISR", HAL_DFLT_CFG_PKT_RX_ISR_THREAD_STACK, + HAL_DFLT_CFG_PKT_RX_ISR_THREAD_PRI, _hal_tau_pkt_handleRxDoneTask, (void *)&ptr_rx_cb->isr_task_cookie[channel], &ptr_rx_cb->isr_task_id[channel]); } @@ -4124,6 +4393,13 @@ hal_tau_pkt_initTask( HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_COMMON, "u=%u, pkt task init done, init flag=0x%x\n", unit, ptr_cb->init_flag); + /* For some specail case in warmboot, the netifs are not destroyed during sdk deinit + * but stopped, here we need to resume them with the original carrier status + */ + _hal_tau_pkt_resumeAllIntf(unit); + + ptr_tx_cb->net_tx_allowed = TRUE; + return (rc); } @@ -4165,8 +4441,8 @@ _hal_tau_pkt_initTxPdma( ptr_tx_pdma->used_idx = 0; ptr_tx_pdma->free_idx = 0; ptr_tx_pdma->used_gpd_num = 0; - ptr_tx_pdma->free_gpd_num = HAL_TAU_PKT_PDMA_TX_GPD_NUM; - ptr_tx_pdma->gpd_num = HAL_TAU_PKT_PDMA_TX_GPD_NUM; + ptr_tx_pdma->free_gpd_num = HAL_DFLT_CFG_PKT_TX_GPD_NUM; + ptr_tx_pdma->gpd_num = HAL_DFLT_CFG_PKT_TX_GPD_NUM; /* Prepare the HW-GPD ring */ ptr_tx_pdma->ptr_gpd_start_addr = (HAL_TAU_PKT_TX_GPD_T *)osal_dma_alloc( @@ -4263,7 +4539,7 @@ _hal_tau_pkt_initRxPdma( /* Reset Rx PDMA */ osal_takeSemaphore(&ptr_rx_pdma->sema, NPS_SEMAPHORE_WAIT_FOREVER); ptr_rx_pdma->cur_idx = 0; - ptr_rx_pdma->gpd_num = HAL_TAU_PKT_PDMA_RX_GPD_NUM; + ptr_rx_pdma->gpd_num = HAL_DFLT_CFG_PKT_RX_GPD_NUM; /* Prepare the HW-GPD ring */ ptr_rx_pdma->ptr_gpd_start_addr = (HAL_TAU_PKT_RX_GPD_T *)osal_dma_alloc( @@ -4374,7 +4650,7 @@ _hal_tau_pkt_initPktTxCb( osal_createEvent("TX_SYNC", &ptr_tx_cb->sync_sema); /* Initialize Tx GPD-queue (of first SW-GPD) from handleTxDoneTask to txTask */ - ptr_tx_cb->sw_queue.len = HAL_TAU_PKT_TX_QUEUE_LEN; + ptr_tx_cb->sw_queue.len = HAL_DFLT_CFG_PKT_TX_QUEUE_LEN; ptr_tx_cb->sw_queue.weight = 0; osal_createSemaphore("TX_QUE", NPS_SEMAPHORE_BINARY, &ptr_tx_cb->sw_queue.sema); @@ -4422,7 +4698,7 @@ _hal_tau_pkt_initPktRxCb( osal_memset(ptr_rx_cb, 0x0, sizeof(HAL_TAU_PKT_RX_CB_T)); - ptr_rx_cb->sched_mode = HAL_TAU_PKT_RX_SCHED_MODE; + ptr_rx_cb->sched_mode = HAL_DFLT_CFG_PKT_RX_SCHED_MODE; /* Sync semaphore to signal rxTask */ osal_createEvent("RX_SYNC", &ptr_rx_cb->sync_sema); @@ -4430,8 +4706,8 @@ _hal_tau_pkt_initPktRxCb( /* Initialize Rx GPD-queue (of first SW-GPD) from handleRxDoneTask to rxTask */ for (queue = 0; ((queue < HAL_TAU_PKT_RX_QUEUE_NUM) && (NPS_E_OK == rc)); queue++) { - ptr_rx_cb->sw_queue[queue].len = HAL_TAU_PKT_RX_QUEUE_LEN; - ptr_rx_cb->sw_queue[queue].weight = HAL_TAU_PKT_RX_QUEUE_WEIGHT; + ptr_rx_cb->sw_queue[queue].len = HAL_DFLT_CFG_PKT_RX_QUEUE_LEN; + ptr_rx_cb->sw_queue[queue].weight = HAL_DFLT_CFG_PKT_RX_QUEUE_WEIGHT; osal_createSemaphore("RX_QUE", NPS_SEMAPHORE_BINARY, &ptr_rx_cb->sw_queue[queue].sema); osal_que_create(&ptr_rx_cb->sw_queue[queue].que_id, ptr_rx_cb->sw_queue[queue].len); @@ -4530,12 +4806,12 @@ _hal_tau_pkt_resetIosCreditCfg( osal_mdc_readPciReg(unit, HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_PDMA_CREDIT_CFG), &credit_cfg, sizeof(credit_cfg)); - credit_cfg |= (0x1 << HAL_TAU_PKT_PDMA_CREDIT_CFG_RESET_OFFSET); + credit_cfg |= (0x1UL << HAL_TAU_PKT_PDMA_CREDIT_CFG_RESET_OFFSET); osal_mdc_writePciReg(unit, HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_PDMA_CREDIT_CFG), &credit_cfg, sizeof(UI32_T)); - credit_cfg &= ~(0x1 << HAL_TAU_PKT_PDMA_CREDIT_CFG_RESET_OFFSET); + credit_cfg &= ~(0x1UL << HAL_TAU_PKT_PDMA_CREDIT_CFG_RESET_OFFSET); osal_mdc_writePciReg(unit, HAL_TAU_PKT_GET_MMIO(HAL_TAU_PKT_PDMA_CREDIT_CFG), &credit_cfg, sizeof(UI32_T)); @@ -4544,27 +4820,6 @@ _hal_tau_pkt_resetIosCreditCfg( return (NPS_E_OK); } -static NPS_ERROR_NO_T -_hal_tau_pkt_stopAllIntf( - const UI32_T unit) -{ - struct net_device *ptr_net_dev = NULL; - UI32_T port; - - /* Unregister net devices by id */ - for (port = 0; port < HAL_TAU_PKT_MAX_PORT_NUM; port++) - { - ptr_net_dev = HAL_TAU_PKT_GET_PORT_NETDEV(port); - if (NULL != ptr_net_dev) - { - netif_carrier_off(ptr_net_dev); - netif_stop_queue(ptr_net_dev); - } - } - - return (NPS_E_OK); -} - static NPS_ERROR_NO_T _hal_tau_pkt_addProfToList( HAL_TAU_PKT_NETIF_PROFILE_T *ptr_new_profile, @@ -4668,8 +4923,8 @@ _hal_tau_pkt_addProfToAllIntf( for (port = 0; port < HAL_TAU_PKT_MAX_PORT_NUM; port++) { ptr_port_db = HAL_TAU_PKT_GET_PORT_DB(port); - /* Shall we check if the interface is ever created in the port?? */ - //if (NULL != ptr_port_db->ptr_net_dev) + /* Shall we check if the interface is ever created on the port?? */ + /* if (NULL != ptr_port_db->ptr_net_dev) */ if (1) { _hal_tau_pkt_addProfToList(ptr_new_profile, &ptr_port_db->ptr_profile_list); @@ -4759,8 +5014,8 @@ _hal_tau_pkt_delProfFromAllIntfById( for (port = 0; port < HAL_TAU_PKT_MAX_PORT_NUM; port++) { ptr_port_db = HAL_TAU_PKT_GET_PORT_DB(port); - /* Shall we check if the interface is ever created in the port?? */ - //if (NULL != ptr_port_db->ptr_net_dev) + /* Shall we check if the interface is ever created on the port?? */ + /* if (NULL != ptr_port_db->ptr_net_dev) */ if (1) { _hal_tau_pkt_delProfFromListById(id, &ptr_port_db->ptr_profile_list); @@ -4824,7 +5079,7 @@ _hal_tau_pkt_destroyAllIntf( ptr_port_db->meta.port, ptr_port_db->meta.port); - netif_stop_queue(ptr_port_db->ptr_net_dev); + netif_tx_disable(ptr_port_db->ptr_net_dev); unregister_netdev(ptr_port_db->ptr_net_dev); free_netdev(ptr_port_db->ptr_net_dev); @@ -5072,7 +5327,7 @@ hal_tau_pkt_prepareGpd( */ ptr_sw_gpd->tx_gpd.itmh_eth.dst_idx = port; - /* [Taurus] we should set all-1 for the following fields to skip some tm-logic */ + /* [NP8360] we should set all-1 for the following fields to skip some tm-logic */ /* TM header */ ptr_sw_gpd->tx_gpd.itmh_eth.src_idx = 0x7fff; @@ -5083,8 +5338,8 @@ hal_tau_pkt_prepareGpd( ptr_sw_gpd->tx_gpd.itmh_eth.nvo3_src_supp_tag_w1 = 0xf; /* PP header */ - ptr_sw_gpd->tx_gpd.pph_l2.nvo3_encap_idx = HAL_TAU_INVALID_NVO3_ENCAP_IDX; - ptr_sw_gpd->tx_gpd.pph_l2.nvo3_adj_idx = HAL_TAU_INVALID_NVO3_ADJ_IDX; + ptr_sw_gpd->tx_gpd.pph_l2.nvo3_encap_idx = HAL_INVALID_NVO3_ENCAP_IDX; + ptr_sw_gpd->tx_gpd.pph_l2.nvo3_adj_idx = HAL_INVALID_NVO3_ADJ_IDX; return (NPS_E_OK); } @@ -5157,6 +5412,7 @@ _hal_tau_pkt_net_dev_tx( struct net_device *ptr_net_dev) { struct net_device_priv *ptr_priv = netdev_priv(ptr_net_dev); + HAL_TAU_PKT_TX_CB_T *ptr_tx_cb; /* chip meta */ unsigned int unit; unsigned int channel = 0; @@ -5180,6 +5436,17 @@ _hal_tau_pkt_net_dev_tx( unit = ptr_priv->unit; + ptr_tx_cb = HAL_TAU_PKT_GET_TX_CB_PTR(unit); + /* for warm de-init procedure, if any net intf not destroyed, it is possible + * that kernel still has packets to send causing segmentation fault + */ + if (FALSE == ptr_tx_cb->net_tx_allowed) { + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_ERR, "net tx during sdk de-init\n"); + ptr_priv->stats.tx_dropped++; + osal_skb_free(ptr_skb); + return NETDEV_TX_OK; + } + /* pad to 60-bytes if skb_len < 60, see: eth_skb_pad(skb) */ if (ptr_skb->len < ETH_ZLEN) { @@ -5245,8 +5512,6 @@ _hal_tau_pkt_net_dev_tx( osal_skb_unmapDma(phy_addr, ptr_skb->len, DMA_TO_DEVICE); osal_skb_free(ptr_skb); osal_free(ptr_sw_gpd); - - return NETDEV_TX_OK; } } } @@ -5374,34 +5639,6 @@ _hal_tau_pkt_setup( memset(&ptr_priv->stats, 0, sizeof(struct net_device_stats)); } -static void -_hal_tau_pkt_lockRxChannelAll( - const UI32_T unit) -{ - UI32_T rch; - HAL_TAU_PKT_RX_PDMA_T *ptr_rx_pdma; - - for (rch = 0; rch < HAL_TAU_PKT_RX_CHANNEL_LAST; rch++) - { - ptr_rx_pdma = HAL_TAU_PKT_GET_RX_PDMA_PTR(unit, rch); - osal_takeSemaphore(&ptr_rx_pdma->sema, NPS_SEMAPHORE_WAIT_FOREVER); - } -} - -static void -_hal_tau_pkt_unlockRxChannelAll( - const UI32_T unit) -{ - UI32_T rch; - HAL_TAU_PKT_RX_PDMA_T *ptr_rx_pdma; - - for (rch = 0; rch < HAL_TAU_PKT_RX_CHANNEL_LAST; rch++) - { - ptr_rx_pdma = HAL_TAU_PKT_GET_RX_PDMA_PTR(unit, rch); - osal_giveSemaphore(&ptr_rx_pdma->sema); - } -} - static NPS_ERROR_NO_T _hal_tau_pkt_createIntf( const UI32_T unit, @@ -5435,7 +5672,7 @@ _hal_tau_pkt_createIntf( #if defined(HAL_TAU_PKT_FORCR_REMOVE_DUPLICATE_NETDEV) ptr_net_dev->operstate = IF_OPER_DOWN; netif_carrier_off(ptr_net_dev); - netif_stop_queue(ptr_net_dev); + netif_tx_disable(ptr_net_dev); unregister_netdev(ptr_net_dev); free_netdev(ptr_net_dev); #endif @@ -5466,6 +5703,8 @@ _hal_tau_pkt_createIntf( register_netdev(ptr_net_dev); + netif_carrier_off(ptr_net_dev); + net_intf.id = net_intf.port; /* Currently, id is 1-to-1 mapped to port */ osal_memcpy(&ptr_port_db->meta, &net_intf, sizeof(HAL_TAU_PKT_NETIF_INTF_T)); @@ -5518,10 +5757,11 @@ _hal_tau_pkt_destroyIntf( "u=%u, find intf %s (id=%d) on phy port=%d, destroy done\n", unit, ptr_port_db->meta.name, + ptr_port_db->meta.id, ptr_port_db->meta.port); netif_carrier_off(ptr_port_db->ptr_net_dev); - netif_stop_queue(ptr_port_db->ptr_net_dev); + netif_tx_disable(ptr_port_db->ptr_net_dev); unregister_netdev(ptr_port_db->ptr_net_dev); free_netdev(ptr_port_db->ptr_net_dev); @@ -5553,7 +5793,7 @@ _hal_tau_pkt_traverseProfList( ptr_curr_node = ptr_prof_list; - HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_INTF, "intf id=%d, prof list=\n", intf_id); + HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_INTF, "intf id=%d, prof list=", intf_id); while(NULL != ptr_curr_node) { HAL_TAU_PKT_DBG(HAL_TAU_PKT_DBG_INTF, "%s (%d) => ", @@ -6043,6 +6283,24 @@ _hal_tau_pkt_dev_ioctl( ret = hal_tau_pkt_setPortAttr(unit, (HAL_TAU_PKT_IOCTL_PORT_COOKIE_T *)arg); break; +#if defined(NETIF_EN_NETLINK) + case HAL_TAU_PKT_IOCTL_TYPE_NL_SET_INTF_PROPERTY: + ret = _hal_tau_pkt_setIntfProperty(unit, (HAL_TAU_PKT_NL_IOCTL_COOKIE_T *)arg); + break; + case HAL_TAU_PKT_IOCTL_TYPE_NL_GET_INTF_PROPERTY: + ret = _hal_tau_pkt_getIntfProperty(unit, (HAL_TAU_PKT_NL_IOCTL_COOKIE_T *)arg); + break; + case HAL_TAU_PKT_IOCTL_TYPE_NL_CREATE_NETLINK: + ret = _hal_tau_pkt_createNetlink(unit, (HAL_TAU_PKT_NL_IOCTL_COOKIE_T *)arg); + break; + case HAL_TAU_PKT_IOCTL_TYPE_NL_DESTROY_NETLINK: + ret = _hal_tau_pkt_destroyNetlink(unit, (HAL_TAU_PKT_NL_IOCTL_COOKIE_T *)arg); + break; + case HAL_TAU_PKT_IOCTL_TYPE_NL_GET_NETLINK: + ret = _hal_tau_pkt_getNetlink(unit, (HAL_TAU_PKT_NL_IOCTL_COOKIE_T *)arg); + break; +#endif + default: ret = -1; break; @@ -6102,6 +6360,10 @@ _hal_tau_pkt_init(void) osal_memset(_hal_tau_pkt_drv_cb, 0x0, NPS_CFG_MAXIMUM_CHIPS_PER_SYSTEM*sizeof(HAL_TAU_PKT_DRV_CB_T)); +#if defined(NETIF_EN_NETLINK) + netif_nl_init(); +#endif + return (0); } @@ -6110,16 +6372,16 @@ _hal_tau_pkt_exit(void) { UI32_T unit = 0; - /* 1st. Stop Rx HW DMA and free all the DMA buffer hooked on the ring */ + /* 1st. Stop all netdev (if any) to prevent kernel from Tx new packets */ + _hal_tau_pkt_stopAllIntf(unit); + + /* 2nd. Stop Rx HW DMA and free all the DMA buffer hooked on the ring */ _hal_tau_pkt_rxStop(unit); - /* 2nd. Need to wait Rx done task process all the availavle packets on GPD ring */ + /* 3rd. Need to wait Rx done task process all the availavle packets on GPD ring */ #define HAL_TAU_PKT_MODULE_EXIT_HOLD_TIME_US (1000000) osal_sleepThread(HAL_TAU_PKT_MODULE_EXIT_HOLD_TIME_US); - /* 3rd. Stop all netdev (if any) to prevent kernel from Tx new packets */ - _hal_tau_pkt_stopAllIntf(unit); - /* 4th. Stop all the internal tasks (if any) */ hal_tau_pkt_deinitTask(unit); @@ -6139,9 +6401,9 @@ _hal_tau_pkt_exit(void) module_init(_hal_tau_pkt_init); module_exit(_hal_tau_pkt_exit); -module_param(dbg_flag, uint, S_IRUGO); -MODULE_PARM_DESC(dbg_flag, "bit0:Error, bit1:Tx, bit2:Rx, bit3:Intf, bit4:Profile"); +module_param(ext_dbg_flag, uint, S_IRUGO); +MODULE_PARM_DESC(ext_dbg_flag, "bit0:Error, bit1:Tx, bit2:Rx, bit3:Intf, bit4:Profile"); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Nephos"); +MODULE_AUTHOR("MediaTek"); MODULE_DESCRIPTION("NETIF Kernel Module"); diff --git a/platform/nephos/nephos-modules/modules/src/inc/aml.h b/platform/nephos/nephos-modules/modules/src/inc/aml.h index 658aa6e56f46..682eaa5ea318 100755 --- a/platform/nephos/nephos-modules/modules/src/inc/aml.h +++ b/platform/nephos/nephos-modules/modules/src/inc/aml.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/platform/nephos/nephos-modules/modules/src/inc/hal_dev.h b/platform/nephos/nephos-modules/modules/src/inc/hal_dev.h index edd582adc197..e8d491358c77 100755 --- a/platform/nephos/nephos-modules/modules/src/inc/hal_dev.h +++ b/platform/nephos/nephos-modules/modules/src/inc/hal_dev.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/platform/nephos/nephos-modules/modules/src/inc/hal_tau_pkt_knl.h b/platform/nephos/nephos-modules/modules/src/inc/hal_tau_pkt_knl.h index 96a8cf6441f0..3605323a5955 100755 --- a/platform/nephos/nephos-modules/modules/src/inc/hal_tau_pkt_knl.h +++ b/platform/nephos/nephos-modules/modules/src/inc/hal_tau_pkt_knl.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public @@ -104,15 +104,15 @@ typedef enum /* hal_tau_const.h */ -#define HAL_TAU_PORT_NUM (128) -#define HAL_TAU_EXCPT_CPU_NUM (256) -#define HAL_TAU_INVALID_NVO3_ENCAP_IDX (0x3FFF) -#define HAL_TAU_INVALID_NVO3_ADJ_IDX (0xFF) -#define HAL_TAU_EXCPT_CPU_BASE_ID (28 * 1024) -#define HAL_TAU_EXCPT_CPU_NON_L3_MIN (0) -#define HAL_TAU_EXCPT_CPU_NON_L3_MAX (HAL_TAU_EXCPT_CPU_NON_L3_MIN + HAL_TAU_EXCPT_CPU_NUM - 1) -#define HAL_TAU_EXCPT_CPU_L3_MIN (HAL_TAU_EXCPT_CPU_NON_L3_MIN + HAL_TAU_EXCPT_CPU_NUM) -#define HAL_TAU_EXCPT_CPU_L3_MAX (HAL_TAU_EXCPT_CPU_L3_MIN + HAL_TAU_EXCPT_CPU_NUM - 1) +#define HAL_PORT_NUM (128) +#define HAL_EXCPT_CPU_NUM (256) +#define HAL_INVALID_NVO3_ENCAP_IDX (0x3FFF) +#define HAL_INVALID_NVO3_ADJ_IDX (0xFF) +#define HAL_EXCPT_CPU_BASE_ID (28 * 1024) +#define HAL_EXCPT_CPU_NON_L3_MIN (0) +#define HAL_EXCPT_CPU_NON_L3_MAX (HAL_EXCPT_CPU_NON_L3_MIN + HAL_EXCPT_CPU_NUM - 1) +#define HAL_EXCPT_CPU_L3_MIN (HAL_EXCPT_CPU_NON_L3_MIN + HAL_EXCPT_CPU_NUM) +#define HAL_EXCPT_CPU_L3_MAX (HAL_EXCPT_CPU_L3_MIN + HAL_EXCPT_CPU_NUM - 1) /* hal_tau_pkt_rsrc.h */ #define HAL_TAU_PKT_IPP_EXCPT_LAST (256) @@ -238,7 +238,7 @@ typedef struct HAL_TAU_PKT_IPP_COPY2CPU_BITMAP_T ipp_copy2cpu_bitmap; HAL_TAU_PKT_EPP_COPY2CPU_BITMAP_T epp_copy2cpu_bitmap; -} HAL_TAU_PKT_RX_REASON_BITMAP_T; +} HAL_PKT_RX_REASON_BITMAP_T; /* hal_tau_pkt.h */ @@ -246,23 +246,23 @@ typedef struct /* NAMING DECLARATIONS */ /* PKT related configurable parameters */ -#define HAL_TAU_PKT_RX_FREE_STACK_SIZE (64 * 1024) -#define HAL_TAU_PKT_RX_FREE_THREAD_PRI (80) +#define HAL_DFLT_CFG_PKT_RX_FREE_STACK_SIZE (64 * 1024) +#define HAL_DFLT_CFG_PKT_RX_FREE_THREAD_PRI (80) -#define HAL_TAU_PKT_RX_ISR_STACK_SIZE (64 * 1024) -#define HAL_TAU_PKT_RX_ISR_THREAD_PRI (80) +#define HAL_DFLT_CFG_PKT_RX_ISR_THREAD_STACK (64 * 1024) +#define HAL_DFLT_CFG_PKT_RX_ISR_THREAD_PRI (80) -#define HAL_TAU_PKT_TX_FREE_STACK_SIZE (64 * 1024) -#define HAL_TAU_PKT_TX_FREE_THREAD_PRI (80) +#define HAL_DFLT_CFG_PKT_TX_FREE_STACK_SIZE (64 * 1024) +#define HAL_DFLT_CFG_PKT_TX_FREE_THREAD_PRI (80) -#define HAL_TAU_PKT_TX_ISR_STACK_SIZE (64 * 1024) -#define HAL_TAU_PKT_TX_ISR_THREAD_PRI (80) +#define HAL_DFLT_CFG_PKT_TX_ISR_THREAD_STACK (64 * 1024) +#define HAL_DFLT_CFG_PKT_TX_ISR_THREAD_PRI (80) -#define HAL_TAU_PKT_TX_NET_STACK_SIZE (64 * 1024) -#define HAL_TAU_PKT_TX_NET_THREAD_PRI (80) +#define HAL_DFLT_CFG_PKT_TX_NET_STACK_SIZE (64 * 1024) +#define HAL_DFLT_CFG_PKT_TX_NET_THREAD_PRI (80) -#define HAL_TAU_PKT_ERROR_ISR_STACK_SIZE (64 * 1024) -#define HAL_TAU_PKT_ERROR_ISR_THREAD_PRI (80) +#define HAL_DFLT_CFG_PKT_ERROR_ISR_THREAD_STACK (64 * 1024) +#define HAL_DFLT_CFG_PKT_ERROR_ISR_THREAD_PRI (80) /* PKT definitions */ #define HAL_TAU_PKT_TX_MAX_LEN (9216) @@ -300,29 +300,29 @@ typedef struct /* PDMA Definitions */ #define HAL_TAU_PKT_PDMA_MAX_GPD_PER_PKT (10) /* <= 256 */ -#define HAL_TAU_PKT_PDMA_TX_GPD_NUM (1024) /* <= 65535 */ -#define HAL_TAU_PKT_PDMA_RX_GPD_NUM (1024) /* <= 65535 */ +#define HAL_DFLT_CFG_PKT_TX_GPD_NUM (1024) /* <= 65535 */ +#define HAL_DFLT_CFG_PKT_RX_GPD_NUM (1024) /* <= 65535 */ #define HAL_TAU_PKT_PDMA_TX_INTR_TIMEOUT (10 * 1000) /* us */ #define HAL_TAU_PKT_PDMA_TX_POLL_MAX_LOOP (10 * 1000) /* int */ /* Mode */ #define HAL_TAU_PKT_TX_WAIT_MODE (HAL_TAU_PKT_TX_WAIT_ASYNC) -#define HAL_TAU_PKT_RX_SCHED_MODE (HAL_TAU_PKT_RX_SCHED_RR) +#define HAL_DFLT_CFG_PKT_RX_SCHED_MODE (HAL_TAU_PKT_RX_SCHED_RR) /* TX Queue */ -#define HAL_TAU_PKT_TX_QUEUE_LEN (HAL_TAU_PKT_PDMA_TX_GPD_NUM * 10) -#define HAL_TAU_PKT_TX_TASK_MAX_LOOP (HAL_TAU_PKT_TX_QUEUE_LEN) +#define HAL_DFLT_CFG_PKT_TX_QUEUE_LEN (HAL_DFLT_CFG_PKT_TX_GPD_NUM * 10) +#define HAL_TAU_PKT_TX_TASK_MAX_LOOP (HAL_DFLT_CFG_PKT_TX_QUEUE_LEN) /* RX Queue */ #define HAL_TAU_PKT_RX_QUEUE_NUM (HAL_TAU_PKT_RX_CHANNEL_LAST) -#define HAL_TAU_PKT_RX_QUEUE_WEIGHT (10) -#define HAL_TAU_PKT_RX_QUEUE_LEN (HAL_TAU_PKT_PDMA_RX_GPD_NUM * 10) -#define HAL_TAU_PKT_RX_TASK_MAX_LOOP (HAL_TAU_PKT_RX_QUEUE_LEN) +#define HAL_DFLT_CFG_PKT_RX_QUEUE_WEIGHT (10) +#define HAL_DFLT_CFG_PKT_RX_QUEUE_LEN (HAL_DFLT_CFG_PKT_RX_GPD_NUM * 10) +#define HAL_TAU_PKT_RX_TASK_MAX_LOOP (HAL_DFLT_CFG_PKT_RX_QUEUE_LEN) /* MACRO FUNCTION DECLARATIONS */ /*---------------------------------------------------------------------------*/ -/* [Taurus] Alignment to 64-bytes */ +/* [NP8360] Alignment to 64-bytes */ #if defined(NPS_EN_HOST_64_BIT_BIG_ENDIAN) || defined(NPS_EN_HOST_64_BIT_LITTLE_ENDIAN) #define HAL_TAU_PKT_PDMA_ALIGN_ADDR(pdma_addr, align_sz) (((pdma_addr) + (align_sz)) & 0xFFFFFFFFFFFFFFC0) #else @@ -1120,77 +1120,77 @@ typedef struct /* ----------------------------------------------------------------------------------- Reg Type */ typedef enum { - HAL_TAU_PKT_L2_ISR_RCH0 = (0x1 << 0), - HAL_TAU_PKT_L2_ISR_RCH1 = (0x1 << 1), - HAL_TAU_PKT_L2_ISR_RCH2 = (0x1 << 2), - HAL_TAU_PKT_L2_ISR_RCH3 = (0x1 << 3), - HAL_TAU_PKT_L2_ISR_TCH0 = (0x1 << 4), - HAL_TAU_PKT_L2_ISR_TCH1 = (0x1 << 5), - HAL_TAU_PKT_L2_ISR_TCH2 = (0x1 << 6), - HAL_TAU_PKT_L2_ISR_TCH3 = (0x1 << 7), - HAL_TAU_PKT_L2_ISR_RX_QID_MAP_ERR = (0x1 << 8), - HAL_TAU_PKT_L2_ISR_RX_FRAME_ERR = (0x1 << 9) + HAL_TAU_PKT_L2_ISR_RCH0 = (0x1UL << 0), + HAL_TAU_PKT_L2_ISR_RCH1 = (0x1UL << 1), + HAL_TAU_PKT_L2_ISR_RCH2 = (0x1UL << 2), + HAL_TAU_PKT_L2_ISR_RCH3 = (0x1UL << 3), + HAL_TAU_PKT_L2_ISR_TCH0 = (0x1UL << 4), + HAL_TAU_PKT_L2_ISR_TCH1 = (0x1UL << 5), + HAL_TAU_PKT_L2_ISR_TCH2 = (0x1UL << 6), + HAL_TAU_PKT_L2_ISR_TCH3 = (0x1UL << 7), + HAL_TAU_PKT_L2_ISR_RX_QID_MAP_ERR = (0x1UL << 8), + HAL_TAU_PKT_L2_ISR_RX_FRAME_ERR = (0x1UL << 9) } HAL_TAU_PKT_L2_ISR_T; typedef enum { - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_HWO_ERROR = (0x1 << 0), /* Tx GPD.hwo = 0 */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_CHKSM_ERROR = (0x1 << 1), /* Tx GPD.chksm is error */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_NO_OVFL_ERROR = (0x1 << 2), /* S/W push too much GPD */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_DMA_READ_ERROR = (0x1 << 3), /* AXI Rd Error when do GPD read */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_BUF_SIZE_ERROR = (0x1 << 4), /* Tx GPD.data_buf_size = 0 */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_RUNT_ERROR = (0x1 << 5), /* Tx GPD.pkt_len < 64 */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_OVSZ_ERROR = (0x1 << 6), /* Tx GPD.pkt_len = 9217 */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_LEN_MISMATCH_ERROR = (0x1 << 7), /* Tx GPD.pkt_len != sum of data_buf_size */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_PKTPL_DMA_READ_ERROR = (0x1 << 8), /* AXI Rd Error when do Payload read */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_COS_ERROR = (0x1 << 9), /* Tx GPD.cos is not match cos_to_tch_map */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_GT255_ERROR = (0x1 << 10), /* Multi-GPD packet's GPD# > 255 */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_PFC = (0x1 << 11), /* */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_CREDIT_UDFL_ERROR = (0x1 << 12), /* Credit Underflow (count down to 0) */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_DMA_WRITE_ERROR = (0x1 << 13), /* AXI Wr Error (GPD Write-Back) */ - HAL_TAU_PKT_TX_CHANNEL_L2_ISR_STOP_CMD_CPLT = (0x1 << 14) + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_HWO_ERROR = (0x1UL << 0), /* Tx GPD.hwo = 0 */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_CHKSM_ERROR = (0x1UL << 1), /* Tx GPD.chksm is error */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_NO_OVFL_ERROR = (0x1UL << 2), /* S/W push too much GPD */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_DMA_READ_ERROR = (0x1UL << 3), /* AXI Rd Error when do GPD read */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_BUF_SIZE_ERROR = (0x1UL << 4), /* Tx GPD.data_buf_size = 0 */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_RUNT_ERROR = (0x1UL << 5), /* Tx GPD.pkt_len < 64 */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_OVSZ_ERROR = (0x1UL << 6), /* Tx GPD.pkt_len = 9217 */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_LEN_MISMATCH_ERROR = (0x1UL << 7), /* Tx GPD.pkt_len != sum of data_buf_size */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_PKTPL_DMA_READ_ERROR = (0x1UL << 8), /* AXI Rd Error when do Payload read */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_COS_ERROR = (0x1UL << 9), /* Tx GPD.cos is not match cos_to_tch_map */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_GPD_GT255_ERROR = (0x1UL << 10), /* Multi-GPD packet's GPD# > 255 */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_PFC = (0x1UL << 11), /* */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_CREDIT_UDFL_ERROR = (0x1UL << 12), /* Credit Underflow (count down to 0) */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_DMA_WRITE_ERROR = (0x1UL << 13), /* AXI Wr Error (GPD Write-Back) */ + HAL_TAU_PKT_TX_CHANNEL_L2_ISR_STOP_CMD_CPLT = (0x1UL << 14) } HAL_TAU_PKT_TX_CHANNEL_L2_ISR_T; typedef enum { - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_AVAIL_GPD_LOW = (0x1 << 0), /* Rx GPD.avbl_gpd_num < threshold */ - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_AVAIL_GPD_EMPTY = (0x1 << 1), /* Rx GPD.avbl_gpd_num = 0 */ - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_AVAIL_GPD_ERROR = (0x1 << 2), /* Rx GPD.hwo = 0 */ - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_GPD_CHKSM_ERROR = (0x1 << 3), /* Rx GPD.chksm is error */ - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_DMA_READ_ERROR = (0x1 << 4), /* DMAR error occurs in PCIE */ - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_DMA_WRITE_ERROR = (0x1 << 5), /* DMAW error occurs in PCIE */ - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_STOP_CMD_CPLT = (0x1 << 6), /* Stop Completion Acknowledge */ - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_GPD_GT255_ERROR = (0x1 << 7), /* Multi-GPD packet's GPD# > 255 */ - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_TOD_UNINIT = (0x1 << 8), /* */ - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_PKT_ERROR_DROP = (0x1 << 9), /* */ - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_UDSZ_DROP = (0x1 << 10), /* */ - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_OVSZ_DROP = (0x1 << 11), /* */ - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_CMDQ_OVF_DROP = (0x1 << 12), /* */ - HAL_TAU_PKT_RX_CHANNEL_L2_ISR_FIFO_OVF_DROP = (0x1 << 13) + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_AVAIL_GPD_LOW = (0x1UL << 0), /* Rx GPD.avbl_gpd_num < threshold */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_AVAIL_GPD_EMPTY = (0x1UL << 1), /* Rx GPD.avbl_gpd_num = 0 */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_AVAIL_GPD_ERROR = (0x1UL << 2), /* Rx GPD.hwo = 0 */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_GPD_CHKSM_ERROR = (0x1UL << 3), /* Rx GPD.chksm is error */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_DMA_READ_ERROR = (0x1UL << 4), /* DMAR error occurs in PCIE */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_DMA_WRITE_ERROR = (0x1UL << 5), /* DMAW error occurs in PCIE */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_STOP_CMD_CPLT = (0x1UL << 6), /* Stop Completion Acknowledge */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_GPD_GT255_ERROR = (0x1UL << 7), /* Multi-GPD packet's GPD# > 255 */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_TOD_UNINIT = (0x1UL << 8), /* */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_PKT_ERROR_DROP = (0x1UL << 9), /* */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_UDSZ_DROP = (0x1UL << 10), /* */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_OVSZ_DROP = (0x1UL << 11), /* */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_CMDQ_OVF_DROP = (0x1UL << 12), /* */ + HAL_TAU_PKT_RX_CHANNEL_L2_ISR_FIFO_OVF_DROP = (0x1UL << 13) } HAL_TAU_PKT_RX_CHANNEL_L2_ISR_T; typedef enum { - HAL_TAU_PKT_TX_CHANNEL_CFG_IOC = (0x1 << 0), - HAL_TAU_PKT_TX_CHANNEL_CFG_CHKSUM = (0x1 << 1), - HAL_TAU_PKT_TX_CHANNEL_CFG_PFC = (0x1 << 2), - HAL_TAU_PKT_TX_CHANNEL_CFG_PKT_LEN_CHK = (0x1 << 3), - HAL_TAU_PKT_TX_CHANNEL_CFG_EARLY_DONE_IRQ = (0x1 << 4), - HAL_TAU_PKT_TX_CHANNEL_CFG_CHK_COS = (0x1 << 5), - HAL_TAU_PKT_TX_CHANNEL_CFG_ADV_GPD_WRBK = (0x1 << 6), - HAL_TAU_PKT_TX_CHANNEL_CFG_GPD_WRBK_FULL_PKT_LEN = (0x1 << 7), - HAL_TAU_PKT_TX_CHANNEL_CFG_LAST = (0x1 << 8) + HAL_TAU_PKT_TX_CHANNEL_CFG_IOC = (0x1UL << 0), + HAL_TAU_PKT_TX_CHANNEL_CFG_CHKSUM = (0x1UL << 1), + HAL_TAU_PKT_TX_CHANNEL_CFG_PFC = (0x1UL << 2), + HAL_TAU_PKT_TX_CHANNEL_CFG_PKT_LEN_CHK = (0x1UL << 3), + HAL_TAU_PKT_TX_CHANNEL_CFG_EARLY_DONE_IRQ = (0x1UL << 4), + HAL_TAU_PKT_TX_CHANNEL_CFG_CHK_COS = (0x1UL << 5), + HAL_TAU_PKT_TX_CHANNEL_CFG_ADV_GPD_WRBK = (0x1UL << 6), + HAL_TAU_PKT_TX_CHANNEL_CFG_GPD_WRBK_FULL_PKT_LEN = (0x1UL << 7), + HAL_TAU_PKT_TX_CHANNEL_CFG_LAST = (0x1UL << 8) } HAL_TAU_PKT_TX_CHANNEL_CFG_T; typedef enum { - HAL_TAU_PKT_RX_CHANNEL_CFG_IOC = (0x1 << 0), - HAL_TAU_PKT_RX_CHANNEL_CFG_CHKSUM = (0x1 << 1), - HAL_TAU_PKT_RX_CHANNEL_CFG_LAST = (0x1 << 2) + HAL_TAU_PKT_RX_CHANNEL_CFG_IOC = (0x1UL << 0), + HAL_TAU_PKT_RX_CHANNEL_CFG_CHKSUM = (0x1UL << 1), + HAL_TAU_PKT_RX_CHANNEL_CFG_LAST = (0x1UL << 2) } HAL_TAU_PKT_RX_CHANNEL_CFG_T; @@ -2079,34 +2079,56 @@ typedef struct /* metadata */ UI8_T mac[6]; -#define HAL_TAU_PKT_NETIF_INTF_FLAGS_MAC (1 << 0) +#define HAL_TAU_PKT_NETIF_INTF_FLAGS_MAC (1UL << 0) UI32_T flags; } HAL_TAU_PKT_NETIF_INTF_T; +#if defined(NETIF_EN_NETLINK) +typedef struct +{ + C8_T name[NPS_NETIF_NAME_LEN]; + C8_T mc_group_name[NPS_NETIF_NAME_LEN]; +} HAL_TAU_PKT_NETIF_RX_DST_NETLINK_T; +#endif + +typedef enum +{ + HAL_TAU_PKT_NETIF_RX_DST_SDK = 0, +#if defined(NETIF_EN_NETLINK) + HAL_TAU_PKT_NETIF_RX_DST_NETLINK, +#endif + HAL_TAU_PKT_NETIF_RX_DST_LAST +} HAL_TAU_PKT_NETIF_RX_DST_TYPE_T; + typedef struct { /* unique key */ - UI32_T id; - C8_T name[NPS_NETIF_NAME_LEN]; - UI32_T priority; + UI32_T id; + C8_T name[NPS_NETIF_NAME_LEN]; + UI32_T priority; /* match fields */ - UI32_T port; /* only support unit port and local port */ - HAL_TAU_PKT_RX_REASON_BITMAP_T reason_bitmap; - UI8_T pattern[NPS_NETIF_PROFILE_PATTERN_NUM][NPS_NETIF_PROFILE_PATTERN_LEN]; - UI8_T mask[NPS_NETIF_PROFILE_PATTERN_NUM][NPS_NETIF_PROFILE_PATTERN_LEN]; - UI32_T offset[NPS_NETIF_PROFILE_PATTERN_NUM]; + UI32_T port; /* only support unit port and local port */ + HAL_PKT_RX_REASON_BITMAP_T reason_bitmap; + UI8_T pattern[NPS_NETIF_PROFILE_PATTERN_NUM][NPS_NETIF_PROFILE_PATTERN_LEN]; + UI8_T mask[NPS_NETIF_PROFILE_PATTERN_NUM][NPS_NETIF_PROFILE_PATTERN_LEN]; + UI32_T offset[NPS_NETIF_PROFILE_PATTERN_NUM]; /* for each flag 1:must hit, 0:don't care */ -#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_PORT (1 << 0) -#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_REASON (1 << 1) -#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_PATTERN_0 (1 << 2) -#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_PATTERN_1 (1 << 3) -#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_PATTERN_2 (1 << 4) -#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_PATTERN_3 (1 << 5) - UI32_T flags; +#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_PORT (1UL << 0) +#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_REASON (1UL << 1) +#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_PATTERN_0 (1UL << 2) +#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_PATTERN_1 (1UL << 3) +#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_PATTERN_2 (1UL << 4) +#define HAL_TAU_PKT_NETIF_PROFILE_FLAGS_PATTERN_3 (1UL << 5) + UI32_T flags; + + HAL_TAU_PKT_NETIF_RX_DST_TYPE_T dst_type; +#if defined(NETIF_EN_NETLINK) + HAL_TAU_PKT_NETIF_RX_DST_NETLINK_T netlink; +#endif } HAL_TAU_PKT_NETIF_PROFILE_T; @@ -2141,6 +2163,13 @@ typedef enum HAL_TAU_PKT_IOCTL_TYPE_CLEAR_RX_CNT, /* port attribute */ HAL_TAU_PKT_IOCTL_TYPE_SET_PORT_ATTR, +#if defined(NETIF_EN_NETLINK) + HAL_TAU_PKT_IOCTL_TYPE_NL_SET_INTF_PROPERTY, + HAL_TAU_PKT_IOCTL_TYPE_NL_GET_INTF_PROPERTY, + HAL_TAU_PKT_IOCTL_TYPE_NL_CREATE_NETLINK, + HAL_TAU_PKT_IOCTL_TYPE_NL_DESTROY_NETLINK, + HAL_TAU_PKT_IOCTL_TYPE_NL_GET_NETLINK, +#endif HAL_TAU_PKT_IOCTL_TYPE_LAST } HAL_TAU_PKT_IOCTL_TYPE_T; @@ -2219,6 +2248,51 @@ typedef struct } HAL_TAU_PKT_IOCTL_PORT_COOKIE_T; +#if defined(NETIF_EN_NETLINK) + +#define NPS_NETIF_NETLINK_NUM_MAX (256) +#define NPS_NETIF_NETLINK_MC_GROUP_NUM_MAX (32) + +typedef enum +{ + NPS_NETIF_INTF_PROPERTY_IGR_SAMPLING_RATE, + NPS_NETIF_INTF_PROPERTY_EGR_SAMPLING_RATE, + NPS_NETIF_INTF_PROPERTY_LAST +} NPS_NETIF_INTF_PROPERTY_T; + +typedef struct +{ + C8_T name[NPS_NETIF_NAME_LEN]; + +} NPS_NETIF_NETLINK_MC_GROUP_T; + +typedef struct +{ + UI32_T id; + C8_T name[NPS_NETIF_NAME_LEN]; + NPS_NETIF_NETLINK_MC_GROUP_T mc_group[NPS_NETIF_NETLINK_MC_GROUP_NUM_MAX]; + UI32_T mc_group_num; + +} NPS_NETIF_NETLINK_T; + +typedef struct +{ + /* intf property */ + UI32_T intf_id; + NPS_NETIF_INTF_PROPERTY_T property; + UI32_T param0; + UI32_T param1; + + /* netlink */ + NPS_NETIF_NETLINK_T netlink; + + NPS_ERROR_NO_T rc; + +} HAL_TAU_PKT_NL_IOCTL_COOKIE_T; + + +#endif /* End of NETIF_EN_NETLINK */ + typedef union { UI32_T value; @@ -2231,6 +2305,7 @@ typedef union } HAL_TAU_PKT_IOCTL_CMD_T; + #endif /* End of NPS_EN_NETIF */ NPS_ERROR_NO_T diff --git a/platform/nephos/nephos-modules/modules/src/inc/netif_nl.h b/platform/nephos/nephos-modules/modules/src/inc/netif_nl.h new file mode 100755 index 000000000000..4b31ceef1620 --- /dev/null +++ b/platform/nephos/nephos-modules/modules/src/inc/netif_nl.h @@ -0,0 +1,104 @@ +/* Copyright (C) 2020 MediaTek, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program. + */ + + /* FILE NAME: netif_nl.h + * PURPOSE: + * It provide xxx API. + * NOTES: + */ + +#ifndef NETIF_NL_H +#define NETIF_NL_H + +#include + +#define NETIF_NL_NETLINK_MC_GROUP_NUM (32) +#define NETIF_NL_NETLINK_NAME_LEN (16) + +typedef enum +{ + NETIF_NL_INTF_PROPERTY_IGR_SAMPLING_RATE, + NETIF_NL_INTF_PROPERTY_EGR_SAMPLING_RATE, + NETIF_NL_INTF_PROPERTY_LAST +} NETIF_NL_INTF_PROPERTY_T; + +/* must be the same with NPS_NETIF_RX_DST_NETLINK_T */ +typedef struct +{ + C8_T name[NETIF_NL_NETLINK_NAME_LEN]; + C8_T mc_group_name[NETIF_NL_NETLINK_NAME_LEN]; +} NETIF_NL_RX_DST_NETLINK_T; + +/* must be the same with NPS_NETIF_NETLINK_MC_GROUP_T */ +typedef struct +{ + C8_T name[NETIF_NL_NETLINK_NAME_LEN]; + +} NETIF_NL_NETLINK_MC_GROUP_T; + +/* must be the same with NPS_NETIF_NETLINK_T */ +typedef struct +{ + UI32_T id; + C8_T name[NETIF_NL_NETLINK_NAME_LEN]; + NETIF_NL_NETLINK_MC_GROUP_T mc_group[NETIF_NL_NETLINK_MC_GROUP_NUM]; + UI32_T mc_group_num; + +} NETIF_NL_NETLINK_T; + +NPS_ERROR_NO_T +netif_nl_rxSkb( + const UI32_T unit, + struct sk_buff *ptr_skb, + void *ptr_cookie); + +NPS_ERROR_NO_T +netif_nl_setIntfProperty( + const UI32_T unit, + const UI32_T id, + const NETIF_NL_INTF_PROPERTY_T property, + const UI32_T param0, + const UI32_T param1); + +NPS_ERROR_NO_T +netif_nl_getIntfProperty( + const UI32_T unit, + const UI32_T port, + const NETIF_NL_INTF_PROPERTY_T property, + UI32_T *ptr_param0, + UI32_T *ptr_param1); + +NPS_ERROR_NO_T +netif_nl_createNetlink( + const UI32_T unit, + NETIF_NL_NETLINK_T *ptr_netlink, + UI32_T *ptr_netlink_id); + +NPS_ERROR_NO_T +netif_nl_destroyNetlink( + const UI32_T unit, + const UI32_T group_id); + +NPS_ERROR_NO_T +netif_nl_getNetlink( + const UI32_T unit, + const UI32_T netlink_id, + NETIF_NL_NETLINK_T *ptr_netlink); + + +NPS_ERROR_NO_T +netif_nl_init(void); + +#endif /* end of NETIF_NL_H */ diff --git a/platform/nephos/nephos-modules/modules/src/inc/netif_osal.h b/platform/nephos/nephos-modules/modules/src/inc/netif_osal.h index 40c8c9ebc358..93f30fc61ce1 100755 --- a/platform/nephos/nephos-modules/modules/src/inc/netif_osal.h +++ b/platform/nephos/nephos-modules/modules/src/inc/netif_osal.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/platform/nephos/nephos-modules/modules/src/inc/netif_perf.h b/platform/nephos/nephos-modules/modules/src/inc/netif_perf.h index 35596668ba9d..5309f01b62d8 100755 --- a/platform/nephos/nephos-modules/modules/src/inc/netif_perf.h +++ b/platform/nephos/nephos-modules/modules/src/inc/netif_perf.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/platform/nephos/nephos-modules/modules/src/inc/nps_cfg.h b/platform/nephos/nephos-modules/modules/src/inc/nps_cfg.h index 34306344c55a..36de3cc70863 100755 --- a/platform/nephos/nephos-modules/modules/src/inc/nps_cfg.h +++ b/platform/nephos/nephos-modules/modules/src/inc/nps_cfg.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/platform/nephos/nephos-modules/modules/src/inc/nps_error.h b/platform/nephos/nephos-modules/modules/src/inc/nps_error.h index 261878abf3cb..3cf0a14adc0b 100755 --- a/platform/nephos/nephos-modules/modules/src/inc/nps_error.h +++ b/platform/nephos/nephos-modules/modules/src/inc/nps_error.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/platform/nephos/nephos-modules/modules/src/inc/nps_types.h b/platform/nephos/nephos-modules/modules/src/inc/nps_types.h index 5630b521404e..88100f69738f 100755 --- a/platform/nephos/nephos-modules/modules/src/inc/nps_types.h +++ b/platform/nephos/nephos-modules/modules/src/inc/nps_types.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/platform/nephos/nephos-modules/modules/src/inc/osal_mdc.h b/platform/nephos/nephos-modules/modules/src/inc/osal_mdc.h index 47971bb38c8d..0add2c8216b1 100755 --- a/platform/nephos/nephos-modules/modules/src/inc/osal_mdc.h +++ b/platform/nephos/nephos-modules/modules/src/inc/osal_mdc.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public @@ -134,6 +134,8 @@ typedef enum OSAL_MDC_IOCTL_TYPE_MDC_FREE_SYS_DMA_MEM, OSAL_MDC_IOCTL_TYPE_MDC_CONNECT_ISR, OSAL_MDC_IOCTL_TYPE_MDC_DISCONNECT_ISR, + OSAL_MDC_IOCTL_TYPE_MDC_SAVE_PCI_CONFIG, + OSAL_MDC_IOCTL_TYPE_MDC_RESTORE_PCI_CONFIG, OSAL_MDC_IOCTL_TYPE_LAST } OSAL_MDC_IOCTL_TYPE_T; @@ -238,4 +240,12 @@ osal_mdc_invalidateCache( void *ptr_virt_addr, const UI32_T size); +NPS_ERROR_NO_T +osal_mdc_savePciConfig( + const UI32_T unit); + +NPS_ERROR_NO_T +osal_mdc_restorePciConfig( + const UI32_T unit); + #endif /* OSAL_MDC_H */ diff --git a/platform/nephos/nephos-modules/modules/src/inc/osal_types.h b/platform/nephos/nephos-modules/modules/src/inc/osal_types.h index 48ac58aba335..59fd3df1260d 100755 --- a/platform/nephos/nephos-modules/modules/src/inc/osal_types.h +++ b/platform/nephos/nephos-modules/modules/src/inc/osal_types.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/platform/nephos/nephos-modules/modules/src/make.mk b/platform/nephos/nephos-modules/modules/src/make.mk index e556ea10d765..b49da8b43cdf 100755 --- a/platform/nephos/nephos-modules/modules/src/make.mk +++ b/platform/nephos/nephos-modules/modules/src/make.mk @@ -1,5 +1,5 @@ ################################################################################ -# Copyright (C) 2019 Nephos, Inc. +# Copyright (C) 2020 MediaTek, Inc. # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public @@ -17,7 +17,7 @@ DEV_MODULE_NAME := nps_dev NETIF_MODULE_NAME := nps_netif ################################################################################ DEV_OBJS_TOTAL := ./src/osal_mdc.o ./src/osal_isymbol.o -NETIF_OBJS_TOTAL := ./src/hal_tau_pkt_knl.o ./src/netif_perf.o ./src/netif_osal.o +NETIF_OBJS_TOTAL := ./src/hal_tau_pkt_knl.o ./src/netif_perf.o ./src/netif_osal.o ./src/netif_nl.o obj-m := $(DEV_MODULE_NAME).o $(NETIF_MODULE_NAME).o $(DEV_MODULE_NAME)-objs := $(DEV_OBJS_TOTAL) diff --git a/platform/nephos/nephos-modules/modules/src/netif_nl.c b/platform/nephos/nephos-modules/modules/src/netif_nl.c new file mode 100755 index 000000000000..c112e4b6dd80 --- /dev/null +++ b/platform/nephos/nephos-modules/modules/src/netif_nl.c @@ -0,0 +1,811 @@ +/* Copyright (C) 2020 MediaTek, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program. + */ + + /* FILE NAME: netif_xxx.c + * PURPOSE: + * It provide xxx API. + * NOTES: + */ +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +extern UI32_T ext_dbg_flag; + +#define NETIF_NL_DBG(__flag__, ...) do \ +{ \ + if (0 != ((__flag__) & (ext_dbg_flag))) \ + { \ + osal_printf(__VA_ARGS__); \ + } \ +}while (0) + +#define NETIF_NL_DBG_NETLINK (0x1UL << 6) + +#define NETIF_NL_FAMILY_NUM_MAX (256) +#define NETIF_NL_INTF_NUM_MAX (256) + +#define NETIF_NL_GET_FAMILY_META(__idx__) &(_netif_nl_cb.fam_entry[__idx__].meta) +#define NETIF_NL_GET_INTF_IGR_SAMPLE_RATE(__inft_id__) (_netif_nl_cb.intf_entry[__inft_id__].igr_sample_rate) + +#define NETIF_NL_FAMILY_IS_PSAMPLE(__ptr_family__) (0 == strncmp(__ptr_family__->name, \ + NETIF_NL_PSAMPLE_FAMILY_NAME, \ + NETIF_NL_NETLINK_NAME_LEN)) ? 1 : 0 + +/* porting part */ +#define NETIF_NL_VER_NUM (1) +#define NETIF_NL_PSAMPLE_MAX_ATTR_NUM (NETIF_NL_PSAMPLE_ATTR_LAST) +#define NETIF_NL_REGISTER_FAMILY(__family__) genl_register_family(__family__) + +#define NETIF_NL_UNREGISTER_FAMILY(__family__) genl_unregister_family(__family__) +#define NETIF_NL_ALLOC_SKB(__len__) genlmsg_new(__len__, GFP_ATOMIC) +#define NETIF_NL_FREE_SKB(__ptr_skb__) nlmsg_free(__ptr_skb__) + +#define NETIF_NL_SEND_PKT(__ptr_family__, __mcgrp_id__, __ptr_skb__) \ + genlmsg_multicast_netns(__ptr_family__, \ + &init_net, \ + __ptr_skb__, \ + 0, /* pid, avoid loop */ \ + __mcgrp_id__, \ + GFP_ATOMIC) +#define NETIF_NL_SET_SKB_ATTR_HDR(__skb__, __family__, __hdr_len__, __cmd__) \ + genlmsg_put(__skb__, 0, 0, __family__, \ + __hdr_len__, __cmd__) +#define NETIF_NL_END_SKB_ATTR_HDR(__skb__, __hdr__) genlmsg_end(__skb__, __hdr__) + +#define NETIF_NL_SET_16_BIT_ATTR(__skb__, __attr__, __data__) nla_put_u16(__skb__, __attr__, __data__) +#define NETIF_NL_SET_32_BIT_ATTR(__skb__, __attr__, __data__) nla_put_u32(__skb__, __attr__, __data__) + + +/* + * <----------- nla_total_size(payload) -------------> + * +------------------+- - -+- - - - - - - - - +- - -+ + * | Attribute Header | Pad | Payload | Pad | + * +------------------+- - -+- - - - - - - - - +- - -+ + * + * + * <-------- nla_attr_size(payload) ----------> + * +------------------+- - -+- - - - - - - - - +- - -+ + * | Attribute Header | Pad | Payload | Pad | + * +------------------+- - -+- - - - - - - - - +- - -+ + * + */ +/* total size = attr data size + attr header size */ +#define NETIF_NL_GET_ATTR_TOTAL_SIZE(__data_size__) nla_total_size(__data_size__) +#define NETIF_NL_GET_ATTR_SIZE(__data_size__) nla_attr_size(__data_size__) /* without padding */ + + +/* psample's family and group parameter */ +#define NETIF_NL_PSAMPLE_FAMILY_NAME "psample" +#define NETIF_NL_PSAMPLE_MC_GROUP_NAME_DATA "packets" +#define NETIF_NL_PSAMPLE_MC_GROUP_NAME_CFG "config" +#define NETIF_NL_PSAMPLE_MC_GROUP_NUM (NETIF_NL_PSAMPLE_MC_GROUP_ID_LAST) +#define NETIF_NL_DEFAULT_MC_GROUP_NUM (1) + +#define NETIF_NL_PSAMPLE_PKT_LEN_MAX (9216) +#define NETIF_NL_PSAMPLE_DFLT_USR_GROUP_ID (1) + +typedef enum +{ + NETIF_NL_PSAMPLE_MC_GROUP_ID_CONFIG = 0, + NETIF_NL_PSAMPLE_MC_GROUP_ID_SAMPLE, + NETIF_NL_PSAMPLE_MC_GROUP_ID_LAST, +} NETIF_NL_PSAMPLE_MC_GROUP_ID_T; + +typedef enum +{ + NETIF_NL_PSAMPLE_ATTR_IIFINDEX = 0, + NETIF_NL_PSAMPLE_ATTR_OIFINDEX, + NETIF_NL_PSAMPLE_ATTR_ORIGSIZE, + NETIF_NL_PSAMPLE_ATTR_SAMPLE_GROUP, + NETIF_NL_PSAMPLE_ATTR_GROUP_SEQ, + NETIF_NL_PSAMPLE_ATTR_SAMPLE_RATE, + NETIF_NL_PSAMPLE_ATTR_DATA, + NETIF_NL_PSAMPLE_ATTR_LAST +} NETIF_NL_PSAMPLE_ATTR_ID_T; + + +typedef struct genl_multicast_group NETIF_NL_MC_GROUP_T; +typedef struct genl_family NETIF_NL_FAMILY_T; + +static NETIF_NL_MC_GROUP_T _netif_nl_psample_mc_group[NETIF_NL_PSAMPLE_MC_GROUP_ID_LAST]; +static C8_T *_ptr_netif_nl_psample_mc_group_name[NETIF_NL_PSAMPLE_MC_GROUP_ID_LAST] = + { + NETIF_NL_PSAMPLE_MC_GROUP_NAME_CFG, + NETIF_NL_PSAMPLE_MC_GROUP_NAME_DATA + }; + +static NETIF_NL_MC_GROUP_T _netif_nl_default_mc_group[NETIF_NL_DEFAULT_MC_GROUP_NUM]; +static C8_T *_ptr_netif_nl_default_mc_group_name[NETIF_NL_DEFAULT_MC_GROUP_NUM] = + { + "default", + }; + +typedef struct +{ + NETIF_NL_FAMILY_T meta; + BOOL_T valid; + +} NETIF_NL_FAMILY_ENTRY_T; + +typedef struct +{ + UI32_T igr_sample_rate; + UI32_T egr_sample_rate; + UI32_T trunc_size; +} NETIF_NL_INTF_ENTRY_T; + +typedef struct +{ + NETIF_NL_FAMILY_ENTRY_T fam_entry[NETIF_NL_FAMILY_NUM_MAX]; + NETIF_NL_INTF_ENTRY_T intf_entry[NETIF_NL_INTF_NUM_MAX]; /* sorted in intf_id */ + UI32_T seq_num; +} NETIF_NL_CB_T; + +static NETIF_NL_CB_T _netif_nl_cb; + +/* should extract to common */ +struct net_device_priv +{ + struct net_device *ptr_net_dev; + struct net_device_stats stats; + UI32_T unit; + UI32_T id; + UI32_T port; + UI16_T vlan; + UI32_T speed; +}; + +static NPS_ERROR_NO_T +_netif_nl_setIntfIgrSampleRate( + const UI32_T unit, + const UI32_T id, + const UI32_T rate) +{ + NETIF_NL_CB_T *ptr_cb = &_netif_nl_cb; + + ptr_cb->intf_entry[id].igr_sample_rate = rate; + + return (NPS_E_OK); +} + +static NPS_ERROR_NO_T +_netif_nl_setIntfEgrSampleRate( + const UI32_T unit, + const UI32_T id, + const UI32_T rate) +{ + NETIF_NL_CB_T *ptr_cb = &_netif_nl_cb; + + ptr_cb->intf_entry[id].egr_sample_rate = rate; + + return (NPS_E_OK); +} + + +NPS_ERROR_NO_T +netif_nl_setIntfProperty( + const UI32_T unit, + const UI32_T id, + const NETIF_NL_INTF_PROPERTY_T property, + const UI32_T param0, + const UI32_T param1) +{ + NPS_ERROR_NO_T rc = NPS_E_BAD_PARAMETER; + + if (NETIF_NL_INTF_PROPERTY_IGR_SAMPLING_RATE == property) + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "receive set igr sample rate req, id=%d, property=%d, param0=%d, param=%d\n", + id, property, param0, param1); + rc = _netif_nl_setIntfIgrSampleRate(unit, id, param0); + } + else if (NETIF_NL_INTF_PROPERTY_EGR_SAMPLING_RATE == property) + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "receive set egr sample rate req, id=%d, property=%d, param0=%d, param=%d\n", + id, property, param0, param1); + rc = _netif_nl_setIntfEgrSampleRate(unit, id, param0); + } + else + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[error] unknown property, property=%d\n", property); + } + + return (rc); +} + +static NPS_ERROR_NO_T +_netif_nl_getIntfIgrSampleRate( + const UI32_T unit, + const UI32_T id, + UI32_T *ptr_rate) +{ + NETIF_NL_CB_T *ptr_cb = &_netif_nl_cb; + + *ptr_rate = ptr_cb->intf_entry[id].igr_sample_rate; + + return (NPS_E_OK); +} + +static NPS_ERROR_NO_T +_netif_nl_getIntfEgrSampleRate( + const UI32_T unit, + const UI32_T id, + UI32_T *ptr_rate) +{ + NETIF_NL_CB_T *ptr_cb = &_netif_nl_cb; + + *ptr_rate = ptr_cb->intf_entry[id].egr_sample_rate; + + return (NPS_E_OK); +} + + +NPS_ERROR_NO_T +netif_nl_getIntfProperty( + const UI32_T unit, + const UI32_T id, + const NETIF_NL_INTF_PROPERTY_T property, + UI32_T *ptr_param0, + UI32_T *ptr_param1) +{ + NPS_ERROR_NO_T rc = NPS_E_BAD_PARAMETER; + + if (NETIF_NL_INTF_PROPERTY_IGR_SAMPLING_RATE == property) + { + rc = _netif_nl_getIntfIgrSampleRate(unit, id, ptr_param0); + } + else if (NETIF_NL_INTF_PROPERTY_EGR_SAMPLING_RATE == property) + { + rc = _netif_nl_getIntfEgrSampleRate(unit, id, ptr_param0); + } + else + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[error] unknown property, property=%d\n", + property); + } + + return (rc); +} + +NPS_ERROR_NO_T +_netif_nl_allocNlFamilyEntry( + NETIF_NL_CB_T *ptr_cb, + UI32_T *ptr_index) +{ + UI32_T idx; + NPS_ERROR_NO_T rc = NPS_E_TABLE_FULL; + + for (idx = 0; idx < NETIF_NL_FAMILY_NUM_MAX; idx++) + { + if (FALSE == ptr_cb->fam_entry[idx].valid) + { + *ptr_index = idx; + ptr_cb->fam_entry[idx].valid = TRUE; + rc = NPS_E_OK; + break; + } + } + + return (rc); +} + +void +_netif_nl_freeNlFamilyEntry( + NETIF_NL_CB_T *ptr_cb, + const UI32_T index) +{ + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[DBG] free netlink family entry, idx=%d\n", + index); + ptr_cb->fam_entry[index].valid = FALSE; +} + +NPS_ERROR_NO_T +_netif_nl_setNlMcgroupPsample( + NETIF_NL_FAMILY_T *ptr_nl_family) +{ + NETIF_NL_MC_GROUP_T *ptr_nl_mc_group = _netif_nl_psample_mc_group; + UI32_T idx; + + /* init the mc group and hook the group to family */ + osal_memset(ptr_nl_mc_group, 0x0, + (NETIF_NL_PSAMPLE_MC_GROUP_NUM * sizeof(NETIF_NL_MC_GROUP_T))); + + for (idx = 0; idx < NETIF_NL_PSAMPLE_MC_GROUP_ID_LAST; idx++) + { + osal_memcpy(ptr_nl_mc_group[idx].name, + _ptr_netif_nl_psample_mc_group_name[idx], + osal_strlen(_ptr_netif_nl_psample_mc_group_name[idx])); + } + ptr_nl_family->n_mcgrps = NETIF_NL_PSAMPLE_MC_GROUP_NUM; + ptr_nl_family->mcgrps = ptr_nl_mc_group; + + return (NPS_E_OK); +} + +NPS_ERROR_NO_T +_netif_nl_setNlMcgroupDefault( + NETIF_NL_FAMILY_T *ptr_nl_family) +{ + NETIF_NL_MC_GROUP_T *ptr_nl_mc_group = _netif_nl_default_mc_group; + UI32_T idx; + + /* init the mc group and hook the group to family */ + osal_memset(ptr_nl_mc_group, 0x0, + (NETIF_NL_DEFAULT_MC_GROUP_NUM * sizeof(NETIF_NL_MC_GROUP_T))); + + for (idx = 0; idx < NETIF_NL_DEFAULT_MC_GROUP_NUM; idx++) + { + osal_memcpy(ptr_nl_mc_group[idx].name, + _ptr_netif_nl_default_mc_group_name[idx], + osal_strlen(_ptr_netif_nl_default_mc_group_name[idx])); + } + ptr_nl_family->n_mcgrps = NETIF_NL_DEFAULT_MC_GROUP_NUM; + ptr_nl_family->mcgrps = ptr_nl_mc_group; + + return (NPS_E_OK); +} + +#define NETIF_NL_IS_FAMILY_ENTRY_VALID(__idx__) \ + (TRUE == _netif_nl_cb.fam_entry[__idx__].valid) ? (TRUE) : (FALSE) +NPS_ERROR_NO_T +netif_nl_createNetlink( + const UI32_T unit, + NETIF_NL_NETLINK_T *ptr_netlink, + UI32_T *ptr_netlink_id) +{ + NETIF_NL_CB_T *ptr_cb = &_netif_nl_cb; + UI32_T entry_id; + NETIF_NL_FAMILY_T *ptr_nl_family; + NETIF_NL_MC_GROUP_T *ptr_nl_mcgrp; + UI32_T idx; + int ret; + NPS_ERROR_NO_T rc; + + rc = _netif_nl_allocNlFamilyEntry(ptr_cb, &entry_id); + if (NPS_E_OK == rc) + { + ptr_nl_family = NETIF_NL_GET_FAMILY_META(entry_id); + + /* fill in the meta data for that netlink family */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) + ptr_nl_family->id = GENL_ID_GENERATE; /* family id can be ignored since linux 4.10 */ +#endif + ptr_nl_family->version = NETIF_NL_VER_NUM; + ptr_nl_family->maxattr = NETIF_NL_PSAMPLE_MAX_ATTR_NUM; + ptr_nl_family->netnsok = true; + osal_memcpy(ptr_nl_family->name, ptr_netlink->name, NETIF_NL_NETLINK_NAME_LEN); + + /* fill in the mc group info */ + ptr_nl_mcgrp = osal_alloc(sizeof(NETIF_NL_MC_GROUP_T)*ptr_netlink->mc_group_num); + if (NULL != ptr_nl_mcgrp) + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, "[DBG] create mc group:\n"); + for (idx = 0; idx < ptr_netlink->mc_group_num; idx++) + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[DBG] - mcgrp%d: %s\n", idx, ptr_netlink->mc_group[idx].name); + osal_memcpy(ptr_nl_mcgrp[idx].name, ptr_netlink->mc_group[idx].name, + NETIF_NL_NETLINK_NAME_LEN); + } + ptr_nl_family->n_mcgrps = ptr_netlink->mc_group_num; + ptr_nl_family->mcgrps = ptr_nl_mcgrp; + + /* register the family to kernel */ + ret = NETIF_NL_REGISTER_FAMILY(ptr_nl_family); + if (0 == ret) + { + *ptr_netlink_id = entry_id; + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[DBG] create netlink family, name=%s, entry_idx=%d, mcgrp_num=%d\n", + ptr_netlink->name, entry_id, ptr_nl_family->n_mcgrps); + rc = NPS_E_OK; + } + else + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[DBG] register netlink family failed, name=%s, ret=%d\n", + ptr_netlink->name, ret); + osal_free(ptr_nl_mcgrp); + _netif_nl_freeNlFamilyEntry(ptr_cb, entry_id); + rc = NPS_E_OTHERS; + } + } + else + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, "[DBG] alloc mcgrp failed\n"); + rc = NPS_E_NO_MEMORY; + } + } + + return (rc); +} + +NPS_ERROR_NO_T +netif_nl_destroyNetlink( + const UI32_T unit, + const UI32_T netlink_id) +{ + NETIF_NL_CB_T *ptr_cb = &_netif_nl_cb; + UI32_T entry_idx = netlink_id; + NETIF_NL_FAMILY_T *ptr_nl_family; + int ret; + NPS_ERROR_NO_T rc; + + if (TRUE == NETIF_NL_IS_FAMILY_ENTRY_VALID(entry_idx)) + { + ptr_nl_family = NETIF_NL_GET_FAMILY_META(entry_idx); + ret = NETIF_NL_UNREGISTER_FAMILY(ptr_nl_family); + if (0 == ret) + { + osal_free(ptr_nl_family->mcgrps); + _netif_nl_freeNlFamilyEntry(ptr_cb, entry_idx); + rc = NPS_E_OK; + } + else + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[DBG] unregister netlink family failed, name=%s, ret=%d\n", + ptr_nl_family->name, ret); + rc = NPS_E_OTHERS; + } + } + else + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[DBG] destroy netlink failed, invalid netlink_id %d\n", + netlink_id); + rc = NPS_E_ENTRY_NOT_FOUND; + } + + return (rc); +} + +NPS_ERROR_NO_T +netif_nl_getNetlink( + const UI32_T unit, + const UI32_T netlink_id, + NETIF_NL_NETLINK_T *ptr_netlink) +{ + UI32_T entry_idx = netlink_id; + NETIF_NL_FAMILY_T *ptr_meta; + UI32_T grp_idx; + NPS_ERROR_NO_T rc = NPS_E_OK; + + if (TRUE == NETIF_NL_IS_FAMILY_ENTRY_VALID(entry_idx)) + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[DBG] get valid netlink, id=%d\n", netlink_id); + + ptr_netlink->id = netlink_id; + ptr_meta = NETIF_NL_GET_FAMILY_META(entry_idx); + + ptr_netlink->mc_group_num = ptr_meta->n_mcgrps; + osal_memcpy(ptr_netlink->name, ptr_meta->name, NETIF_NL_NETLINK_NAME_LEN); + + for (grp_idx = 0; grp_idx < ptr_meta->n_mcgrps; grp_idx++) + { + osal_memcpy(ptr_netlink->mc_group[grp_idx].name, + ptr_meta->mcgrps[grp_idx].name, + NETIF_NL_NETLINK_NAME_LEN); + } + } + else + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[DBG] get netlink failed, invalid netlink_id %d\n", + netlink_id); + rc = NPS_E_ENTRY_NOT_FOUND; + } + + return (rc); +} + + +NPS_ERROR_NO_T +_netif_nl_getFamilyByName( + NETIF_NL_CB_T *ptr_cb, + const C8_T *ptr_name, + NETIF_NL_FAMILY_T **pptr_nl_family) +{ + UI32_T idx; + NPS_ERROR_NO_T rc = NPS_E_ENTRY_NOT_FOUND; + + for (idx = 0; idx < NETIF_NL_FAMILY_NUM_MAX; idx++) + { + if ((TRUE == ptr_cb->fam_entry[idx].valid) && + (0 == strncmp(ptr_cb->fam_entry[idx].meta.name, + ptr_name, + NETIF_NL_NETLINK_NAME_LEN))) + { + *pptr_nl_family = &(ptr_cb->fam_entry[idx].meta); + rc = NPS_E_OK; + break; + } + } + + if (NPS_E_ENTRY_NOT_FOUND == rc) + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[DBG] find family failed, name=%s\n", + ptr_name); + } + + return (rc); +} + +NPS_ERROR_NO_T +_netif_nl_getMcgrpIdByName( + NETIF_NL_FAMILY_T *ptr_nl_family, + const C8_T *ptr_mcgrp_name, + UI32_T *ptr_mcgrp_id) +{ + UI32_T idx; + NPS_ERROR_NO_T rc = NPS_E_ENTRY_NOT_FOUND; + + for (idx = 0; idx < ptr_nl_family->n_mcgrps; idx++) + { + if ((0 == strncmp(ptr_nl_family->mcgrps[idx].name, + ptr_mcgrp_name, + NETIF_NL_NETLINK_NAME_LEN))) + { + *ptr_mcgrp_id = idx; + rc = NPS_E_OK; + break; + } + } + + if (NPS_E_OK != rc) + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[DBG] find mcgrp %s failed in family %s\n", + ptr_mcgrp_name, ptr_nl_family->name); + } + + return (rc); +} + +NPS_ERROR_NO_T +_netif_nl_allocPsampleSkb( + NETIF_NL_CB_T *ptr_cb, + NETIF_NL_FAMILY_T *ptr_nl_family, + struct sk_buff *ptr_ori_skb, + struct sk_buff **pptr_nl_skb) +{ + UI32_T msg_hdr_len; + UI32_T data_len; + struct sk_buff *ptr_nl_skb; + UI16_T igr_intf_idx; + struct net_device_priv *ptr_priv; + UI32_T rate; + UI32_T intf_id; + void *ptr_nl_hdr = NULL; + struct nlattr *ptr_nl_attr; + NPS_ERROR_NO_T rc = NPS_E_OK; + + /* make sure the total len (original pkt len + hdr msg) < PSAMPLE_MAX_PACKET_SIZE */ + + msg_hdr_len = NETIF_NL_GET_ATTR_TOTAL_SIZE(sizeof(UI16_T)) + /* PSAMPLE_ATTR_IIFINDEX */ + NETIF_NL_GET_ATTR_TOTAL_SIZE(sizeof(UI32_T)) + /* PSAMPLE_ATTR_SAMPLE_RATE */ + NETIF_NL_GET_ATTR_TOTAL_SIZE(sizeof(UI32_T)) + /* PSAMPLE_ATTR_ORIGSIZE */ + NETIF_NL_GET_ATTR_TOTAL_SIZE(sizeof(UI32_T)) + /* PSAMPLE_ATTR_SAMPLE_GROUP */ + NETIF_NL_GET_ATTR_TOTAL_SIZE(sizeof(UI32_T)); /* PSAMPLE_ATTR_GROUP_SEQ */ + + data_len = NETIF_NL_GET_ATTR_TOTAL_SIZE(ptr_ori_skb->len); + + if ((msg_hdr_len + NETIF_NL_GET_ATTR_TOTAL_SIZE(ptr_ori_skb->len)) > NETIF_NL_PSAMPLE_PKT_LEN_MAX) + { + data_len = NETIF_NL_PSAMPLE_PKT_LEN_MAX - msg_hdr_len - NLA_HDRLEN - NLA_ALIGNTO; + } + else + { + data_len = ptr_ori_skb->len; + } + + ptr_nl_skb = NETIF_NL_ALLOC_SKB(NETIF_NL_GET_ATTR_TOTAL_SIZE(data_len) + msg_hdr_len); + if (NULL != ptr_nl_skb) + { + /* to create a netlink msg header (cmd=0) */ + ptr_nl_hdr = NETIF_NL_SET_SKB_ATTR_HDR(ptr_nl_skb, ptr_nl_family, 0, 0); + if (NULL != ptr_nl_hdr) + { + /* obtain the intf index for the igr_port */ + igr_intf_idx = ptr_ori_skb->dev->ifindex; + NETIF_NL_SET_16_BIT_ATTR(ptr_nl_skb, NETIF_NL_PSAMPLE_ATTR_IIFINDEX, + (UI16_T)igr_intf_idx); + + /* meta header */ + /* use the igr port id as the index for the database to get sample rate */ + ptr_priv = netdev_priv(ptr_ori_skb->dev); + intf_id = ptr_priv->port; + rate = NETIF_NL_GET_INTF_IGR_SAMPLE_RATE(intf_id); + NETIF_NL_SET_32_BIT_ATTR(ptr_nl_skb, NETIF_NL_PSAMPLE_ATTR_SAMPLE_RATE, rate); + NETIF_NL_SET_32_BIT_ATTR(ptr_nl_skb, NETIF_NL_PSAMPLE_ATTR_ORIGSIZE, data_len); + NETIF_NL_SET_32_BIT_ATTR(ptr_nl_skb, NETIF_NL_PSAMPLE_ATTR_SAMPLE_GROUP, + NETIF_NL_PSAMPLE_DFLT_USR_GROUP_ID); + NETIF_NL_SET_32_BIT_ATTR(ptr_nl_skb, NETIF_NL_PSAMPLE_ATTR_GROUP_SEQ, ptr_cb->seq_num); + ptr_cb->seq_num++; + + /* data */ + ptr_nl_attr = (struct nlattr *)skb_put(ptr_nl_skb, NETIF_NL_GET_ATTR_TOTAL_SIZE(data_len)); + ptr_nl_attr->nla_type = NETIF_NL_PSAMPLE_ATTR_DATA; + /* get the attr size without padding, since it's the last one */ + ptr_nl_attr->nla_len = NETIF_NL_GET_ATTR_SIZE(data_len); + skb_copy_bits(ptr_ori_skb, 0, nla_data(ptr_nl_attr), data_len); + + NETIF_NL_END_SKB_ATTR_HDR(ptr_nl_skb, ptr_nl_hdr); + } + else + { + rc = NPS_E_OTHERS; + } + } + else + { + rc = NPS_E_OTHERS; + } + + *pptr_nl_skb = ptr_nl_skb; + + return (rc); +} + +NPS_ERROR_NO_T +_netif_nl_allocNetlinkSkb( + NETIF_NL_CB_T *ptr_cb, + NETIF_NL_FAMILY_T *ptr_nl_family, + struct sk_buff *ptr_ori_skb, + struct sk_buff **pptr_nl_skb) +{ + NPS_ERROR_NO_T rc = NPS_E_OK; + + /* need to fill specific skb header format */ + if (NETIF_NL_FAMILY_IS_PSAMPLE(ptr_nl_family)) + { + rc = _netif_nl_allocPsampleSkb(ptr_cb, ptr_nl_family, + ptr_ori_skb, pptr_nl_skb); + if (NPS_E_OK != rc) + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[DBG] alloc netlink skb failed\n"); + } + } + else + { + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "[DBG] unknown netlink family\n"); + rc = NPS_E_OTHERS; + } + + return (rc); +} + +NPS_ERROR_NO_T +_netif_nl_sendNetlinkSkb( + NETIF_NL_FAMILY_T *ptr_nl_family, + UI32_T nl_mcgrp_id, + struct sk_buff *ptr_nl_skb) +{ + int ret; + NPS_ERROR_NO_T rc; + + ret = NETIF_NL_SEND_PKT(ptr_nl_family, nl_mcgrp_id, ptr_nl_skb); + if (0 == ret) + { + rc = NPS_E_OK; + } + else + { + /* in errno_base.h, #define ESRCH 3 : No such process */ + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, + "send skb to mc group failed, ret=%d\n", ret); + rc = NPS_E_OTHERS; + } + + return (rc); +} + +void +_netif_nl_freeNetlinkSkb( + struct sk_buff *ptr_nl_skb) +{ + NETIF_NL_DBG(NETIF_NL_DBG_NETLINK, "[DBG] free nl skb\n"); + NETIF_NL_FREE_SKB(ptr_nl_skb); +} + +NPS_ERROR_NO_T +_netif_nl_forwardPkt( + NETIF_NL_CB_T *ptr_cb, + NETIF_NL_RX_DST_NETLINK_T *ptr_nl_dest, + struct sk_buff *ptr_ori_skb) +{ + struct sk_buff *ptr_nl_skb = NULL; + NETIF_NL_FAMILY_T *ptr_nl_family; + UI32_T nl_mcgrp_id; + NPS_ERROR_NO_T rc; + + rc = _netif_nl_getFamilyByName(ptr_cb, ptr_nl_dest->name, + &ptr_nl_family); + if (NPS_E_OK == rc) + { + rc = _netif_nl_getMcgrpIdByName(ptr_nl_family, ptr_nl_dest->mc_group_name, + &nl_mcgrp_id); + if (NPS_E_OK == rc) + { + rc = _netif_nl_allocNetlinkSkb(ptr_cb, ptr_nl_family, + ptr_ori_skb, &ptr_nl_skb); + if (NPS_E_OK == rc) + { + rc = _netif_nl_sendNetlinkSkb(ptr_nl_family, nl_mcgrp_id, + ptr_nl_skb); + if (NPS_E_OK != rc) + { + /* _netif_nl_freeNetlinkSkb(ptr_nl_skb); */ + } + } + } + } + + return (rc); +} + +NPS_ERROR_NO_T +netif_nl_rxSkb( + const UI32_T unit, + struct sk_buff *ptr_skb, + void *ptr_cookie) +{ + NETIF_NL_CB_T *ptr_cb = &_netif_nl_cb; + + NETIF_NL_RX_DST_NETLINK_T *ptr_nl_dest; + NPS_ERROR_NO_T rc; + + ptr_nl_dest = (NETIF_NL_RX_DST_NETLINK_T *)ptr_cookie; + + /* send the packet to netlink mcgroup */ + rc = _netif_nl_forwardPkt(ptr_cb, ptr_nl_dest, ptr_skb); + + /* need to free the original skb anyway */ + osal_skb_free(ptr_skb); + + return (rc); +} + +NPS_ERROR_NO_T +netif_nl_init(void) +{ + osal_memset(&_netif_nl_cb, 0x0, sizeof(NETIF_NL_CB_T)); + + return (NPS_E_OK); +} + +NPS_ERROR_NO_T +netif_nl_deinit(void) +{ + return (NPS_E_OK); +} + diff --git a/platform/nephos/nephos-modules/modules/src/netif_osal.c b/platform/nephos/nephos-modules/modules/src/netif_osal.c index 15599e3a0aa0..51af7fcb3ad9 100755 --- a/platform/nephos/nephos-modules/modules/src/netif_osal.c +++ b/platform/nephos/nephos-modules/modules/src/netif_osal.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/platform/nephos/nephos-modules/modules/src/netif_perf.c b/platform/nephos/nephos-modules/modules/src/netif_perf.c index 18606d6d25d4..11dd03b58eb5 100755 --- a/platform/nephos/nephos-modules/modules/src/netif_perf.c +++ b/platform/nephos/nephos-modules/modules/src/netif_perf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/platform/nephos/nephos-modules/modules/src/osal_isymbol.c b/platform/nephos/nephos-modules/modules/src/osal_isymbol.c index c23cc70bed23..f908c2325966 100755 --- a/platform/nephos/nephos-modules/modules/src/osal_isymbol.c +++ b/platform/nephos/nephos-modules/modules/src/osal_isymbol.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/platform/nephos/nephos-modules/modules/src/osal_mdc.c b/platform/nephos/nephos-modules/modules/src/osal_mdc.c index 3dad3173ac79..d0a25e48fc32 100755 --- a/platform/nephos/nephos-modules/modules/src/osal_mdc.c +++ b/platform/nephos/nephos-modules/modules/src/osal_mdc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Nephos, Inc. +/* Copyright (C) 2020 MediaTek, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public @@ -37,7 +37,7 @@ #include #include #include - +#include #include #include @@ -685,6 +685,7 @@ _osal_mdc_removePciCallback( iounmap(ptr_dev->ptr_mmio_virt_addr); pci_release_region(pdev, OSAL_MDC_PCI_BAR0_OFFSET); pci_disable_device(pdev); + _osal_mdc_cb.dev_num--; } static struct pci_device_id _osal_mdc_id_table[] = @@ -708,6 +709,7 @@ _osal_mdc_probePciDevice(void) if (pci_register_driver(&_osal_mdc_pci_driver) < 0) { + OSAL_MDC_ERR("Cannot find PCI device\n"); rc = NPS_E_OTHERS; } return (rc); @@ -720,6 +722,119 @@ _osal_mdc_removePciDevice(void) return (NPS_E_OK); } +static NPS_ERROR_NO_T +_osal_mdc_maskStatus( + const UI32_T unit) +{ + struct pci_dev *ptr_ep_dev = _osal_mdc_cb.dev[unit].ptr_pci_dev; + struct pci_dev *ptr_rc_dev = ptr_ep_dev->bus->self; + int ext_cap = 0; + UI32_T data_32 = 0; + + ext_cap = pci_find_ext_capability(ptr_rc_dev, 0x1); + if (0 != ext_cap) + { + /* Mask */ + pci_read_config_dword(ptr_rc_dev, ext_cap + 0x8, &data_32); + data_32 |= 0x20; + pci_write_config_dword(ptr_rc_dev, ext_cap + 0x8, data_32); + } + + return NPS_E_OK; +} + +static NPS_ERROR_NO_T +_osal_mdc_clearStatus( + const UI32_T unit) +{ + struct pci_dev *ptr_ep_dev = _osal_mdc_cb.dev[unit].ptr_pci_dev; + struct pci_dev *ptr_rc_dev = ptr_ep_dev->bus->self; + int ext_cap = 0; + UI32_T data_32 = 0; + + ext_cap = pci_find_ext_capability(ptr_rc_dev, 0x1); + if (0 != ext_cap) + { + /* Clear */ + pci_write_config_word(ptr_rc_dev, ptr_rc_dev->pcie_cap + 0xa, 0x04); + pci_write_config_word(ptr_rc_dev, ptr_rc_dev->pcie_cap + 0x12, 0x8000); + pci_write_config_dword(ptr_rc_dev, ext_cap + 0x4, 0x20); + + /* UnMask */ + pci_read_config_dword(ptr_rc_dev, ext_cap + 0x8, &data_32); + data_32 &= ~0x20; + pci_write_config_dword(ptr_rc_dev, ext_cap + 0x8, data_32); + } + + return NPS_E_OK; +} + +static NPS_ERROR_NO_T +_osal_mdc_savePciConfig( + const UI32_T unit) +{ + struct pci_dev *ptr_dev = _osal_mdc_cb.dev[unit].ptr_pci_dev; + NPS_ERROR_NO_T rc = NPS_E_OK; + + rc = _osal_mdc_maskStatus(unit); + + if (NPS_E_OK == rc) + { + pci_save_state(ptr_dev); + } + + return rc; +} + +static NPS_ERROR_NO_T +_osal_mdc_restorePciConfig( + const UI32_T unit) +{ +#define OSAL_MDC_PCI_PRESENT_POLL_CNT (100) +#define OSAL_MDC_PCI_PRESENT_POLL_INTERVAL (10) /* ms */ + + struct pci_dev *ptr_dev = _osal_mdc_cb.dev[unit].ptr_pci_dev; + UI32_T poll_cnt = 0; + NPS_ERROR_NO_T rc = NPS_E_OK; + + /* standard: at least 100ms for link recovery */ + msleep(100); + + /* make sure pci device is there before restoring the config space */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) + while ((0 == pci_device_is_present(ptr_dev)) && +#else + while ((0 == pci_dev_present(_osal_mdc_id_table)) && +#endif + (poll_cnt < OSAL_MDC_PCI_PRESENT_POLL_CNT)) + { + msleep(OSAL_MDC_PCI_PRESENT_POLL_INTERVAL); + poll_cnt++; + } + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) + if (1 == pci_device_is_present(ptr_dev)) +#else + if (1 == pci_dev_present(_osal_mdc_id_table)) +#endif + { + pci_restore_state(ptr_dev); + rc = NPS_E_OK; + } + else + { + OSAL_MDC_ERR("detect pci device failed\n"); + rc = NPS_E_OTHERS; + } + + if (NPS_E_OK == rc) + { + rc = _osal_mdc_clearStatus(unit); + } + + return (rc); +} + #endif /* End of AML_EN_I2C */ /* --------------------------------------------------------------------------- DMA */ @@ -1415,6 +1530,20 @@ osal_mdc_invalidateCache( return (NPS_E_OK); } +NPS_ERROR_NO_T +osal_mdc_savePciConfig( + const UI32_T unit) +{ + return _osal_mdc_savePciConfig(unit); +} + +NPS_ERROR_NO_T +osal_mdc_restorePciConfig( + const UI32_T unit) +{ + return _osal_mdc_restorePciConfig(unit); +} + #endif /* End of NPS_LINUX_KERNEL_MODE */ /* --------------------------------------------------------------------------- Interrupt */ @@ -1458,7 +1587,7 @@ _osal_mdc_notifyUserProcess( /* set the device bitmap. */ spin_lock_irqsave(&_osal_mdc_isr_dev_bitmap_lock, flags); - _osal_mdc_isr_dev_bitmap |= (1 << unit); + _osal_mdc_isr_dev_bitmap |= (1U << unit); spin_unlock_irqrestore(&_osal_mdc_isr_dev_bitmap_lock, flags); /* notify user process. */ @@ -2045,12 +2174,12 @@ _osal_mdc_ioctl_connectIsrCallback( { NPS_ERROR_NO_T rc = NPS_E_OK; - if (0 == (_osal_mdc_isr_init_bitmap & (1 << unit))) + if (0 == (_osal_mdc_isr_init_bitmap & (1U << unit))) { rc = osal_mdc_connectIsr(unit, NULL, ptr_data); if (NPS_E_OK == rc) { - _osal_mdc_isr_init_bitmap |= (1 << unit); + _osal_mdc_isr_init_bitmap |= (1U << unit); } } return (rc); @@ -2065,11 +2194,27 @@ _osal_mdc_ioctl_disconnectIsrCallback( _osal_mdc_notifyUserProcess(unit); osal_mdc_disconnectIsr(unit); - _osal_mdc_isr_init_bitmap &= ~(1 << unit); + _osal_mdc_isr_init_bitmap &= ~(1U << unit); return (NPS_E_OK); } +static NPS_ERROR_NO_T +_osal_mdc_ioctl_savePciConfigCallback( + const UI32_T unit, + void *ptr_data) +{ + return _osal_mdc_savePciConfig(unit); +} + +static NPS_ERROR_NO_T +_osal_mdc_ioctl_restorePciConfigCallback( + const UI32_T unit, + void *ptr_data) +{ + return _osal_mdc_restorePciConfig(unit); +} + static NPS_ERROR_NO_T _osal_mdc_registerIoctlCallback( const OSAL_MDC_IOCTL_TYPE_T type, @@ -2126,6 +2271,12 @@ _osal_mdc_initIoctl(void) _osal_mdc_registerIoctlCallback(OSAL_MDC_IOCTL_TYPE_MDC_DISCONNECT_ISR, _osal_mdc_ioctl_disconnectIsrCallback); + + _osal_mdc_registerIoctlCallback(OSAL_MDC_IOCTL_TYPE_MDC_SAVE_PCI_CONFIG, + _osal_mdc_ioctl_savePciConfigCallback); + + _osal_mdc_registerIoctlCallback(OSAL_MDC_IOCTL_TYPE_MDC_RESTORE_PCI_CONFIG, + _osal_mdc_ioctl_restorePciConfigCallback); return (NPS_E_OK); } @@ -2221,6 +2372,8 @@ _osal_mdc_ioctl( /* type: DEINIT_DEV * DEINIT_RSRV_DMA_MEM * DISCONNECT_ISR + * SAVE_PCI_CONFIG + * RESTORE_PCI_CONFIG */ if (NPS_E_OK != ptr_cb->callback[type](unit, (void *)ptr_temp_buf)) { @@ -2308,10 +2461,10 @@ osal_mdc_module_exit(void) /* ref: _osal_mdc_ioctl_disconnectIsrCallback */ for (unit = 0; unit < NPS_CFG_MAXIMUM_CHIPS_PER_SYSTEM; unit++) { - if (0 != (_osal_mdc_isr_init_bitmap & (1 << unit))) + if (0 != (_osal_mdc_isr_init_bitmap & (1U << unit))) { osal_mdc_disconnectIsr(unit); - _osal_mdc_isr_init_bitmap &= ~(1 << unit); + _osal_mdc_isr_init_bitmap &= ~(1U << unit); } } @@ -2355,5 +2508,5 @@ osal_mdc_module_exit(void) module_init(osal_mdc_module_init); module_exit(osal_mdc_module_exit); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Nephos"); +MODULE_AUTHOR("MediaTek"); MODULE_DESCRIPTION("SDK Kernel Module"); From ca8ac9d4377e0250fa2b6c2745bc23f00c97fcee Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Tue, 24 Mar 2020 20:32:52 +0800 Subject: [PATCH 125/178] [Mellanox] Add a new Mellanox platform x86_64-mlnx_msn4700 and new SKU ACS-MSN4700 (#3901) * add MSN4700 device files * update ACS-MSN4700 sai profile * update buffer pool size, headroom, sensor conf, port config and reboot scripts * fix ident * update sensor conf and buffer pool * [sn4700] add sku 4700 to chassis.py * [Mellanox-4700] Add 4700 info to psu and thermal platform API * update buffer config file template to the latest. update SAI profile to use 100G X 4lanes for now update port_config.ini according to the SAI profile * [Mellanox]Update the buffer configurations for 4700 * fix alignment in pg_profile_lookup.ini * add platform components file for new sku * Update device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/pg_profile_lookup.ini Co-Authored-By: Nazarii Hnydyn * remove redundant line * [Mellanox]Correct type, buffer size Co-authored-by: Nazarii Hnydyn Co-authored-by: junchao Co-authored-by: Stephen Sun --- .../ACS-MSN4700/buffers.json.j2 | 1 + .../ACS-MSN4700/buffers_defaults_t0.j2 | 106 ++++++++ .../ACS-MSN4700/buffers_defaults_t1.j2 | 106 ++++++++ .../ACS-MSN4700/pg_profile_lookup.ini | 25 ++ .../ACS-MSN4700/port_config.ini | 33 +++ .../ACS-MSN4700/qos.json.j2 | 1 + .../ACS-MSN4700/sai.profile | 1 + .../ACS-MSN4700/sai_4700_100G.xml | 244 +++++++++++++++++ .../x86_64-mlnx_msn4700-r0/default_sku | 1 + .../platform_components.json | 10 + .../x86_64-mlnx_msn4700-r0/platform_reboot | 1 + .../x86_64-mlnx_msn4700-r0/platform_wait | 1 + .../x86_64-mlnx_msn4700-r0/plugins/eeprom.py | 1 + .../x86_64-mlnx_msn4700-r0/plugins/psuutil.py | 1 + .../plugins/sfplpmget.py | 1 + .../plugins/sfplpmset.py | 1 + .../plugins/sfpreset.py | 1 + .../x86_64-mlnx_msn4700-r0/plugins/sfputil.py | 1 + .../pmon_daemon_control.json | 1 + .../x86_64-mlnx_msn4700-r0/sensors.conf | 162 +++++++++++ .../x86_64-mlnx_msn4700_simx-r0/ACS-MSN4700 | 1 + .../x86_64-mlnx_msn4700_simx-r0/default_sku | 1 + .../platform_reboot | 1 + .../x86_64-mlnx_msn4700_simx-r0/plugins | 1 + .../pmon_daemon_control.json | 5 + .../x86_64-mlnx_msn4700_simx-r0/syseeprom.hex | 256 ++++++++++++++++++ .../sonic_platform/chassis.py | 2 +- .../mlnx-platform-api/sonic_platform/psu.py | 4 +- .../sonic_platform/thermal.py | 18 +- 29 files changed, 984 insertions(+), 4 deletions(-) create mode 120000 device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers.json.j2 create mode 100644 device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers_defaults_t0.j2 create mode 100644 device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers_defaults_t1.j2 create mode 100644 device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/pg_profile_lookup.ini create mode 100644 device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/port_config.ini create mode 120000 device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/qos.json.j2 create mode 100644 device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai.profile create mode 100644 device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai_4700_100G.xml create mode 100644 device/mellanox/x86_64-mlnx_msn4700-r0/default_sku create mode 100644 device/mellanox/x86_64-mlnx_msn4700-r0/platform_components.json create mode 120000 device/mellanox/x86_64-mlnx_msn4700-r0/platform_reboot create mode 120000 device/mellanox/x86_64-mlnx_msn4700-r0/platform_wait create mode 120000 device/mellanox/x86_64-mlnx_msn4700-r0/plugins/eeprom.py create mode 120000 device/mellanox/x86_64-mlnx_msn4700-r0/plugins/psuutil.py create mode 120000 device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfplpmget.py create mode 120000 device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfplpmset.py create mode 120000 device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfpreset.py create mode 120000 device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfputil.py create mode 120000 device/mellanox/x86_64-mlnx_msn4700-r0/pmon_daemon_control.json create mode 100644 device/mellanox/x86_64-mlnx_msn4700-r0/sensors.conf create mode 120000 device/mellanox/x86_64-mlnx_msn4700_simx-r0/ACS-MSN4700 create mode 120000 device/mellanox/x86_64-mlnx_msn4700_simx-r0/default_sku create mode 120000 device/mellanox/x86_64-mlnx_msn4700_simx-r0/platform_reboot create mode 120000 device/mellanox/x86_64-mlnx_msn4700_simx-r0/plugins create mode 100644 device/mellanox/x86_64-mlnx_msn4700_simx-r0/pmon_daemon_control.json create mode 100644 device/mellanox/x86_64-mlnx_msn4700_simx-r0/syseeprom.hex diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers.json.j2 b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers.json.j2 new file mode 120000 index 000000000000..add8bf8bb7c2 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers_defaults_t0.j2 new file mode 100644 index 000000000000..b71e6b35fa2e --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers_defaults_t0.j2 @@ -0,0 +1,106 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '56623104' %} +{% set ingress_lossy_pool_size = '56623104' %} +{% set egress_lossless_pool_size = '60817392' %} +{% set egress_lossy_pool_size = '56623104' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0, 32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "ingress_lossy_pool": { + "size": "{{ ingress_lossy_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"0" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_profile_lists(port_names) %} + "BUFFER_PORT_INGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile],[BUFFER_PROFILE|ingress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + }, + "BUFFER_PORT_EGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { +{% for port in port_names.split(',') %} + "{{ port }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|0-2": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|5-6": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} + + diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers_defaults_t1.j2 new file mode 100644 index 000000000000..87e55d5a46e0 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/buffers_defaults_t1.j2 @@ -0,0 +1,106 @@ +{% set default_cable = '5m' %} +{% set ingress_lossless_pool_size = '36011952' %} +{% set ingress_lossy_pool_size = '36011952' %} +{% set egress_lossless_pool_size = '60817392' %} +{% set egress_lossy_pool_size = '36011952' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {%- for port_idx in range(0, 32) %} + {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %} + {%- endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "{{ ingress_lossless_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "ingress_lossy_pool": { + "size": "{{ ingress_lossy_pool_size }}", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "{{ egress_lossless_pool_size }}", + "type": "egress", + "mode": "dynamic" + }, + "egress_lossy_pool": { + "size": "{{ egress_lossy_pool_size }}", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossless_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"0" + }, + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "dynamic_th":"7" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"4096", + "dynamic_th":"3" + }, + "q_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossy_pool]", + "size":"0", + "dynamic_th":"3" + } + }, +{%- endmacro %} + +{%- macro generate_profile_lists(port_names) %} + "BUFFER_PORT_INGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile],[BUFFER_PROFILE|ingress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + }, + "BUFFER_PORT_EGRESS_PROFILE_LIST": { +{% for port in port_names.split(',') %} + "{{ port }}": { + "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} + +{%- macro generate_queue_buffers(port_names) %} + "BUFFER_QUEUE": { +{% for port in port_names.split(',') %} + "{{ port }}|3-4": { + "profile" : "[BUFFER_PROFILE|egress_lossless_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|0-2": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }, +{% endfor %} +{% for port in port_names.split(',') %} + "{{ port }}|5-6": { + "profile" : "[BUFFER_PROFILE|q_lossy_profile]" + }{% if not loop.last %},{% endif %} + +{% endfor %} + } +{%- endmacro %} + + diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/pg_profile_lookup.ini new file mode 100644 index 000000000000..950cf9434967 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/pg_profile_lookup.ini @@ -0,0 +1,25 @@ +# speed cable size xon xoff threshold +1000 5m 32768 18432 14336 0 +10000 5m 32768 18432 14336 0 +25000 5m 33792 18432 15360 0 +40000 5m 33792 18432 15360 0 +50000 5m 33792 18432 15360 0 +100000 5m 35840 18432 17408 0 +200000 5m 37888 18432 19456 0 +400000 5m 43008 18432 24576 0 +1000 40m 32768 18432 14336 0 +10000 40m 34816 18432 16384 0 +25000 40m 37888 18432 19456 0 +40000 40m 40960 18432 22528 0 +50000 40m 43008 18432 24576 0 +100000 40m 53248 18432 34816 0 +200000 40m 72704 18432 54272 0 +400000 40m 112640 18432 94208 0 +1000 300m 34816 18432 16384 0 +10000 300m 48128 18432 29696 0 +25000 300m 70656 18432 52224 0 +40000 300m 93184 18432 74752 0 +50000 300m 108544 18432 90112 0 +100000 300m 183296 18432 164864 0 +200000 300m 333824 18432 315392 0 +400000 300m 634880 18432 616448 0 diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/port_config.ini b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/port_config.ini new file mode 100644 index 000000000000..1e1906ff0ef5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias +Ethernet0 0,1,2,3 etp1 +Ethernet4 4,5,6,7 etp2 +Ethernet8 8,9,10,11 etp3 +Ethernet12 12,13,14,15 etp4 +Ethernet16 16,17,18,19 etp5 +Ethernet20 20,21,22,23 etp6 +Ethernet24 24,25,26,27 etp7 +Ethernet28 28,29,30,31 etp8 +Ethernet32 32,33,34,35 etp9 +Ethernet36 36,37,38,39 etp10 +Ethernet40 40,41,42,43 etp11 +Ethernet44 44,45,46,47 etp12 +Ethernet48 48,49,50,51 etp13 +Ethernet52 52,53,54,55 etp14 +Ethernet56 56,57,58,59 etp15 +Ethernet60 60,61,62,63 etp16 +Ethernet64 64,65,66,67 etp17 +Ethernet68 68,69,70,71 etp18 +Ethernet72 72,73,74,75 etp19 +Ethernet76 76,77,78,79 etp20 +Ethernet80 80,81,82,83 etp21 +Ethernet84 84,85,86,87 etp22 +Ethernet88 88,89,90,91 etp23 +Ethernet92 92,93,94,95 etp24 +Ethernet96 96,97,98,99 etp25 +Ethernet100 100,101,102,103 etp26 +Ethernet104 104,105,106,107 etp27 +Ethernet108 108,109,110,111 etp28 +Ethernet112 112,113,114,115 etp29 +Ethernet116 116,117,118,119 etp30 +Ethernet120 120,121,122,123 etp31 +Ethernet124 124,125,126,127 etp32 diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/qos.json.j2 b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/qos.json.j2 new file mode 120000 index 000000000000..eccf286dc879 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/qos.json.j2 @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/qos.json.j2 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai.profile b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai.profile new file mode 100644 index 000000000000..31b3fd09ddd9 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/sai_4700_100G.xml diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai_4700_100G.xml b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai_4700_100G.xml new file mode 100644 index 000000000000..a76e23d5d119 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/ACS-MSN4700/sai_4700_100G.xml @@ -0,0 +1,244 @@ + + + + + + 00:02:03:04:05:00 + + + 32 + + + + + 1 + 4 + 17 + 3 + 1536 + + + 5 + 4 + 16 + 3 + 1536 + + + 9 + 4 + 19 + 3 + 1536 + + + 13 + 4 + 18 + 3 + 1536 + + + 17 + 4 + 21 + 3 + 1536 + + + 21 + 4 + 20 + 3 + 1536 + + + 25 + 4 + 23 + 3 + 1536 + + + 29 + 4 + 22 + 3 + 1536 + + + 33 + 4 + 29 + 3 + 1536 + + + 37 + 4 + 28 + 3 + 1536 + + + 41 + 4 + 31 + 3 + 1536 + + + 45 + 4 + 30 + 3 + 1536 + + + 49 + 4 + 25 + 3 + 1536 + + + 53 + 4 + 24 + 3 + 1536 + + + 57 + 4 + 27 + 3 + 1536 + + + 61 + 4 + 26 + 3 + 1536 + + + 65 + 4 + 14 + 3 + 1536 + + + 69 + 4 + 15 + 3 + 1536 + + + 73 + 4 + 12 + 3 + 1536 + + + 77 + 4 + 13 + 3 + 1536 + + + 81 + 4 + 10 + 3 + 1536 + + + 85 + 4 + 11 + 3 + 1536 + + + 89 + 4 + 8 + 3 + 1536 + + + 93 + 4 + 9 + 3 + 1536 + + + 97 + 4 + 2 + 3 + 1536 + + + 101 + 4 + 3 + 3 + 1536 + + + 105 + 4 + 0 + + + 3 + + + 1536 + + + 109 + 4 + 1 + 3 + 1536 + + + 113 + 4 + 6 + 3 + 1536 + + + 117 + 4 + 7 + 3 + 1536 + + + 121 + 4 + 4 + 3 + 1536 + + + 125 + 4 + 5 + 3 + 1536 + + + + + diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/default_sku b/device/mellanox/x86_64-mlnx_msn4700-r0/default_sku new file mode 100644 index 000000000000..80e541477f79 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/default_sku @@ -0,0 +1 @@ +ACS-MSN4700 t1 diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/platform_components.json b/device/mellanox/x86_64-mlnx_msn4700-r0/platform_components.json new file mode 100644 index 000000000000..2804e29e11b1 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/platform_components.json @@ -0,0 +1,10 @@ +{ + "chassis": { + "x86_64-mlnx_msn4700-r0": { + "component": { + "BIOS": { }, + "CPLD": { } + } + } + } +} diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/platform_reboot b/device/mellanox/x86_64-mlnx_msn4700-r0/platform_reboot new file mode 120000 index 000000000000..43c8ea567493 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/platform_reboot @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/platform_reboot \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/platform_wait b/device/mellanox/x86_64-mlnx_msn4700-r0/platform_wait new file mode 120000 index 000000000000..4b30bd429854 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/platform_wait @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/platform_wait \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/eeprom.py b/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/eeprom.py new file mode 120000 index 000000000000..b4e2a6a61671 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/eeprom.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/eeprom.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/psuutil.py b/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/psuutil.py new file mode 120000 index 000000000000..9f724238a8d5 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/psuutil.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/psuutil.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfplpmget.py b/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfplpmget.py new file mode 120000 index 000000000000..2e84f435abd9 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfplpmget.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/sfplpmget.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfplpmset.py b/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfplpmset.py new file mode 120000 index 000000000000..6a88bac30467 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfplpmset.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/sfplpmset.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfpreset.py b/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfpreset.py new file mode 120000 index 000000000000..fef2063e3496 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfpreset.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/sfpreset.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfputil.py b/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfputil.py new file mode 120000 index 000000000000..45909b880fc9 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/plugins/sfputil.py @@ -0,0 +1 @@ +../../x86_64-mlnx_msn2700-r0/plugins/sfputil.py \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/pmon_daemon_control.json b/device/mellanox/x86_64-mlnx_msn4700-r0/pmon_daemon_control.json new file mode 120000 index 000000000000..435a2ce7c0ba --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/pmon_daemon_control.json @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700-r0/pmon_daemon_control.json \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/sensors.conf b/device/mellanox/x86_64-mlnx_msn4700-r0/sensors.conf new file mode 100644 index 000000000000..b4eaf76f2ec0 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/sensors.conf @@ -0,0 +1,162 @@ +################################################################################ +# Copyright (c) 2019 Mellanox Technologies +# +# Platform specific sensors config for SN4700 +################################################################################ + +# Temperature sensors +bus "i2c-2" "i2c-1-mux (chan_id 1)" + chip "mlxsw-i2c-*-48" + label temp1 "Ambient ASIC Temp" + +bus "i2c-7" "i2c-1-mux (chan_id 6)" + chip "tmp102-i2c-*-49" + label temp1 "Ambient Fan Side Temp (air intake)" + chip "tmp102-i2c-*-4a" + label temp1 "Ambient Port Side Temp (air exhaust)" + +bus "i2c-15" "i2c-1-mux (chan_id 6)" + chip "tmp102-i2c-15-49" + label temp1 "Ambient COMEX Temp" + +# Power controllers +bus "i2c-5" "i2c-1-mux (chan_id 4)" + chip "tps53679-i2c-*-62" + label in1 "PMIC-1 PSU 12V Rail (in)" + label in2 "PMIC-1 ASIC 0.8V VCORE_MAIN Rail (out)" + ignore in3 + label temp1 "PMIC-1 Temp 1" + label temp2 "PMIC-1 Temp 2" + label power1 "PMIC-1 ASIC 0.8V VCORE_MAIN Rail Pwr (out)" + ignore power2 + label curr1 "PMIC-1 ASIC 0.8V VCORE_MAIN Rail Curr (out)" + ignore curr2 + chip "tps53679-i2c-*-64" + label in1 "PMIC-2 PSU 12V Rail (in)" + label in2 "PMIC-2 ASIC 1.8V MAIN Rail (out)" + compute in2 (1.5)*@, @/(1.5) + label in3 "PMIC-2 ASIC 1.2V MAIN Rail (out)" + label temp1 "PMIC-2 Temp 1" + label temp2 "PMIC-2 Temp 2" + label power1 "PMIC-2 ASIC 1.8V MAIN Rail Pwr (out)" + label power2 "PMIC-2 ASIC 1.2V MAIN Rail Pwr (out)" + label curr1 "PMIC-2 ASIC 1.8V MAIN Rail Curr (out)" + label curr2 "PMIC-2 ASIC 1.2V MAIN Rail Curr (out)" + chip "tps53679-i2c-*-66" + label in1 "PMIC-3 PSU 12V Rail (in)" + label in2 "PMIC-3 ASIC 0.85V VCORE_T0_1 Rail (out)" + label in3 "PMIC-3 ASIC 1.8V T0_1 Rail (out)" + label temp1 "PMIC-3 Temp 1" + label temp2 "PMIC-3 Temp 2" + label power1 "PMIC-3 ASIC 0.85V VCORE_T0_1 Rail Pwr (out)" + label power2 "PMIC-3 ASIC 1.8V T0_1 Rail Pwr (out)" + label curr1 "PMIC-3 ASIC 0.85V VCORE_T0_1 Rail Curr (out)" + label curr2 "PMIC-3 ASIC 1.8V T0_1 Rail Curr (out)" + chip "tps53679-i2c-*-68" + label in1 "PMIC-4 PSU 12V Rail (in)" + label in2 "PMIC-4 ASIC 0.85V VCORE_T2_3 Rail (out)" + label in3 "PMIC-4 ASIC 1.8V T2_3 Rail (out)" + label temp1 "PMIC-4 Temp 1" + label temp2 "PMIC-4 Temp 2" + label power1 "PMIC-4 ASIC 0.85V VCORE_T2_3 Rail Pwr (out)" + label power2 "PMIC-4 ASIC 1.8V T2_3 Rail Pwr (out)" + label curr1 "PMIC-4 ASIC 0.85V VCORE_T2_3 Rail Curr (out)" + label curr2 "PMIC-4 ASIC 1.8V T2_3 Rail Curr (out)" + chip "tps53679-i2c-*-6a" + label in1 "PMIC-5 PSU 12V Rail (in)" + label in2 "PMIC-5 ASIC 0.85V VCORE_T4_5 Rail (out)" + label in3 "PMIC-5 ASIC 1.8V T4_5 Rail (out)" + label temp1 "PMIC-5 Temp 1" + label temp2 "PMIC-5 Temp 2" + label power1 "PMIC-5 ASIC 0.85V VCORE_T4_5 Rail Pwr (out)" + label power2 "PMIC-5 ASIC 1.8V T4_5 Rail Pwr (out)" + label curr1 "PMIC-5 ASIC 0.85V VCORE_T4_5 Rail Curr (out)" + label curr2 "PMIC-5 ASIC 1.8V T4_5 Rail Curr (out)" + chip "tps53679-i2c-*-6c" + label in1 "PMIC-6 PSU 12V Rail (in)" + label in2 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail (out)" + label in3 "PMIC-6 ASIC 1.8V T6_7 Rail (out)" + label temp1 "PMIC-6 Temp 1" + label temp2 "PMIC-6 Temp 2" + label power1 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail Pwr (out)" + label power2 "PMIC-6 ASIC 1.8V T6_7 Rail Pwr (out)" + label curr1 "PMIC-6 ASIC 0.85V VCORE_T6_7 Rail Curr (out)" + label curr2 "PMIC-6 ASIC 1.8V T6_7 Rail Curr (out)" + chip "tps53679-i2c-*-6e" + label in1 "PMIC-7 PSU 12V Rail (in)" + label in2 "PMIC-7 ASIC 1.2V T0_3 Rail (out)" + label in3 "PMIC-7 ASIC 1.2V T4_7 Rail (out)" + label temp1 "PMIC-7 Temp 1" + label temp2 "PMIC-7 Temp 2" + label power1 "PMIC-7 ASIC 1.2V T0_3 Rail Pwr (out)" + label power2 "PMIC-7 ASIC 1.2V T4_7 Rail Pwr (out)" + label curr1 "PMIC-7 ASIC 1.2V T0_3 Rail Curr (out)" + label curr2 "PMIC-7 ASIC 1.2V T4_7 Rail Curr (out)" + +bus "i2c-15" "i2c-1-mux (chan_id 6)" + chip "tps53679-i2c-*-58" + label in1 "PMIC-8 PSU 12V Rail (in)" + label in2 "PMIC-8 COMEX 1.8V Rail (out)" + label in3 "PMIC-8 COMEX 1.05V Rail (out)" + label temp1 "PMIC-8 Temp 1" + label temp2 "PMIC-8 Temp 2" + label power1 "PMIC-8 COMEX 1.8V Rail Pwr (out)" + label power2 "PMIC-8 COMEX 1.05V Rail Pwr (out)" + label curr1 "PMIC-8 COMEX 1.8V Rail Curr (out)" + label curr2 "PMIC-8 COMEX 1.05V Rail Curr (out)" + chip "tps53679-i2c-*-61" + label in1 "PMIC-9 PSU 12V Rail (in)" + label in2 "PMIC-9 COMEX 1.2V Rail (out)" + ignore in3 + label temp1 "PMIC-9 Temp 1" + label temp2 "PMIC-9 Temp 2" + label power1 "PMIC-9 COMEX 1.2V Rail Pwr (out)" + ignore power2 + label curr1 "PMIC-9 COMEX 1.2V Rail Curr (out)" + ignore curr2 + +# Power supplies +bus "i2c-4" "i2c-1-mux (chan_id 3)" + chip "dps460-i2c-*-58" + label in1 "PSU-1(L) 220V Rail (in)" + ignore in2 + label in3 "PSU-1(L) 12V Rail (out)" + label fan1 "PSU-1(L) Fan 1" + label temp1 "PSU-1(L) Temp 1" + label temp2 "PSU-1(L) Temp 2" + label temp3 "PSU-1(L) Temp 3" + label power1 "PSU-1(L) 220V Rail Pwr (in)" + label power2 "PSU-1(L) 12V Rail Pwr (out)" + label curr1 "PSU-1(L) 220V Rail Curr (in)" + label curr2 "PSU-1(L) 12V Rail Curr (out)" + chip "dps460-i2c-*-59" + label in1 "PSU-2(R) 220V Rail (in)" + ignore in2 + label in3 "PSU-2(R) 12V Rail (out)" + label fan1 "PSU-2(R) Fan 1" + label temp1 "PSU-2(R) Temp 1" + label temp2 "PSU-2(R) Temp 2" + label temp3 "PSU-2(R) Temp 3" + label power1 "PSU-2(R) 220V Rail Pwr (in)" + label power2 "PSU-2(R) 12V Rail Pwr (out)" + label curr1 "PSU-2(R) 220V Rail Curr (in)" + label curr2 "PSU-2(R) 12V Rail Curr (out)" + +# Chassis fans +chip "mlxreg_fan-isa-*" + label fan1 "Chassis Fan Drawer-1 Tach 1" + label fan2 "Chassis Fan Drawer-1 Tach 2" + label fan3 "Chassis Fan Drawer-2 Tach 1" + label fan4 "Chassis Fan Drawer-2 Tach 2" + label fan5 "Chassis Fan Drawer-3 Tach 1" + label fan6 "Chassis Fan Drawer-3 Tach 2" + label fan7 "Chassis Fan Drawer-4 Tach 1" + label fan8 "Chassis Fan Drawer-4 Tach 2" + label fan9 "Chassis Fan Drawer-5 Tach 1" + label fan10 "Chassis Fan Drawer-5 Tach 2" + label fan11 "Chassis Fan Drawer-6 Tach 1" + label fan12 "Chassis Fan Drawer-6 Tach 2" + +# Miscellaneous +chip "*-virtual-*" + ignore temp1 diff --git a/device/mellanox/x86_64-mlnx_msn4700_simx-r0/ACS-MSN4700 b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/ACS-MSN4700 new file mode 120000 index 000000000000..3f61c9909a65 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/ACS-MSN4700 @@ -0,0 +1 @@ +../x86_64-mlnx_msn4700-r0/ACS-MSN4700 \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700_simx-r0/default_sku b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/default_sku new file mode 120000 index 000000000000..6f72f84de680 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/default_sku @@ -0,0 +1 @@ +../x86_64-mlnx_msn4700-r0/default_sku \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700_simx-r0/platform_reboot b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/platform_reboot new file mode 120000 index 000000000000..dfaf53417665 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/platform_reboot @@ -0,0 +1 @@ +../x86_64-mlnx_msn2700_simx-r0/platform_reboot \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700_simx-r0/plugins b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/plugins new file mode 120000 index 000000000000..e98a1d3fbaeb --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/plugins @@ -0,0 +1 @@ +../x86_64-mlnx_msn4700-r0/plugins \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn4700_simx-r0/pmon_daemon_control.json b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..40fc367acf32 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/pmon_daemon_control.json @@ -0,0 +1,5 @@ +{ + "skip_ledd": true, + "skip_xcvrd": true, + "skip_psud": true +} diff --git a/device/mellanox/x86_64-mlnx_msn4700_simx-r0/syseeprom.hex b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/syseeprom.hex new file mode 100644 index 000000000000..b50ffa5a0231 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn4700_simx-r0/syseeprom.hex @@ -0,0 +1,256 @@ +54 6c 76 49 6e 66 6f 00 01 02 53 21 40 4d 53 4e +33 37 30 30 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 22 14 4d +53 4e 33 37 30 30 2d 56 53 32 46 00 00 00 00 00 +00 00 00 23 18 4d 54 31 38 35 31 58 30 32 39 36 +31 00 00 00 00 00 00 00 00 00 00 00 00 24 06 98 +03 9b 94 d4 80 25 13 31 32 2f 32 38 2f 32 30 31 +38 20 30 34 3a 34 32 3a 31 38 26 01 00 2a 02 00 +fe 2b 08 4d 65 6c 6c 61 6e 6f 78 fd 24 00 00 81 +19 00 16 01 01 00 56 00 00 4d 4c 4e 58 02 01 0c +05 0e 02 10 06 12 07 00 00 00 00 00 00 00 00 00 +00 fd a4 00 00 81 19 00 92 00 03 01 01 00 00 4d +54 31 38 35 31 58 30 32 39 36 31 00 00 00 00 00 +00 00 00 00 00 00 00 4d 53 4e 33 37 30 30 2d 56 +53 32 46 00 00 00 00 00 00 00 00 41 32 00 00 00 +3a 82 b8 41 6e 61 63 6f 6e 64 61 20 45 74 68 20 +32 30 30 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 70 00 00 00 0e 74 4d 53 4e 33 37 +30 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 fd 24 00 00 81 19 00 10 00 +03 05 e8 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 fd 24 00 +00 81 19 00 1e 00 11 02 85 00 00 0d 00 00 00 00 +00 00 00 98 03 9b 94 d4 80 00 fe 98 03 9b 03 00 +94 d4 80 fd 24 00 00 81 19 00 12 00 01 06 81 00 +00 00 46 00 00 08 00 06 06 06 06 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 fd 14 00 00 81 19 00 +0e 00 02 07 99 00 00 30 00 20 00 00 00 00 00 28 +40 78 38 36 5f 36 34 2d 6d 6c 6e 78 5f 6d 73 6e +33 37 30 30 2d 72 30 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 29 15 32 30 31 38 2e 31 31 2d 35 2e 32 2e 30 +30 30 38 2d 39 36 30 30 fe 04 89 cb 82 5b 00 00 +00 00 00 fe 04 72 60 7f 13 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index 38320c730cc9..cb64a64d1455 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -44,7 +44,7 @@ # magic code defnition for port number, qsfp port position of each hwsku # port_position_tuple = (PORT_START, QSFP_PORT_START, PORT_END, PORT_IN_BLOCK, EEPROM_OFFSET) -hwsku_dict_port = {'ACS-MSN2010': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2700': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'LS-SN2700':0, 'ACS-MSN2740': 0, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'ACS-MSN3800': 4, 'Mellanox-SN3800-D112C8': 4} +hwsku_dict_port = {'ACS-MSN2010': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2700': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'LS-SN2700':0, 'ACS-MSN2740': 0, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'ACS-MSN3800': 4, 'Mellanox-SN3800-D112C8': 4, 'ACS-MSN4700': 0} port_position_tuple_list = [(0, 0, 31, 32, 1), (0, 0, 15, 16, 1), (0, 48, 55, 56, 1), (0, 18, 21, 22, 1), (0, 0, 63, 64, 1)] class Chassis(ChassisBase): diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py index 87d6024f7d8b..045e5a842993 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/psu.py @@ -32,7 +32,7 @@ # in most SKUs the file psuX_curr, psuX_volt and psuX_power contain current, voltage and power data respectively. # but there are exceptions which will be handled by the following dictionary -hwsku_dict_psu = {'ACS-MSN3700': 1, 'ACS-MSN3700C': 1, 'ACS-MSN3800': 1, 'Mellanox-SN3800-D112C8': 1} +hwsku_dict_psu = {'ACS-MSN3700': 1, 'ACS-MSN3700C': 1, 'ACS-MSN3800': 1, 'Mellanox-SN3800-D112C8': 1, 'ACS-MSN4700': 1} psu_profile_list = [ # default filename convention { @@ -40,7 +40,7 @@ PSU_VOLTAGE : "power/psu{}_volt", PSU_POWER : "power/psu{}_power" }, - # for 3700, 3700c, 3800 + # for 3700, 3700c, 3800, 4700 { PSU_CURRENT : "power/psu{}_curr", PSU_VOLTAGE : "power/psu{}_volt_out2", diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py index 74d61220738f..903b55404bb3 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/thermal.py @@ -106,7 +106,7 @@ THERMAL_API_GET_HIGH_THRESHOLD ] -hwsku_dict_thermal = {'ACS-MSN2700': 0, 'LS-SN2700':0, 'ACS-MSN2740': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 4, 'ACS-MSN3700': 5, 'ACS-MSN3700C': 6, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'ACS-MSN3800': 7, 'Mellanox-SN3800-D112C8': 7} +hwsku_dict_thermal = {'ACS-MSN2700': 0, 'LS-SN2700':0, 'ACS-MSN2740': 3, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 4, 'ACS-MSN3700': 5, 'ACS-MSN3700C': 6, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'ACS-MSN3800': 7, 'Mellanox-SN3800-D112C8': 7, 'ACS-MSN4700': 8} thermal_profile_list = [ # 2700 { @@ -231,6 +231,22 @@ ] ) }, + # 4700 + { + THERMAL_DEV_CATEGORY_CPU_CORE:(0, 4), + THERMAL_DEV_CATEGORY_MODULE:(1, 32), + THERMAL_DEV_CATEGORY_PSU:(1, 2), + THERMAL_DEV_CATEGORY_CPU_PACK:(0,1), + THERMAL_DEV_CATEGORY_GEARBOX:(0,0), + THERMAL_DEV_CATEGORY_AMBIENT:(0, + [ + THERMAL_DEV_ASIC_AMBIENT, + THERMAL_DEV_COMEX_AMBIENT, + THERMAL_DEV_PORT_AMBIENT, + THERMAL_DEV_FAN_AMBIENT + ] + ) + } ] def initialize_thermals(sku, thermal_list, psu_list): From da92d8f5c31f55686ff104045ef7a0d3d4987e04 Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Mon, 23 Mar 2020 18:04:11 +0200 Subject: [PATCH 126/178] [mellanox]: Align platform API: change CPLD version representation (#4221) --- .../sonic_platform/chassis.py | 2 +- .../sonic_platform/component.py | 148 +++++++++++------- 2 files changed, 93 insertions(+), 57 deletions(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index cb64a64d1455..5884b833b12b 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -139,7 +139,7 @@ def initialize_components(self): # Initialize component list from sonic_platform.component import ComponentBIOS, ComponentCPLD self._component_list.append(ComponentBIOS()) - self._component_list.append(ComponentCPLD()) + self._component_list.extend(ComponentCPLD.get_component_list()) def get_name(self): diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py index dc09ae4011fa..70fd96023b8c 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py @@ -18,13 +18,13 @@ except ImportError as e: raise ImportError(str(e) + "- required module not found") -#components definitions -COMPONENT_BIOS = "BIOS" -COMPONENT_CPLD = "CPLD" +ZERO = '0' +NEWLINE = '\n' class Component(ComponentBase): def __init__(self): self.name = None + self.description = None self.image_ext_name = None @@ -38,20 +38,35 @@ def get_name(self): return self.name - def _read_generic_file(self, filename, len): + def get_description(self): + """ + Retrieves the description of the component + + Returns: + A string containing the description of the component + """ + return self.description + + + @staticmethod + def _read_generic_file(filename, len, ignore_errors=False): """ Read a generic file, returns the contents of the file """ - result = '' + result = None + try: with io.open(filename, 'r') as fileobj: result = fileobj.read(len) - return result except IOError as e: - raise RuntimeError("Failed to read file {} due to {}".format(filename, repr(e))) + if not ignore_errors: + raise RuntimeError("Failed to read file {} due to {}".format(filename, repr(e))) + + return result - def _get_command_result(self, cmdline): + @staticmethod + def _get_command_result(cmdline): try: proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT) stdout = proc.communicate()[0] @@ -83,38 +98,33 @@ def _check_file_validity(self, image_path): class ComponentBIOS(Component): + COMPONENT_NAME = 'BIOS' + COMPONENT_DESCRIPTION = 'BIOS - Basic Input/Output System' + COMPONENT_FIRMWARE_EXTENSION = '.rom' + # To update BIOS requires the ONIE with version 5.2.0016 or upper ONIE_VERSION_PARSE_PATTERN = '[0-9]{4}\.[0-9]{2}-([0-9]+)\.([0-9]+)\.([0-9]+)' ONIE_VERSION_MAJOR_OFFSET = 1 ONIE_VERSION_MINOR_OFFSET = 2 ONIE_VERSION_RELEASE_OFFSET = 3 - ONIE_REQUIRED_MAJOR = "5" - ONIE_REQUIRED_MINOR = "2" - ONIE_REQUIRED_RELEASE = "0016" + ONIE_REQUIRED_MAJOR = '5' + ONIE_REQUIRED_MINOR = '2' + ONIE_REQUIRED_RELEASE = '0016' BIOS_VERSION_PARSE_PATTERN = 'OEM[\s]*Strings\n[\s]*String[\s]*1:[\s]*([0-9a-zA-Z_\.]*)' BIOS_PENDING_UPDATE_PATTERN = '([0-9A-Za-z_]*.rom)[\s]*\|[\s]*bios_update' - ONIE_FW_UPDATE_CMD_ADD = "/usr/bin/onie-fw-update.sh add {}" - ONIE_FW_UPDATE_CMD_REMOVE = "/usr/bin/onie-fw-update.sh remove {}" - ONIE_FW_UPDATE_CMD_UPDATE = "/usr/bin/onie-fw-update.sh update" - ONIE_FW_UPDATE_CMD_SHOW = "/usr/bin/onie-fw-update.sh show-pending" + ONIE_FW_UPDATE_CMD_ADD = '/usr/bin/onie-fw-update.sh add {}' + ONIE_FW_UPDATE_CMD_REMOVE = '/usr/bin/onie-fw-update.sh remove {}' + ONIE_FW_UPDATE_CMD_UPDATE = '/usr/bin/onie-fw-update.sh update' + ONIE_FW_UPDATE_CMD_SHOW = '/usr/bin/onie-fw-update.sh show-pending' BIOS_QUERY_VERSION_COMMAND = 'dmidecode -t 11' def __init__(self): - self.name = COMPONENT_BIOS - self.image_ext_name = ".rom" - - - def get_description(self): - """ - Retrieves the description of the component - - Returns: - A string containing the description of the component - """ - return "BIOS - Basic Input/Output System" + self.name = self.COMPONENT_NAME + self.description = self.COMPONENT_DESCRIPTION + self.image_ext_name = self.COMPONENT_FIRMWARE_EXTENSION def get_firmware_version(self): @@ -210,33 +220,39 @@ def install_firmware(self, image_path): print("ERROR: Installing BIOS failed due to {}".format(repr(e))) return False - print("INFO: Reboot is required to finish BIOS installation.") + print("INFO: Reboot is required to finish BIOS installation") return True class ComponentCPLD(Component): - CPLD_VERSION_FILE_PATTERN = '/var/run/hw-management/system/cpld[0-9]_version' - CPLD_VERSION_MAX_LENGTH = 4 + COMPONENT_NAME = 'CPLD{}' + COMPONENT_DESCRIPTION = 'CPLD - Complex Programmable Logic Device' + COMPONENT_FIRMWARE_EXTENSION = '.vme' - CPLD_UPDATE_COMMAND = "cpldupdate --dev {} {}" - CPLD_INSTALL_SUCCESS_FLAG = "PASS!" + CPLD_NUMBER_FILE = '/var/run/hw-management/config/cpld_num' + CPLD_PART_NUMBER_FILE = '/var/run/hw-management/system/cpld{}_pn' + CPLD_VERSION_FILE = '/var/run/hw-management/system/cpld{}_version' + CPLD_VERSION_MINOR_FILE = '/var/run/hw-management/system/cpld{}_version_minor' - MST_DEVICE_PATTERN = "/dev/mst/mt[0-9]*_pciconf0" + CPLD_NUMBER_MAX_LENGTH = 1 + CPLD_PART_NUMBER_MAX_LENGTH = 6 + CPLD_VERSION_MAX_LENGTH = 2 + CPLD_VERSION_MINOR_MAX_LENGTH = 2 - def __init__(self): - self.name = COMPONENT_CPLD - self.image_ext_name = ".vme" + CPLD_PART_NUMBER_DEFAULT = ZERO + CPLD_VERSION_MINOR_DEFAULT = ZERO + CPLD_UPDATE_COMMAND = 'cpldupdate --dev {} {}' + CPLD_INSTALL_SUCCESS_FLAG = 'PASS!' - def get_description(self): - """ - Retrieves the description of the component + MST_DEVICE_PATTERN = '/dev/mst/mt[0-9]*_pci_cr0' - Returns: - A string containing the description of the component - """ - return "CPLD - includes all CPLDs in the switch" + def __init__(self, idx): + self.idx = idx + self.name = self.COMPONENT_NAME.format(self.idx) + self.description = self.COMPONENT_DESCRIPTION + self.image_ext_name = self.COMPONENT_FIRMWARE_EXTENSION def get_firmware_version(self): @@ -246,19 +262,26 @@ def get_firmware_version(self): Returns: A string containing the firmware version of the component """ - cpld_version_file_list = glob(self.CPLD_VERSION_FILE_PATTERN) - cpld_version = '' - if cpld_version_file_list: - cpld_version_file_list.sort() - for version_file in cpld_version_file_list: - version = self._read_generic_file(version_file, self.CPLD_VERSION_MAX_LENGTH) - if cpld_version: - cpld_version += '.' - cpld_version += version.rstrip('\n') - else: - raise RuntimeError("Failed to get CPLD version files by matching {}".format(self.CPLD_VERSION_FILE_PATTERN)) - return cpld_version + part_number_file = self.CPLD_PART_NUMBER_FILE.format(self.idx) + version_file = self.CPLD_VERSION_FILE.format(self.idx) + version_minor_file = self.CPLD_VERSION_MINOR_FILE.format(self.idx) + + part_number = self._read_generic_file(part_number_file, self.CPLD_PART_NUMBER_MAX_LENGTH, True) + version = self._read_generic_file(version_file, self.CPLD_VERSION_MAX_LENGTH) + version_minor = self._read_generic_file(version_minor_file, self.CPLD_VERSION_MINOR_MAX_LENGTH, True) + + if part_number is None: + part_number = self.CPLD_PART_NUMBER_DEFAULT + + if version_minor is None: + version_minor = self.CPLD_VERSION_MINOR_DEFAULT + + part_number = part_number.rstrip(NEWLINE).zfill(self.CPLD_PART_NUMBER_MAX_LENGTH) + version = version.rstrip(NEWLINE).zfill(self.CPLD_VERSION_MAX_LENGTH) + version_minor = version_minor.rstrip(NEWLINE).zfill(self.CPLD_VERSION_MINOR_MAX_LENGTH) + + return "CPLD{}_REV{}{}".format(part_number, version, version_minor) def _get_mst_device(self): @@ -331,8 +354,21 @@ def install_firmware(self, image_path): raise RuntimeError("Failed to execute command {} due to {}".format(cmdline, repr(e))) if success_flag: - print("INFO: Success. Refresh or power cycle is required to finish CPLD installation.") + print("INFO: Refresh or power cycle is required to finish CPLD installation") else: print("ERROR: Failed to install CPLD") return success_flag + + + @classmethod + def get_component_list(cls): + component_list = [ ] + + cpld_number = cls._read_generic_file(cls.CPLD_NUMBER_FILE, cls.CPLD_NUMBER_MAX_LENGTH) + cpld_number = cpld_number.rstrip(NEWLINE) + + for cpld_idx in xrange(1, int(cpld_number) + 1): + component_list.append(cls(cpld_idx)) + + return component_list From 75437bd539e7f7d7b85ec09af72bec8120c81db7 Mon Sep 17 00:00:00 2001 From: noaOrMlnx <58519608+noaOrMlnx@users.noreply.github.com> Date: Mon, 23 Mar 2020 09:42:30 +0200 Subject: [PATCH 127/178] [Mellanox] Update MFT version to 4.14.0 (#4262) Signed-off-by: Noa Or --- platform/mellanox/mft.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/mellanox/mft.mk b/platform/mellanox/mft.mk index e6c9d9ba0ea6..229ba86b4a7b 100644 --- a/platform/mellanox/mft.mk +++ b/platform/mellanox/mft.mk @@ -1,7 +1,7 @@ # Mellanox SAI -MFT_VERSION = 4.13.5 -MFT_REVISION = 1 +MFT_VERSION = 4.14.0 +MFT_REVISION = 500 export MFT_VERSION MFT_REVISION From 8969b7c06f69c614b9beff827bdba8ba714c71ea Mon Sep 17 00:00:00 2001 From: lguohan Date: Tue, 24 Mar 2020 00:04:36 -0700 Subject: [PATCH 128/178] [telemetry]: move default certs location from device metadata to telemetry (#4307) maintains backward compatibility to search original x509 location when telemetry table does not have certs Signed-off-by: Guohan Lu --- dockers/docker-sonic-telemetry/telemetry.sh | 52 +++++++++++++-------- src/sonic-config-engine/minigraph.py | 10 ++-- 2 files changed, 37 insertions(+), 25 deletions(-) diff --git a/dockers/docker-sonic-telemetry/telemetry.sh b/dockers/docker-sonic-telemetry/telemetry.sh index 37ab4dd2d04f..b8f7fffb3ebb 100755 --- a/dockers/docker-sonic-telemetry/telemetry.sh +++ b/dockers/docker-sonic-telemetry/telemetry.sh @@ -1,34 +1,46 @@ #!/usr/bin/env bash -# Try to read telemetry and x509 config from ConfigDB. +# Try to read telemetry and certs config from ConfigDB. # Use default value if no valid config exists X509=`sonic-cfggen -d -v "DEVICE_METADATA['x509']"` -TELEMETRY=`sonic-cfggen -d -v 'TELEMETRY.keys() | join(" ") if TELEMETRY'` +gnmi=`sonic-cfggen -d -v "TELEMETRY['gnmi']"` +certs=`sonic-cfggen -d -v "TELEMETRY['certs']"` TELEMETRY_ARGS=" -logtostderr" export CVL_SCHEMA_PATH=/usr/sbin/schema -if [ -n "$X509" ]; then - SERVER_CRT=`sonic-cfggen -d -v "DEVICE_METADATA['x509']['server_crt']"` - SERVER_KEY=`sonic-cfggen -d -v "DEVICE_METADATA['x509']['server_key']"` - if [ -z $SERVER_CRT ] || [ -z $SERVER_KEY ]; then - TELEMETRY_ARGS+=" --insecure" - else +if [ -n "$certs" ]; then + SERVER_CRT=`sonic-cfggen -d -v "TELEMETRY['certs']['server_crt']"` + SERVER_KEY=`sonic-cfggen -d -v "TELEMETRY['certs']['server_key']"` + if [ -z $SERVER_CRT ] || [ -z $SERVER_KEY ]; then + TELEMETRY_ARGS+=" --insecure" + else + TELEMETRY_ARGS+=" --server_crt $SERVER_CRT --server_key $SERVER_KEY " + fi + + CA_CRT=`sonic-cfggen -d -v "TELEMETRY['certs']['ca_crt']"` + if [ ! -z $CA_CRT ]; then + TELEMETRY_ARGS+=" --ca_crt $CA_CRT" + fi +elif [ -n "$X509" ]; then + SERVER_CRT=`sonic-cfggen -d -v "DEVICE_METADATA['x509']['server_crt']"` + SERVER_KEY=`sonic-cfggen -d -v "DEVICE_METADATA['x509']['server_key']"` + if [ -z $SERVER_CRT ] || [ -z $SERVER_KEY ]; then + TELEMETRY_ARGS+=" --insecure" + else TELEMETRY_ARGS+=" --server_crt $SERVER_CRT --server_key $SERVER_KEY " fi -else - TELEMETRY_ARGS+=" --insecure" -fi -if [ -n "$X509" ]; then - CA_CRT=`sonic-cfggen -d -v "DEVICE_METADATA['x509']['ca_crt']"` - if [ ! -z $CA_CRT ]; then - TELEMETRY_ARGS+=" --ca_crt $CA_CRT" - fi + CA_CRT=`sonic-cfggen -d -v "DEVICE_METADATA['x509']['ca_crt']"` + if [ ! -z $CA_CRT ]; then + TELEMETRY_ARGS+=" --ca_crt $CA_CRT" + fi +else + TELEMETRY_ARGS+=" --insecure" fi # If no configuration entry exists for TELEMETRY, create one default port -if [ -z $TELEMETRY ]; then +if [ -z "$gnmi" ]; then sonic-db-cli CONFIG_DB hset "TELEMETRY|gnmi" port 8080 fi @@ -37,14 +49,14 @@ TELEMETRY_ARGS+=" --port $PORT" CLIENT_AUTH=`sonic-cfggen -d -v "TELEMETRY['gnmi']['client_auth']"` if [ -z $CLIENT_AUTH ] || [ $CLIENT_AUTH == "false" ]; then - TELEMETRY_ARGS+=" --allow_no_client_auth" + TELEMETRY_ARGS+=" --allow_no_client_auth" fi LOG_LEVEL=`sonic-cfggen -d -v "TELEMETRY['gnmi']['log_level']"` if [ ! -z $LOG_LEVEL ]; then - TELEMETRY_ARGS+=" -v=$LOG_LEVEL" + TELEMETRY_ARGS+=" -v=$LOG_LEVEL" else - TELEMETRY_ARGS+=" -v=2" + TELEMETRY_ARGS+=" -v=2" fi exec /usr/sbin/telemetry ${TELEMETRY_ARGS} diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 0f2cbfc60522..c640d1378614 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -636,11 +636,6 @@ def parse_xml(filename, platform=None, port_config_file=None): 'hostname': hostname, 'hwsku': hwsku, 'type': current_device['type'] - }, - 'x509': { - 'server_crt': '/etc/sonic/telemetry/streamingtelemetryserver.cer', - 'server_key': '/etc/sonic/telemetry/streamingtelemetryserver.key', - 'ca_crt': '/etc/sonic/telemetry/dsmsroot.cer' } } results['BGP_NEIGHBOR'] = bgp_sessions @@ -829,6 +824,11 @@ def parse_xml(filename, platform=None, port_config_file=None): 'client_auth': 'true', 'port': '50051', 'log_level': '2' + }, + 'certs': { + 'server_crt': '/etc/sonic/telemetry/streamingtelemetryserver.cer', + 'server_key': '/etc/sonic/telemetry/streamingtelemetryserver.key', + 'ca_crt': '/etc/sonic/telemetry/dsmsroot.cer' } } From 9385e0201fb840adcfc79e69584e3d4bfe9f82bf Mon Sep 17 00:00:00 2001 From: Aravind Mani <53524901+aravindmani-1@users.noreply.github.com> Date: Tue, 24 Mar 2020 09:39:35 +0530 Subject: [PATCH 129/178] [DellEMC] Fix Z9100 port index issue (#4309) --- .../z9100/sonic_platform/chassis.py | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py index 7f4dab3a19c0..3e070d54004e 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/z9100/sonic_platform/chassis.py @@ -162,6 +162,28 @@ def get_serial(self): string: Serial number of chassis """ return self._eeprom.serial_str() + + def get_sfp(self, index): + """ + Retrieves sfp represented by (1-based) index + + Args: + index: An integer, the index (1-based) of the sfp to retrieve. + The index should be the sequence of a physical port in a chassis, + starting from 1. + For example, 0 for Ethernet0, 1 for Ethernet4 and so on. + + Returns: + An object dervied from SfpBase representing the specified sfp + """ + sfp = None + + try: + sfp = self._sfp_list[index-1] + except IndexError: + sys.stderr.write("SFP index {} out of range (1-{})\n".format( + index, len(self._sfp_list)-1)) + return sfp def get_status(self): """ From 4a99a763d276f7df6a2a82c14ed9fb5e2383b8d8 Mon Sep 17 00:00:00 2001 From: Abhishek Dosi Date: Tue, 24 Mar 2020 15:40:42 -0700 Subject: [PATCH 130/178] [SubModule Update] sonic-swsss . Following changes: Don't remove RIF for Vnet interface when ip prefix is deleted (#1225) --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index 71bd8558e20e..1e29fa4c200f 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 71bd8558e20e36ab20e2579786645580feb0def2 +Subproject commit 1e29fa4c200ff2fe3c733be7289a64740fa51d88 From 1ba894426809d30c320c37195c5ec1feb6a3a6cc Mon Sep 17 00:00:00 2001 From: Abhishek Dosi Date: Tue, 24 Mar 2020 15:43:16 -0700 Subject: [PATCH 131/178] [Submodule Update] sonic-utilities Following Changes: [fwutil]: Use overlay driver when mounting next image filesystem (#825) Fix for adding L3 interface to Vlan group (#826)Fix for adding L3 interface to Vlan group (#826) [db_migrator]Do DB migration for buffer pool size change on Mellanox platform (#833) explicitly specify command with underscores (#846) [intfutil] set speed to 0 when interface speed is not available (#839) --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index a2ca28d1e3be..144290c5e717 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit a2ca28d1e3be76e85127bd8dc4098fda719e1582 +Subproject commit 144290c5e7179e903bc57f82ac8a8fe413114218 From 83c7770d3ab424f84ee83ce562fddbf990b3c17d Mon Sep 17 00:00:00 2001 From: Renuka Manavalan <47282725+renukamanavalan@users.noreply.github.com> Date: Tue, 24 Mar 2020 23:39:39 -0700 Subject: [PATCH 132/178] [submodule]: Update sonic-mgmt-framework to fix a build break fix. (#4318) Module updated: sonic-mgmt-framework Azure/sonic-mgmt-framework#44 --- src/sonic-mgmt-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-mgmt-framework b/src/sonic-mgmt-framework index 3b177823d406..f789b295f4c7 160000 --- a/src/sonic-mgmt-framework +++ b/src/sonic-mgmt-framework @@ -1 +1 @@ -Subproject commit 3b177823d406f8ff188a9770ff0f34f4820c75fc +Subproject commit f789b295f4c775ac303b4370d9380ebba8ac6272 From 6929d1f3acace2750cface7b7bdbc170ae8a19fb Mon Sep 17 00:00:00 2001 From: lguohan Date: Fri, 27 Mar 2020 10:49:08 -0700 Subject: [PATCH 133/178] [build]: install cmake 3.13.2 (#4319) fix #4315 download and install cmake 3.13.2 from azure storage latest cmake 3.16.3 from stretch-backports breaks the libyang 1.0.73 build Signed-off-by: Guohan Lu --- sonic-slave-stretch/Dockerfile.j2 | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/sonic-slave-stretch/Dockerfile.j2 b/sonic-slave-stretch/Dockerfile.j2 index 4d34e8e81a75..f9e96791464d 100644 --- a/sonic-slave-stretch/Dockerfile.j2 +++ b/sonic-slave-stretch/Dockerfile.j2 @@ -249,9 +249,6 @@ RUN apt-get update && apt-get install -y \ python3-yaml \ # For lockfile procmail \ -# For gtest - libgtest-dev \ - cmake \ # For pam_tacplus build autoconf-archive \ # For iproute2 @@ -382,6 +379,23 @@ RUN apt-get install -y vim # Install rsyslog RUN apt-get install -y rsyslog +RUN apt-get install -y libgtest-dev +RUN apt-get install -y libarchive13 librhash0 +RUN apt-get -t stretch-backports install -y libuv1 +# Install cmake/cmake-data 3.13.2-1_bpo9+1 +# latest cmake 3.16.3 break the build libyang 1.0.73 +RUN wget -O cmake-data_3.13.2-1_bpo9+1_all.deb "https://sonicstorage.blob.core.windows.net/packages/cmake/cmake-data_3.13.2-1_bpo9%2B1_all.deb?st=2020-03-27T02%3A22%3A24Z&se=2100-03-26T19%3A00%3A00Z&sp=rl&sv=2018-03-28&sr=b&sig=Xby%2Bm3OZOjPB%2FSlDbHD65yDcPzAgoys%2FA3vK8RB4BzA%3D" +RUN dpkg -i cmake-data_3.13.2-1_bpo9+1_all.deb || apt-get install -f +{% if CONFIGURED_ARCH == "armhf" %} +RUN wget -O cmake_3.13.2-1_bpo9+1_armhf.deb "https://sonicstorage.blob.core.windows.net/packages/cmake/cmake_3.13.2-1_bpo9%2B1_armhf.deb?st=2020-03-27T02%3A29%3A41Z&se=2100-03-26T19%3A00%3A00Z&sp=rl&sv=2018-03-28&sr=b&sig=sWt7kxrFumn020d2GeutGJ716cuQsFwmAmgU%2BJ0kqnk%3D" +RUN dpkg -i cmake_3.13.2-1_bpo9+1_armhf.deb || apt-get install -f +{% elif CONFIGURED_ARCH == "arm64" %} +RUN wget -O cmake_3.13.2-1_bpo9+1_arm64.deb "https://sonicstorage.blob.core.windows.net/packages/cmake/cmake_3.13.2-1_bpo9%2B1_arm64.deb?st=2020-03-27T02%3A28%3A38Z&se=2100-03-26T19%3A00%3A00Z&sp=rl&sv=2018-03-28&sr=b&sig=rrHMkLi29aI8yH6s52ILCY8VcEbNFrzYT2DmC5RwOgs%3D" +RUN dpkg -i cmake_3.13.2-1_bpo9+1_arm64.deb || apt-get install -f +{% else %} +RUN wget -O cmake_3.13.2-1_bpo9+1_amd64.deb "https://sonicstorage.blob.core.windows.net/packages/cmake/cmake_3.13.2-1_bpo9%2B1_amd64.deb?st=2020-03-27T02%3A27%3A21Z&se=2100-03-26T19%3A00%3A00Z&sp=rl&sv=2018-03-28&sr=b&sig=4MvmmDBQuicFEJYakLm7xCNU19yJ8GIP4ankFSnITKY%3D" +RUN dpkg -i cmake_3.13.2-1_bpo9+1_amd64.deb || apt-get install -f +{% endif %} RUN cd /usr/src/gtest && cmake . && make -C /usr/src/gtest RUN mkdir /var/run/sshd From a059d7ec0e1128e7b048601e94f14ca3a805d18b Mon Sep 17 00:00:00 2001 From: Garrick He <32883830+GarrickHe@users.noreply.github.com> Date: Sat, 28 Mar 2020 11:43:48 -0700 Subject: [PATCH 134/178] [procdockerstatsd] Fix CMD field in dB (#4335) * Fix the CMD for the PROCESSSTATS entries so that there is a space between the command name and the arguments. Signed-off-by: Garrick He --- files/image_config/procdockerstatsd/procdockerstatsd | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/files/image_config/procdockerstatsd/procdockerstatsd b/files/image_config/procdockerstatsd/procdockerstatsd index a7bdcd6e6ce6..65d4b029b0ff 100755 --- a/files/image_config/procdockerstatsd/procdockerstatsd +++ b/files/image_config/procdockerstatsd/procdockerstatsd @@ -41,8 +41,8 @@ class ProcDockerStats: def __init__(self): self.state_db = swsssdk.SonicV2Connector(host=REDIS_HOSTIP) - self.state_db.connect("STATE_DB") - + self.state_db.connect("STATE_DB") + def run_command(self, cmd): proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) (stdout, stderr) = proc.communicate() @@ -75,7 +75,7 @@ class ProcDockerStats: # To remove extra space before UID val = list(filter(None, values1)) # Merging extra columns created due to space in cmd ouput - val[8:] = [''.join(val[8:])] + val[8:] = [' '.join(val[8:])] process_data = dict(zip(keylist, val)) process_data_list.append(process_data) return process_data_list @@ -109,10 +109,10 @@ class ProcDockerStats: for row in dict_list[0:]: cid = row.get('CONTAINER ID') if cid: - key = 'DOCKER_STATS|' + str(cid) + key = 'DOCKER_STATS|' + str(cid) dockerdict[key] = {} dockerdict[key]['NAME'] = row.get('NAME') - + splitcol = row.get('CPU %') cpu = re.split("%", str(splitcol)) dockerdict[key]['CPU%'] = str(cpu[0]) @@ -131,7 +131,7 @@ class ProcDockerStats: netio = re.split(" / ", str(splitcol)) dockerdict[key]['NET_IN_BYTES'] = str(self.convert_to_bytes(netio[0])) dockerdict[key]['NET_OUT_BYTES'] = str(self.convert_to_bytes(netio[1])) - + splitcol = row.get('BLOCK I/O') blockio = re.split(" / ", str(splitcol)) dockerdict[key]['BLOCK_IN_BYTES'] = str(self.convert_to_bytes(blockio[0])) From 2fd1641feb74f52e7965f46753618843b81d4da9 Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Sat, 28 Mar 2020 21:45:38 +0300 Subject: [PATCH 135/178] copy spc3 fw file to image (#4328) --- files/build_templates/sonic_debian_extension.j2 | 1 + 1 file changed, 1 insertion(+) diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 9967f0fefdef..66391c7bac8d 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -455,6 +455,7 @@ sudo cp {{src}} $FILESYSTEM_ROOT/{{dst}} sudo mkdir -p $FILESYSTEM_ROOT/etc/mlnx/ sudo cp $files_path/$MLNX_SPC_FW_FILE $FILESYSTEM_ROOT/etc/mlnx/fw-SPC.mfa sudo cp $files_path/$MLNX_SPC2_FW_FILE $FILESYSTEM_ROOT/etc/mlnx/fw-SPC2.mfa +sudo cp $files_path/$MLNX_SPC3_FW_FILE $FILESYSTEM_ROOT/etc/mlnx/fw-SPC3.mfa sudo cp $files_path/$ISSU_VERSION_FILE $FILESYSTEM_ROOT/etc/mlnx/issu-version sudo cp $files_path/$MLNX_FFB_SCRIPT $FILESYSTEM_ROOT/usr/bin/mlnx-ffb.sh sudo cp $files_path/$ONIE_FW_UPDATE $FILESYSTEM_ROOT/usr/bin/onie-fw-update.sh From d35e382dad526638aae27abf1039d91ac4a2ef82 Mon Sep 17 00:00:00 2001 From: rlhui Date: Sun, 29 Mar 2020 23:07:08 -0700 Subject: [PATCH 136/178] [multi-asic]: Update reload of systemd services to support multi-asic platform --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 144290c5e717..1adf83c1a0df 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 144290c5e7179e903bc57f82ac8a8fe413114218 +Subproject commit 1adf83c1a0dfc888f0d4765d03fd59fac0b5ed1e From a5a11f6e7da549a0352e6d5c2b37c924b3846c83 Mon Sep 17 00:00:00 2001 From: Wirut Getbamrung Date: Wed, 1 Apr 2020 15:24:55 +0700 Subject: [PATCH 137/178] [device/celestica]: Fix xcvrd error (#3979) (#4345) * [device/celestica]: add pmon_daemon_control config * [device/celestica]: update sfp index follow port_config * [device/celestica]: update get_watchdog to avoid multiple daemon try opening watchdog --- .../pmon_daemon_control.json | 3 +++ .../sonic_platform/chassis.py | 19 ++++++++++++++++--- .../x86_64-cel_e1031-r0/sonic_platform/sfp.py | 2 +- .../pmon_daemon_control.json | 3 +++ .../pmon_daemon_control.json | 3 +++ .../sonic_platform/chassis.py | 19 ++++++++++++++++--- .../sonic_platform/sfp.py | 2 +- .../pmon_daemon_control.json | 3 +++ 8 files changed, 46 insertions(+), 8 deletions(-) create mode 100644 device/celestica/x86_64-cel_e1031-r0/pmon_daemon_control.json create mode 100644 device/celestica/x86_64-cel_midstone-r0/pmon_daemon_control.json create mode 100644 device/celestica/x86_64-cel_seastone-r0/pmon_daemon_control.json create mode 100644 device/celestica/x86_64-cel_silverstone-r0/pmon_daemon_control.json diff --git a/device/celestica/x86_64-cel_e1031-r0/pmon_daemon_control.json b/device/celestica/x86_64-cel_e1031-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..94592fa8cebc --- /dev/null +++ b/device/celestica/x86_64-cel_e1031-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_ledd": true +} diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py index 99eb49ce53e0..719170d831b7 100644 --- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py +++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py @@ -19,7 +19,6 @@ from sonic_platform.fan import Fan from sonic_platform.psu import Psu from sonic_platform.component import Component - from sonic_platform.watchdog import Watchdog from sonic_platform.thermal import Thermal from sonic_platform.sfp import Sfp from sonic_platform.eeprom import Tlv @@ -54,7 +53,9 @@ def __init__(self): for index in range(0, NUM_THERMAL): thermal = Thermal(index) self._thermal_list.append(thermal) - for index in range(0, NUM_SFP): + # sfp index start from 1 + self._sfp_list.append(None) + for index in range(1, NUM_SFP+1): sfp = Sfp(index) self._sfp_list.append(sfp) for index in range(0, NUM_COMPONENT): @@ -63,7 +64,6 @@ def __init__(self): self._reboot_cause_path = HOST_REBOOT_CAUSE_PATH if self.__is_host( ) else PMON_REBOOT_CAUSE_PATH - self._watchdog = Watchdog() self._eeprom = Tlv() def __is_host(self): @@ -134,3 +134,16 @@ def get_reboot_cause(self): description = 'Unknown reason' return (reboot_cause, description) + + def get_watchdog(self): + """ + Retreives hardware watchdog device on this chassis + Returns: + An object derived from WatchdogBase representing the hardware + watchdog device + """ + if self._watchdog is None: + from sonic_platform.watchdog import Watchdog + self._watchdog = Watchdog() + + return self._watchdog diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/sfp.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/sfp.py index 4cfdcf50b66d..6ef8838ba8af 100644 --- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/sfp.py +++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/sfp.py @@ -94,7 +94,7 @@ class Sfp(SfpBase): def __init__(self, sfp_index): # Init index self.index = sfp_index - self.port_num = self.index + 1 + self.port_num = self.index # Init eeprom path eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom' diff --git a/device/celestica/x86_64-cel_midstone-r0/pmon_daemon_control.json b/device/celestica/x86_64-cel_midstone-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..94592fa8cebc --- /dev/null +++ b/device/celestica/x86_64-cel_midstone-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_ledd": true +} diff --git a/device/celestica/x86_64-cel_seastone-r0/pmon_daemon_control.json b/device/celestica/x86_64-cel_seastone-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..94592fa8cebc --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_ledd": true +} diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py index c9447b56a2fe..7db46e55bd8c 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py @@ -19,7 +19,6 @@ from sonic_platform.fan import Fan from sonic_platform.psu import Psu from sonic_platform.component import Component - from sonic_platform.watchdog import Watchdog from sonic_platform.thermal import Thermal from sonic_platform.sfp import Sfp from sonic_platform.eeprom import Tlv @@ -56,14 +55,15 @@ def __init__(self): for index in range(0, NUM_THERMAL): thermal = Thermal(index) self._thermal_list.append(thermal) - for index in range(0, NUM_SFP): + # sfp index start from 1 + self._sfp_list.append(None) + for index in range(1, NUM_SFP+1): sfp = Sfp(index) self._sfp_list.append(sfp) for index in range(0, NUM_COMPONENT): component = Component(index) self._component_list.append(component) - self._watchdog = Watchdog() self._eeprom = Tlv() def __is_host(self): @@ -146,3 +146,16 @@ def get_reboot_cause(self): description = 'Unknown reason' return (reboot_cause, description) + + def get_watchdog(self): + """ + Retreives hardware watchdog device on this chassis + Returns: + An object derived from WatchdogBase representing the hardware + watchdog device + """ + if self._watchdog is None: + from sonic_platform.watchdog import Watchdog + self._watchdog = Watchdog() + + return self._watchdog diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/sfp.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/sfp.py index 3a02be39df6e..04fb36b72b8f 100644 --- a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/sfp.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/sfp.py @@ -100,7 +100,7 @@ class Sfp(SfpBase): def __init__(self, sfp_index): # Init index self.index = sfp_index - self.port_num = self.index + 1 if self.PORT_START == 1 else index + self.port_num = self.index # Init eeprom path eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom' diff --git a/device/celestica/x86_64-cel_silverstone-r0/pmon_daemon_control.json b/device/celestica/x86_64-cel_silverstone-r0/pmon_daemon_control.json new file mode 100644 index 000000000000..94592fa8cebc --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/pmon_daemon_control.json @@ -0,0 +1,3 @@ +{ + "skip_ledd": true +} From 2e87a16941a5624c701baa39044ff14eadc6c0da Mon Sep 17 00:00:00 2001 From: SuvarnaMeenakshi <50386592+SuvarnaMeenakshi@users.noreply.github.com> Date: Tue, 31 Mar 2020 10:06:19 -0700 Subject: [PATCH 138/178] Multi-ASIC implementation (#3888) Changes made to support multi-asic platform. Added multi-instance support for swss, syncd, database, bgp, teamd and lldp. --- .../msft_multi_asic_vs/0/lanemap.ini | 32 ++++++ .../msft_multi_asic_vs/0/sai.profile | 7 +- .../msft_multi_asic_vs/1/lanemap.ini | 32 ++++++ .../msft_multi_asic_vs/1/sai.profile | 7 +- .../msft_multi_asic_vs/2/lanemap.ini | 32 ++++++ .../msft_multi_asic_vs/2/sai.profile | 7 +- .../msft_multi_asic_vs/3/lanemap.ini | 32 ++++++ .../msft_multi_asic_vs/3/sai.profile | 7 +- .../msft_multi_asic_vs/4/lanemap.ini | 32 ++++++ .../msft_multi_asic_vs/4/sai.profile | 7 +- .../msft_multi_asic_vs/5/lanemap.ini | 32 ++++++ .../msft_multi_asic_vs/5/sai.profile | 7 +- .../msft_multi_asic_vs/topology.sh | 13 +-- dockers/docker-fpm-frr/bgpd.conf.default.j2 | 20 ++++ files/build_templates/database.service.j2 | 1 + files/build_templates/docker_image_ctl.j2 | 69 +++++++----- files/build_templates/lldp.service.j2 | 18 ---- .../per_namespace/bgp.service.j2 | 21 ++++ .../per_namespace/database.service.j2 | 22 ++++ .../per_namespace/lldp.service.j2 | 22 ++++ .../per_namespace/swss.service.j2 | 31 ++++++ .../per_namespace/syncd.service.j2 | 33 ++++++ .../per_namespace/teamd.service.j2 | 19 ++++ .../single_instance/bgp.service.j2 | 18 ---- .../single_instance/database.service.j2 | 18 ---- .../single_instance/swss.service.j2 | 25 ----- .../single_instance/syncd.service.j2 | 30 ------ .../single_instance/teamd.service.j2 | 18 ---- .../build_templates/sonic_debian_extension.j2 | 4 + files/image_config/topology/topology.sh | 18 ++-- files/scripts/sonic-netns-exec | 12 +++ files/scripts/swss.sh | 100 ++++++++++++------ files/scripts/syncd.sh | 55 ++++++---- platform/vs/sonic_multiasic.xml | 2 +- rules/docker-fpm-frr.mk | 1 - slave.mk | 28 +++-- 36 files changed, 586 insertions(+), 246 deletions(-) create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/lanemap.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/lanemap.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/lanemap.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/lanemap.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/lanemap.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/lanemap.ini create mode 120000 files/build_templates/database.service.j2 delete mode 100644 files/build_templates/lldp.service.j2 create mode 100644 files/build_templates/per_namespace/bgp.service.j2 create mode 100644 files/build_templates/per_namespace/database.service.j2 create mode 100644 files/build_templates/per_namespace/lldp.service.j2 create mode 100644 files/build_templates/per_namespace/swss.service.j2 create mode 100644 files/build_templates/per_namespace/syncd.service.j2 create mode 100644 files/build_templates/per_namespace/teamd.service.j2 delete mode 100644 files/build_templates/single_instance/bgp.service.j2 delete mode 100644 files/build_templates/single_instance/database.service.j2 delete mode 100644 files/build_templates/single_instance/swss.service.j2 delete mode 100644 files/build_templates/single_instance/syncd.service.j2 delete mode 100644 files/build_templates/single_instance/teamd.service.j2 create mode 100755 files/scripts/sonic-netns-exec diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/lanemap.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/lanemap.ini new file mode 100644 index 000000000000..36278a01778c --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/lanemap.ini @@ -0,0 +1,32 @@ +eth1:25,26,27,28 +eth2:29,30,31,32 +eth3:33,34,35,36 +eth4:37,38,39,40 +eth5:45,46,47,48 +eth6:41,42,43,44 +eth7:1,2,3,4 +eth8:5,6,7,8 +eth9:13,14,15,16 +eth10:9,10,11,12 +eth11:17,18,19,20 +eth12:21,22,23,24 +eth13:53,54,55,56 +eth14:49,50,51,52 +eth15:57,58,59,60 +eth16:61,62,63,64 +eth17:69,70,71,72 +eth18:65,66,67,68 +eth19:73,74,75,76 +eth20:77,78,79,80 +eth21:109,110,111,112 +eth22:105,106,107,108 +eth23:113,114,115,116 +eth24:117,118,119,120 +eth25:125,126,127,128 +eth26:121,122,123,124 +eth27:81,82,83,84 +eth28:85,86,87,88 +eth29:93,94,95,96 +eth30:89,90,91,92 +eth31:101,102,103,104 +eth32:97,98,99,100 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/sai.profile index 52e2e289af60..bfc466f27e54 100644 --- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/sai.profile +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/sai.profile @@ -1,2 +1,5 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm -SAI_NUM_ECMP_MEMBERS=32 +SAI_WARM_BOOT_READ_FILE=/var/cache/sai_warmboot.bin +SAI_WARM_BOOT_WRITE_FILE=/var/cache/sai_warmboot.bin +SAI_VS_SWITCH_TYPE=SAI_VS_SWITCH_TYPE_BCM56850 +SAI_VS_HOSTIF_USE_TAP_DEVICE=true +SAI_VS_INTERFACE_LANE_MAP_FILE=/usr/share/sonic/hwsku/lanemap.ini diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/lanemap.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/lanemap.ini new file mode 100644 index 000000000000..36278a01778c --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/lanemap.ini @@ -0,0 +1,32 @@ +eth1:25,26,27,28 +eth2:29,30,31,32 +eth3:33,34,35,36 +eth4:37,38,39,40 +eth5:45,46,47,48 +eth6:41,42,43,44 +eth7:1,2,3,4 +eth8:5,6,7,8 +eth9:13,14,15,16 +eth10:9,10,11,12 +eth11:17,18,19,20 +eth12:21,22,23,24 +eth13:53,54,55,56 +eth14:49,50,51,52 +eth15:57,58,59,60 +eth16:61,62,63,64 +eth17:69,70,71,72 +eth18:65,66,67,68 +eth19:73,74,75,76 +eth20:77,78,79,80 +eth21:109,110,111,112 +eth22:105,106,107,108 +eth23:113,114,115,116 +eth24:117,118,119,120 +eth25:125,126,127,128 +eth26:121,122,123,124 +eth27:81,82,83,84 +eth28:85,86,87,88 +eth29:93,94,95,96 +eth30:89,90,91,92 +eth31:101,102,103,104 +eth32:97,98,99,100 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/sai.profile index 52e2e289af60..bfc466f27e54 100644 --- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/sai.profile +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/sai.profile @@ -1,2 +1,5 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm -SAI_NUM_ECMP_MEMBERS=32 +SAI_WARM_BOOT_READ_FILE=/var/cache/sai_warmboot.bin +SAI_WARM_BOOT_WRITE_FILE=/var/cache/sai_warmboot.bin +SAI_VS_SWITCH_TYPE=SAI_VS_SWITCH_TYPE_BCM56850 +SAI_VS_HOSTIF_USE_TAP_DEVICE=true +SAI_VS_INTERFACE_LANE_MAP_FILE=/usr/share/sonic/hwsku/lanemap.ini diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/lanemap.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/lanemap.ini new file mode 100644 index 000000000000..36278a01778c --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/lanemap.ini @@ -0,0 +1,32 @@ +eth1:25,26,27,28 +eth2:29,30,31,32 +eth3:33,34,35,36 +eth4:37,38,39,40 +eth5:45,46,47,48 +eth6:41,42,43,44 +eth7:1,2,3,4 +eth8:5,6,7,8 +eth9:13,14,15,16 +eth10:9,10,11,12 +eth11:17,18,19,20 +eth12:21,22,23,24 +eth13:53,54,55,56 +eth14:49,50,51,52 +eth15:57,58,59,60 +eth16:61,62,63,64 +eth17:69,70,71,72 +eth18:65,66,67,68 +eth19:73,74,75,76 +eth20:77,78,79,80 +eth21:109,110,111,112 +eth22:105,106,107,108 +eth23:113,114,115,116 +eth24:117,118,119,120 +eth25:125,126,127,128 +eth26:121,122,123,124 +eth27:81,82,83,84 +eth28:85,86,87,88 +eth29:93,94,95,96 +eth30:89,90,91,92 +eth31:101,102,103,104 +eth32:97,98,99,100 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/sai.profile index 52e2e289af60..bfc466f27e54 100644 --- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/sai.profile +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/sai.profile @@ -1,2 +1,5 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm -SAI_NUM_ECMP_MEMBERS=32 +SAI_WARM_BOOT_READ_FILE=/var/cache/sai_warmboot.bin +SAI_WARM_BOOT_WRITE_FILE=/var/cache/sai_warmboot.bin +SAI_VS_SWITCH_TYPE=SAI_VS_SWITCH_TYPE_BCM56850 +SAI_VS_HOSTIF_USE_TAP_DEVICE=true +SAI_VS_INTERFACE_LANE_MAP_FILE=/usr/share/sonic/hwsku/lanemap.ini diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/lanemap.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/lanemap.ini new file mode 100644 index 000000000000..36278a01778c --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/lanemap.ini @@ -0,0 +1,32 @@ +eth1:25,26,27,28 +eth2:29,30,31,32 +eth3:33,34,35,36 +eth4:37,38,39,40 +eth5:45,46,47,48 +eth6:41,42,43,44 +eth7:1,2,3,4 +eth8:5,6,7,8 +eth9:13,14,15,16 +eth10:9,10,11,12 +eth11:17,18,19,20 +eth12:21,22,23,24 +eth13:53,54,55,56 +eth14:49,50,51,52 +eth15:57,58,59,60 +eth16:61,62,63,64 +eth17:69,70,71,72 +eth18:65,66,67,68 +eth19:73,74,75,76 +eth20:77,78,79,80 +eth21:109,110,111,112 +eth22:105,106,107,108 +eth23:113,114,115,116 +eth24:117,118,119,120 +eth25:125,126,127,128 +eth26:121,122,123,124 +eth27:81,82,83,84 +eth28:85,86,87,88 +eth29:93,94,95,96 +eth30:89,90,91,92 +eth31:101,102,103,104 +eth32:97,98,99,100 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/sai.profile index 52e2e289af60..bfc466f27e54 100644 --- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/sai.profile +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/sai.profile @@ -1,2 +1,5 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm -SAI_NUM_ECMP_MEMBERS=32 +SAI_WARM_BOOT_READ_FILE=/var/cache/sai_warmboot.bin +SAI_WARM_BOOT_WRITE_FILE=/var/cache/sai_warmboot.bin +SAI_VS_SWITCH_TYPE=SAI_VS_SWITCH_TYPE_BCM56850 +SAI_VS_HOSTIF_USE_TAP_DEVICE=true +SAI_VS_INTERFACE_LANE_MAP_FILE=/usr/share/sonic/hwsku/lanemap.ini diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/lanemap.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/lanemap.ini new file mode 100644 index 000000000000..36278a01778c --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/lanemap.ini @@ -0,0 +1,32 @@ +eth1:25,26,27,28 +eth2:29,30,31,32 +eth3:33,34,35,36 +eth4:37,38,39,40 +eth5:45,46,47,48 +eth6:41,42,43,44 +eth7:1,2,3,4 +eth8:5,6,7,8 +eth9:13,14,15,16 +eth10:9,10,11,12 +eth11:17,18,19,20 +eth12:21,22,23,24 +eth13:53,54,55,56 +eth14:49,50,51,52 +eth15:57,58,59,60 +eth16:61,62,63,64 +eth17:69,70,71,72 +eth18:65,66,67,68 +eth19:73,74,75,76 +eth20:77,78,79,80 +eth21:109,110,111,112 +eth22:105,106,107,108 +eth23:113,114,115,116 +eth24:117,118,119,120 +eth25:125,126,127,128 +eth26:121,122,123,124 +eth27:81,82,83,84 +eth28:85,86,87,88 +eth29:93,94,95,96 +eth30:89,90,91,92 +eth31:101,102,103,104 +eth32:97,98,99,100 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/sai.profile index 52e2e289af60..bfc466f27e54 100644 --- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/sai.profile +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/sai.profile @@ -1,2 +1,5 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm -SAI_NUM_ECMP_MEMBERS=32 +SAI_WARM_BOOT_READ_FILE=/var/cache/sai_warmboot.bin +SAI_WARM_BOOT_WRITE_FILE=/var/cache/sai_warmboot.bin +SAI_VS_SWITCH_TYPE=SAI_VS_SWITCH_TYPE_BCM56850 +SAI_VS_HOSTIF_USE_TAP_DEVICE=true +SAI_VS_INTERFACE_LANE_MAP_FILE=/usr/share/sonic/hwsku/lanemap.ini diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/lanemap.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/lanemap.ini new file mode 100644 index 000000000000..36278a01778c --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/lanemap.ini @@ -0,0 +1,32 @@ +eth1:25,26,27,28 +eth2:29,30,31,32 +eth3:33,34,35,36 +eth4:37,38,39,40 +eth5:45,46,47,48 +eth6:41,42,43,44 +eth7:1,2,3,4 +eth8:5,6,7,8 +eth9:13,14,15,16 +eth10:9,10,11,12 +eth11:17,18,19,20 +eth12:21,22,23,24 +eth13:53,54,55,56 +eth14:49,50,51,52 +eth15:57,58,59,60 +eth16:61,62,63,64 +eth17:69,70,71,72 +eth18:65,66,67,68 +eth19:73,74,75,76 +eth20:77,78,79,80 +eth21:109,110,111,112 +eth22:105,106,107,108 +eth23:113,114,115,116 +eth24:117,118,119,120 +eth25:125,126,127,128 +eth26:121,122,123,124 +eth27:81,82,83,84 +eth28:85,86,87,88 +eth29:93,94,95,96 +eth30:89,90,91,92 +eth31:101,102,103,104 +eth32:97,98,99,100 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/sai.profile index 52e2e289af60..bfc466f27e54 100644 --- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/sai.profile +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/sai.profile @@ -1,2 +1,5 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm -SAI_NUM_ECMP_MEMBERS=32 +SAI_WARM_BOOT_READ_FILE=/var/cache/sai_warmboot.bin +SAI_WARM_BOOT_WRITE_FILE=/var/cache/sai_warmboot.bin +SAI_VS_SWITCH_TYPE=SAI_VS_SWITCH_TYPE_BCM56850 +SAI_VS_HOSTIF_USE_TAP_DEVICE=true +SAI_VS_INTERFACE_LANE_MAP_FILE=/usr/share/sonic/hwsku/lanemap.ini diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/topology.sh b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/topology.sh index 378f794190d4..cf70f3063189 100755 --- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/topology.sh +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/topology.sh @@ -14,9 +14,10 @@ start () { # eth48 - eth63: asic5 for ASIC in `seq $FIRST_FRONTEND_ASIC $LAST_FRONTEND_ASIC`; do for NUM in `seq 1 16`; do - ORIG="eth$((16 * $ASIC + $NUM - 1))" + ORIG="eth$((16 * $ASIC + $NUM))" TEMP="ethTemp999" - NEW="eth$(($NUM + 16))" + NEW="eth$(($NUM))" + echo "$ASIC : $NEW old $ORIG" ip link set dev $ORIG down ip link set dev $ORIG name $TEMP # rename to prevent conflicts before renaming in new namespace ip link set dev $TEMP netns asic$ASIC @@ -29,8 +30,9 @@ start () { for BACKEND in `seq $FIRST_BACKEND_ASIC $LAST_BACKEND_ASIC`; do for FRONTEND in `seq $FIRST_FRONTEND_ASIC $LAST_FRONTEND_ASIC`; do for LINK in `seq 1 8`; do - BACK_NAME="eth$((8 * $FRONTEND + $LINK))" - FRONT_NAME="eth$((8 * $(($LAST_BACKEND_ASIC - $BACKEND)) + $LINK))" + FRONT_NAME="eth$((8 * $(($BACKEND - $FIRST_BACKEND_ASIC)) + $LINK + 16))" + BACK_NAME="eth$((8 * $FRONTEND + $LINK))" + echo "$FRONTEND:$FRONT_NAME - $BACKEND:$BACK_NAME" TEMP_BACK="ethBack999" TEMP_FRONT="ethFront999" @@ -52,7 +54,7 @@ stop() { for ASIC in `seq $FIRST_FRONTEND_ASIC $LAST_FRONTEND_ASIC`; do for NUM in `seq 1 16`; do TEMP="eth999" - OLD="eth$(($NUM + 16))" + OLD="eth$((16 * $ASIC + $NUM))" NAME="eth$((16 * $ASIC + $NUM - 1))" sudo ip netns exec asic$ASIC ip link set dev $OLD down sudo ip netns exec asic$ASIC ip link set dev $OLD name $TEMP @@ -78,4 +80,3 @@ case "$1" in echo "Usage: $0 {start|stop}" ;; esac - diff --git a/dockers/docker-fpm-frr/bgpd.conf.default.j2 b/dockers/docker-fpm-frr/bgpd.conf.default.j2 index e12782b035aa..2bf80b80a787 100644 --- a/dockers/docker-fpm-frr/bgpd.conf.default.j2 +++ b/dockers/docker-fpm-frr/bgpd.conf.default.j2 @@ -23,6 +23,20 @@ route-map TO_BGP_PEER_V4 permit 100 ! route-map TO_BGP_PEER_V6 permit 100 ! +{% if DEVICE_METADATA['localhost']['type'] == 'InternalFrontend' %} +route-map HIDE_INTERNAL permit 10 + set community local-AS +! +{% endif %} +{% if DEVICE_METADATA['localhost']['type'] == 'InternalBackend' %} +route-map OVERRIDE_ORIGINATOR_ID permit 10 +{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} +{% if prefix | ipv4 and name == 'Loopback0' %} + set originator-id {{ prefix | ip }} +{% endif %} +{% endfor %} +! +{% endif %} {% if BGP_MONITORS is defined and BGP_MONITORS|length > 0 %} route-map FROM_BGPMON deny 10 ! @@ -37,6 +51,9 @@ route-map set-next-hop-global-v6 permit 10 set ipv6 next-hop prefer-global ! router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} +{% if DEVICE_METADATA['localhost']['type'] == 'InternalFrontend' %} + redistribute connected route-map HIDE_INTERNAL +{% endif %} bgp log-neighbor-changes bgp bestpath as-path multipath-relax no bgp default ipv4-unicast @@ -151,6 +168,9 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} neighbor {{ neighbor_addr }} peer-group BGPMON neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} neighbor {{ neighbor_addr }} activate +{% if DEVICE_METADATA['localhost']['type'] == 'InternalBackend' %} + neighbor {{ neighbor_addr }} route-map OVERRIDE_ORIGINATOR_ID in +{% endif %} address-family ipv6 neighbor {{ neighbor_addr }} activate exit-address-family diff --git a/files/build_templates/database.service.j2 b/files/build_templates/database.service.j2 new file mode 120000 index 000000000000..63340abef881 --- /dev/null +++ b/files/build_templates/database.service.j2 @@ -0,0 +1 @@ +per_namespace/database.service.j2 \ No newline at end of file diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 5de892555a1b..297c9dd1c2bd 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -14,15 +14,16 @@ link_namespace() { mkdir -p /var/run/netns PID="$(docker inspect -f {{"'{{.State.Pid}}'"}} "{{docker_container_name}}$DEV")" - if `ip netns | grep --quiet -w "{{docker_container_name}}$DEV"`; then # namespace exists - if [ $(readlink -f /var/run/netns/$NET_NS$DEV) = $(readlink -f /proc/$PID/ns/net) ]; then # namespace is correctly linked + PIDS=`ip netns pids "$NET_NS" 2>/dev/null` + if [ "$?" -eq "0" ]; then # namespace exists + if `echo $PIDS | grep --quiet -w $PID`; then # namespace is correctly linked return 0 else # if it's incorrectly linked remove it - ip netns delete "{{docker_container_name}}$DEV" + ip netns delete $NET_NS fi fi - ln -s /proc/$PID/ns/net /var/run/netns/$NET_NS$DEV + ln -s /proc/$PID/ns/net /var/run/netns/$NET_NS } {%- endif %} @@ -56,14 +57,14 @@ function preStartAction() WARM_DIR=/host/warmboot if [[ ("$BOOT_TYPE" == "warm" || "$BOOT_TYPE" == "fastfast") && -f $WARM_DIR/dump.rdb ]]; then # Load redis content from /host/warmboot/dump.rdb - docker cp $WARM_DIR/dump.rdb database:/var/lib/redis/dump.rdb + docker cp $WARM_DIR/dump.rdb database$DEV:/var/lib/redis/dump.rdb else # Create an emtpy file and overwrite any RDB if already there echo -n > /tmp/dump.rdb - docker cp /tmp/dump.rdb database:/var/lib/redis/ + docker cp /tmp/dump.rdb database$DEV:/var/lib/redis/ fi {%- elif docker_container_name == "snmp" %} - sonic-db-cli STATE_DB HSET 'DEVICE_METADATA|localhost' chassis_serial_number $(decode-syseeprom -s) + sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB HSET 'DEVICE_METADATA|localhost' chassis_serial_number $(decode-syseeprom -s) {%- else %} : # nothing {%- endif %} @@ -76,25 +77,25 @@ function postStartAction() link_namespace $DEV fi # Wait until redis starts - /usr/bin/docker exec database ping_pong_db_insts + /usr/bin/docker exec database$DEV ping_pong_db_insts if [[ ("$BOOT_TYPE" == "warm" || "$BOOT_TYPE" == "fastfast") && -f $WARM_DIR/dump.rdb ]]; then rm -f $WARM_DIR/dump.rdb else # If there is a config_db.json dump file, load it. - if [ -r /etc/sonic/config_db.json ]; then + if [ -r /etc/sonic/config_db$DEV.json ]; then if [ -r /etc/sonic/init_cfg.json ]; then - sonic-cfggen -j /etc/sonic/init_cfg.json -j /etc/sonic/config_db.json --write-to-db + sonic-netns-exec "$NET_NS" sonic-cfggen -j /etc/sonic/init_cfg.json -j /etc/sonic/config_db$DEV.json --write-to-db else - sonic-cfggen -j /etc/sonic/config_db.json --write-to-db + sonic-netns-exec "$NET_NS" sonic-cfggen -j /etc/sonic/config_db$DEV.json --write-to-db fi fi if [[ "$BOOT_TYPE" == "fast" ]]; then # set the key to expire in 3 minutes - sonic-db-cli STATE_DB SET "FAST_REBOOT|system" "1" "EX" "180" + /usr/bin/sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB SET "FAST_REBOOT|system" "1" "EX" "180" fi - sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" + /usr/bin/sonic-netns-exec "$NET_NS" sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" fi if [[ -x /usr/bin/db_migrator.py ]]; then @@ -102,14 +103,14 @@ function postStartAction() /usr/bin/db_migrator.py -o migrate fi {%- elif docker_container_name == "swss" %} - docker exec swss rm -f /ready # remove cruft + docker exec swss$DEV rm -f /ready # remove cruft if [[ "$BOOT_TYPE" == "fast" ]] && [[ -d /host/fast-reboot ]]; then - test -e /host/fast-reboot/fdb.json && docker cp /host/fast-reboot/fdb.json swss:/ - test -e /host/fast-reboot/arp.json && docker cp /host/fast-reboot/arp.json swss:/ - test -e /host/fast-reboot/default_routes.json && docker cp /host/fast-reboot/default_routes.json swss:/ + test -e /host/fast-reboot/fdb.json && docker cp /host/fast-reboot/fdb.json swss$DEV:/ + test -e /host/fast-reboot/arp.json && docker cp /host/fast-reboot/arp.json swss$DEV:/ + test -e /host/fast-reboot/default_routes.json && docker cp /host/fast-reboot/default_routes.json swss$DEV:/ rm -fr /host/fast-reboot fi - docker exec swss touch /ready # signal swssconfig.sh to go + docker exec swss$DEV touch /ready # signal swssconfig.sh to go {%- elif docker_container_name == "pmon" %} DEVPATH="/usr/share/sonic/device" @@ -131,14 +132,14 @@ start() { BOOT_TYPE=`getBootType` # Obtain our platform as we will mount directories with these names in each docker - PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` + PLATFORM=`sonic-netns-exec "$NET_NS" sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` {%- if docker_container_name == "database" %} # Don't mount HWSKU in {{docker_container_name}} container. HWSKU="" {%- else %} # Obtain our HWSKU as we will mount directories with these names in each docker - HWSKU=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hwsku"]'` + HWSKU=`sonic-netns-exec "$NET_NS" sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hwsku"]'` {%- endif %} DOCKERCHECK=`docker inspect --type container {{docker_container_name}}$DEV 2>/dev/null` @@ -185,7 +186,14 @@ start() { NET="container:database$DEV" {%- endif %} fi - +{%- if docker_container_name == "bgp" %} + if [ "$DEV" ]; then + if [ ! -d "/etc/sonic/frr/$DEV" ]; then + mkdir /etc/sonic/frr/$DEV + cp -r /etc/sonic/frr/*.conf /etc/sonic/frr/$DEV + fi + fi +{%- endif %} {%- if sonic_asic_platform == "mellanox" %} # TODO: Mellanox will remove the --tmpfs exception after SDK socket path changed in new SDK version {%- endif %} @@ -215,10 +223,13 @@ start() { --tmpfs /tmp \ {%- endif %} {%- endif %} - -v /var/run/redis:/var/run/redis:rw \ +{%- if docker_container_name == "bgp" %} + -v /etc/sonic/frr/$DEV:/etc/frr:rw \ +{%- endif %} + -v /var/run/redis$DEV:/var/run/redis:rw \ -v /usr/share/sonic/device/$PLATFORM:/usr/share/sonic/platform:ro \ {%- if docker_container_name != "database" %} - -v /usr/share/sonic/device/$PLATFORM/$HWSKU:/usr/share/sonic/hwsku:ro \ + -v /usr/share/sonic/device/$PLATFORM/$HWSKU/$DEV:/usr/share/sonic/hwsku:ro \ {%- endif %} {%- if sonic_asic_platform != "mellanox" %} --tmpfs /tmp \ @@ -230,7 +241,7 @@ start() { } preStartAction - docker start {{docker_container_name}} + docker start {{docker_container_name}}$DEV postStartAction } @@ -241,13 +252,19 @@ wait() { stop() { docker stop {{docker_container_name}}$DEV {%- if docker_container_name == "database" %} - ip netns delete "$NET_NS$DEV" + if [ "$DEV" ]; then + ip netns delete "$NET_NS" + fi {%- endif %} } OP=$1 DEV=$2 # namespace/device number to operate on -NET_NS="asic" #name of the network namespace +if [ "$DEV" ]; then + NET_NS="asic$DEV" #name of the network namespace +else + NET_NS="" +fi case "$1" in start|wait|stop) diff --git a/files/build_templates/lldp.service.j2 b/files/build_templates/lldp.service.j2 deleted file mode 100644 index 2599fc5c5bdc..000000000000 --- a/files/build_templates/lldp.service.j2 +++ /dev/null @@ -1,18 +0,0 @@ -[Unit] -Description=LLDP container -Requires=updategraph.service -After=updategraph.service swss.service syncd.service -Before=ntp-config.service -StartLimitIntervalSec=1200 -StartLimitBurst=3 - -[Service] -User={{ sonicadmin_user }} -ExecStartPre=/usr/bin/{{docker_container_name}}.sh start -ExecStart=/usr/bin/{{docker_container_name}}.sh wait -ExecStop=/usr/bin/{{docker_container_name}}.sh stop -Restart=always -RestartSec=30 - -[Install] -WantedBy=multi-user.target diff --git a/files/build_templates/per_namespace/bgp.service.j2 b/files/build_templates/per_namespace/bgp.service.j2 new file mode 100644 index 000000000000..79e9afc4ebc1 --- /dev/null +++ b/files/build_templates/per_namespace/bgp.service.j2 @@ -0,0 +1,21 @@ +[Unit] +Description=BGP container +Requires=database{% if multi_instance == 'true' %}@%i{% endif %}.service +After=database{% if multi_instance == 'true' %}@%i{% endif %}.service +Requires=updategraph.service +After=updategraph.service +Before=ntp-config.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 + +[Service] +User={{ sonicadmin_user }} +ExecStartPre=/usr/bin/{{docker_container_name}}.sh start{% if multi_instance == 'true' %} %i{% endif %} +ExecStart=/usr/bin/{{docker_container_name}}.sh wait{% if multi_instance == 'true' %} %i{% endif %} +ExecStop=/usr/bin/{{docker_container_name}}.sh stop{% if multi_instance == 'true' %} %i{% endif %} + +Restart=always +RestartSec=30 + +[Install] +WantedBy=multi-user.target diff --git a/files/build_templates/per_namespace/database.service.j2 b/files/build_templates/per_namespace/database.service.j2 new file mode 100644 index 000000000000..396fdc6678c2 --- /dev/null +++ b/files/build_templates/per_namespace/database.service.j2 @@ -0,0 +1,22 @@ +[Unit] +Description=Database container +{% if multi_instance == 'true' %} +Requires=database.service +After=database.service +{% endif %} +Requires=docker.service +After=docker.service +After=rc-local.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 + +[Service] +User=root +ExecStartPre=/usr/bin/{{docker_container_name}}.sh start{% if multi_instance == 'true' %} %i{% endif %} +ExecStart=/usr/bin/{{docker_container_name}}.sh wait{% if multi_instance == 'true' %} %i{% endif %} +ExecStop=/usr/bin/{{docker_container_name}}.sh stop{% if multi_instance == 'true' %} %i{% endif %} +Restart=always +RestartSec=30 + +[Install] +WantedBy=multi-user.target diff --git a/files/build_templates/per_namespace/lldp.service.j2 b/files/build_templates/per_namespace/lldp.service.j2 new file mode 100644 index 000000000000..b48675b03202 --- /dev/null +++ b/files/build_templates/per_namespace/lldp.service.j2 @@ -0,0 +1,22 @@ +[Unit] +Description=LLDP container +Requires=database{% if multi_instance == 'true' %}@%i{% endif %}.service +After=database{% if multi_instance == 'true' %}@%i{% endif %}.service +After=swss{% if multi_instance == 'true' %}@%i{% endif %}.service +After=syncd{% if multi_instance == 'true' %}@%i{% endif %}.service +Requires=updategraph.service +After=updategraph.service +Before=ntp-config.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 + +[Service] +User={{ sonicadmin_user }} +ExecStartPre=/usr/bin/{{docker_container_name}}.sh start{% if multi_instance == 'true' %} %i{% endif %} +ExecStart=/usr/bin/{{docker_container_name}}.sh wait{% if multi_instance == 'true' %} %i{% endif %} +ExecStop=/usr/bin/{{docker_container_name}}.sh stop{% if multi_instance == 'true' %} %i{% endif %} +Restart=always +RestartSec=30 + +[Install] +WantedBy=multi-user.target diff --git a/files/build_templates/per_namespace/swss.service.j2 b/files/build_templates/per_namespace/swss.service.j2 new file mode 100644 index 000000000000..53d6b4497df7 --- /dev/null +++ b/files/build_templates/per_namespace/swss.service.j2 @@ -0,0 +1,31 @@ +[Unit] +Description=switch state service +Requires=database{% if multi_instance == 'true' %}@%i{% endif %}.service +After=database{% if multi_instance == 'true' %}@%i{% endif %}.service +{% if multi_instance == 'true' and sonic_asic_platform == 'vs' %} +Requires=topology.service +After=topology.service +{% endif %} +{% if sonic_asic_platform == 'broadcom' %} +Requires=opennsl-modules.service +{% elif sonic_asic_platform == 'nephos' %} +Requires=nps-modules-4.9.0-11-2-amd64.service +{% endif %} +Requires=updategraph.service +After=updategraph.service +After=interfaces-config.service +Before=ntp-config.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 + +[Service] +User=root +Environment=sonic_asic_platform={{ sonic_asic_platform }} +ExecStartPre=/usr/local/bin/swss.sh start{% if multi_instance == 'true' %} %i{% endif %} +ExecStart=/usr/local/bin/swss.sh wait{% if multi_instance == 'true' %} %i{% endif %} +ExecStop=/usr/local/bin/swss.sh stop{% if multi_instance == 'true' %} %i{% endif %} +Restart=always +RestartSec=30 + +[Install] +WantedBy=multi-user.target diff --git a/files/build_templates/per_namespace/syncd.service.j2 b/files/build_templates/per_namespace/syncd.service.j2 new file mode 100644 index 000000000000..b2922e0d12b6 --- /dev/null +++ b/files/build_templates/per_namespace/syncd.service.j2 @@ -0,0 +1,33 @@ +[Unit] +Description=syncd service +Requires=database{% if multi_instance == 'true' %}@%i{% endif %}.service +After=database{% if multi_instance == 'true' %}@%i{% endif %}.service +After=swss{% if multi_instance == 'true' %}@%i{% endif %}.service +{% if multi_instance == 'true' and sonic_asic_platform == 'vs' %} +Requires=topology.service +After=topology.service +{% endif %} +{% if sonic_asic_platform == 'broadcom' %} +Requires=opennsl-modules.service +After=opennsl-modules.service +{% elif sonic_asic_platform == 'nephos' %} +Requires=nps-modules-4.9.0-11-2-amd64.service +After=nps-modules-4.9.0-11-2-amd64.service +{% endif %} +Requires=updategraph.service +After=updategraph.service +After=interfaces-config.service +Before=ntp-config.service + +[Service] +User=root +Environment=sonic_asic_platform={{ sonic_asic_platform }} +ExecStartPre=/usr/local/bin/syncd.sh start{% if multi_instance == 'true' %} %i{% endif %} +ExecStart=/usr/local/bin/syncd.sh wait{% if multi_instance == 'true' %} %i{% endif %} +ExecStop=/usr/local/bin/syncd.sh stop{% if multi_instance == 'true' %} %i{% endif %} +{% if sonic_asic_platform == 'mellanox' %} +TimeoutStartSec=150 +{% endif %} + +[Install] +WantedBy=multi-user.target diff --git a/files/build_templates/per_namespace/teamd.service.j2 b/files/build_templates/per_namespace/teamd.service.j2 new file mode 100644 index 000000000000..092f9d2ebde2 --- /dev/null +++ b/files/build_templates/per_namespace/teamd.service.j2 @@ -0,0 +1,19 @@ +[Unit] +Description=TEAMD container +After=swss{% if multi_instance == 'true' %}@%i{% endif %}.service +Requires=updategraph.service +After=updategraph.service +Before=ntp-config.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 + +[Service] +User={{ sonicadmin_user }} +ExecStartPre=/usr/bin/{{docker_container_name}}.sh start{% if multi_instance == 'true' %} %i{% endif %} +ExecStart=/usr/bin/{{docker_container_name}}.sh wait{% if multi_instance == 'true' %} %i{% endif %} +ExecStop=/usr/bin/{{docker_container_name}}.sh stop{% if multi_instance == 'true' %} %i{% endif %} +Restart=always +RestartSec=30 + +[Install] +WantedBy=multi-user.target diff --git a/files/build_templates/single_instance/bgp.service.j2 b/files/build_templates/single_instance/bgp.service.j2 deleted file mode 100644 index fdf9d9c78c04..000000000000 --- a/files/build_templates/single_instance/bgp.service.j2 +++ /dev/null @@ -1,18 +0,0 @@ -[Unit] -Description=BGP container -Requires=updategraph.service -After=updategraph.service -Before=ntp-config.service -StartLimitIntervalSec=1200 -StartLimitBurst=3 - -[Service] -User={{ sonicadmin_user }} -ExecStartPre=/usr/bin/{{docker_container_name}}.sh start -ExecStart=/usr/bin/{{docker_container_name}}.sh wait -ExecStop=/usr/bin/{{docker_container_name}}.sh stop -Restart=always -RestartSec=30 - -[Install] -WantedBy=multi-user.target diff --git a/files/build_templates/single_instance/database.service.j2 b/files/build_templates/single_instance/database.service.j2 deleted file mode 100644 index fd0063195e31..000000000000 --- a/files/build_templates/single_instance/database.service.j2 +++ /dev/null @@ -1,18 +0,0 @@ -[Unit] -Description=Database container -Requires=docker.service -After=docker.service -After=rc-local.service -StartLimitIntervalSec=1200 -StartLimitBurst=3 - -[Service] -User=root -ExecStartPre=/usr/bin/{{docker_container_name}}.sh start -ExecStart=/usr/bin/{{docker_container_name}}.sh wait -ExecStop=/usr/bin/{{docker_container_name}}.sh stop -Restart=always -RestartSec=30 - -[Install] -WantedBy=multi-user.target diff --git a/files/build_templates/single_instance/swss.service.j2 b/files/build_templates/single_instance/swss.service.j2 deleted file mode 100644 index 44206b08ebce..000000000000 --- a/files/build_templates/single_instance/swss.service.j2 +++ /dev/null @@ -1,25 +0,0 @@ -[Unit] -Description=switch state service -Requires=database.service updategraph.service -{% if sonic_asic_platform == 'broadcom' %} -Requires=opennsl-modules.service -{% elif sonic_asic_platform == 'nephos' %} -Requires=nps-modules-4.9.0-11-2-amd64.service -{% endif %} -After=database.service updategraph.service -After=interfaces-config.service -Before=ntp-config.service -StartLimitIntervalSec=1200 -StartLimitBurst=3 - -[Service] -User=root -Environment=sonic_asic_platform={{ sonic_asic_platform }} -ExecStartPre=/usr/local/bin/swss.sh start -ExecStart=/usr/local/bin/swss.sh wait -ExecStop=/usr/local/bin/swss.sh stop -Restart=always -RestartSec=30 - -[Install] -WantedBy=multi-user.target diff --git a/files/build_templates/single_instance/syncd.service.j2 b/files/build_templates/single_instance/syncd.service.j2 deleted file mode 100644 index 7a7d27114b07..000000000000 --- a/files/build_templates/single_instance/syncd.service.j2 +++ /dev/null @@ -1,30 +0,0 @@ -[Unit] -Description=syncd service -Requires=database.service updategraph.service -{% if sonic_asic_platform == 'broadcom' %} -Requires=opennsl-modules.service -{% elif sonic_asic_platform == 'nephos' %} -Requires=nps-modules-4.9.0-11-2-amd64.service -{% endif %} -After=database.service updategraph.service -After=interfaces-config.service -{% if sonic_asic_platform == 'broadcom' %} -After=opennsl-modules.service -{% elif sonic_asic_platform == 'nephos' %} -After=nps-modules-4.9.0-11-2-amd64.service -{% endif %} -After=swss.service -Before=ntp-config.service - -[Service] -User=root -Environment=sonic_asic_platform={{ sonic_asic_platform }} -ExecStartPre=/usr/local/bin/syncd.sh start -ExecStart=/usr/local/bin/syncd.sh wait -ExecStop=/usr/local/bin/syncd.sh stop -{% if sonic_asic_platform == 'mellanox' %} -TimeoutStartSec=150 -{% endif %} - -[Install] -WantedBy=multi-user.target diff --git a/files/build_templates/single_instance/teamd.service.j2 b/files/build_templates/single_instance/teamd.service.j2 deleted file mode 100644 index be0521a4fbec..000000000000 --- a/files/build_templates/single_instance/teamd.service.j2 +++ /dev/null @@ -1,18 +0,0 @@ -[Unit] -Description=TEAMD container -Requires=updategraph.service -After=updategraph.service swss.service -Before=ntp-config.service -StartLimitIntervalSec=1200 -StartLimitBurst=3 - -[Service] -User={{ sonicadmin_user }} -ExecStartPre=/usr/bin/{{docker_container_name}}.sh start -ExecStart=/usr/bin/{{docker_container_name}}.sh wait -ExecStop=/usr/bin/{{docker_container_name}}.sh stop -Restart=always -RestartSec=30 - -[Install] -WantedBy=multi-user.target diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 66391c7bac8d..abc5361910be 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -284,6 +284,7 @@ j2 files/build_templates/init_cfg.json.j2 | sudo tee $FILESYSTEM_ROOT/etc/sonic/ # Copy config-setup script and service file j2 files/build_templates/config-setup.service.j2 | sudo tee $FILESYSTEM_ROOT/etc/systemd/system/config-setup.service sudo cp $IMAGE_CONFIGS/config-setup/config-setup $FILESYSTEM_ROOT/usr/bin/config-setup +echo "config-setup.service" | sudo tee -a $GENERATED_SERVICE_FILE sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable config-setup.service # Copy SNMP configuration files @@ -430,6 +431,9 @@ sudo LANG=C chroot $FILESYSTEM_ROOT umount -lf /sys sudo LANG=C cp $SCRIPTS_DIR/swss.sh $FILESYSTEM_ROOT/usr/local/bin/swss.sh sudo LANG=C cp $SCRIPTS_DIR/syncd.sh $FILESYSTEM_ROOT/usr/local/bin/syncd.sh +# Copy sonic-netns-exec script +sudo LANG=C cp $SCRIPTS_DIR/sonic-netns-exec $FILESYSTEM_ROOT/usr/bin/sonic-netns-exec + # Copy systemd timer configuration # It implements delayed start of services sudo cp $BUILD_TEMPLATES/snmp.timer $FILESYSTEM_ROOT/etc/systemd/system/ diff --git a/files/image_config/topology/topology.sh b/files/image_config/topology/topology.sh index 7013920ec016..dde7da247484 100755 --- a/files/image_config/topology/topology.sh +++ b/files/image_config/topology/topology.sh @@ -6,18 +6,16 @@ # start() { - DB_FIRST_INSTANCE="/var/run/redis0/redis.sock" - TOPOLOGY_SCRIPT="topology.sh" - PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform -s $DB_FIRST_INSTANCE` - HWSKU=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hwsku"]' -s $DB_FIRST_INSTANCE` - /usr/share/sonic/device/$PLATFORM/$HWSKU/$TOPOLOGY_SCRIPT start + TOPOLOGY_SCRIPT="topology.sh" + PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` + HWSKU=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hwsku"]'` + /usr/share/sonic/device/$PLATFORM/$HWSKU/$TOPOLOGY_SCRIPT start } stop() { - DB_FIRST_INSTANCE="/var/run/redis0/redis.sock" - TOPOLOGY_SCRIPT="topology.sh" - PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform -s $DB_FIRST_INSTANCE` - HWSKU=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hwsku"]' -s $DB_FIRST_INSTANCE` - /usr/share/sonic/device/$PLATFORM/$HWSKU/$TOPOLOGY_SCRIPT stop + TOPOLOGY_SCRIPT="topology.sh" + PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` + HWSKU=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hwsku"]'` + usr/share/sonic/device/$PLATFORM/$HWSKU/$TOPOLOGY_SCRIPT stop } case "$1" in diff --git a/files/scripts/sonic-netns-exec b/files/scripts/sonic-netns-exec new file mode 100755 index 000000000000..166a2c7e4a2f --- /dev/null +++ b/files/scripts/sonic-netns-exec @@ -0,0 +1,12 @@ +#!/bin/bash +# Wrapper to execute any command in a specific +# network namespace. +# Usage: +# sonic-netns-exec +NS="$1" +shift +if [ "$NS" != "" ]; then + ip netns exec $NS $@ +else + $@ +fi diff --git a/files/scripts/swss.sh b/files/scripts/swss.sh index a14d03e40f50..360e331f3636 100755 --- a/files/scripts/swss.sh +++ b/files/scripts/swss.sh @@ -1,10 +1,7 @@ #!/bin/bash -SERVICE="swss" -PEER="syncd" -DEPENDENT="teamd radv dhcp_relay" -DEBUGLOG="/tmp/swss-syncd-debug.log" -LOCKFILE="/tmp/swss-syncd-lock" +DEPENDENT="radv dhcp_relay" +MULTI_INST_DEPENDENT="teamd" function debug() { @@ -14,25 +11,25 @@ function debug() function lock_service_state_change() { - debug "Locking ${LOCKFILE} from ${SERVICE} service" + debug "Locking ${LOCKFILE} from ${SERVICE}$DEV service" exec {LOCKFD}>${LOCKFILE} /usr/bin/flock -x ${LOCKFD} trap "/usr/bin/flock -u ${LOCKFD}" 0 2 3 15 - debug "Locked ${LOCKFILE} (${LOCKFD}) from ${SERVICE} service" + debug "Locked ${LOCKFILE} (${LOCKFD}) from ${SERVICE}$DEV service" } function unlock_service_state_change() { - debug "Unlocking ${LOCKFILE} (${LOCKFD}) from ${SERVICE} service" + debug "Unlocking ${LOCKFILE} (${LOCKFD}) from ${SERVICE}$DEV service" /usr/bin/flock -u ${LOCKFD} } function check_warm_boot() { - SYSTEM_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` - SERVICE_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` + SYSTEM_WARM_START=`sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` + SERVICE_WARM_START=`sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` if [[ x"$SYSTEM_WARM_START" == x"true" ]] || [[ x"$SERVICE_WARM_START" == x"true" ]]; then WARM_BOOT="true" else @@ -43,7 +40,7 @@ function check_warm_boot() function validate_restore_count() { if [[ x"$WARM_BOOT" == x"true" ]]; then - RESTORE_COUNT=`sonic-db-cli STATE_DB hget "WARM_RESTART_TABLE|orchagent" restore_count` + RESTORE_COUNT=`sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB hget "WARM_RESTART_TABLE|orchagent" restore_count` # We have to make sure db data has not been flushed. if [[ -z "$RESTORE_COUNT" ]]; then WARM_BOOT="false" @@ -54,10 +51,10 @@ function validate_restore_count() function wait_for_database_service() { # Wait for redis server start before database clean - /usr/bin/docker exec database ping_pong_db_insts + /usr/bin/docker exec database$DEV ping_pong_db_insts # Wait for configDB initialization - until [[ $(sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; + until [[ $(sonic-netns-exec "$NET_NS" sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; do sleep 1; done } @@ -67,7 +64,7 @@ function wait_for_database_service() # $2 the string of a list of table prefixes function clean_up_tables() { - sonic-db-cli $1 EVAL " + sonic-netns-exec "$NET_NS" sonic-db-cli $1 EVAL " local tables = {$2} for i = 1, table.getn(tables) do local matches = redis.call('KEYS', tables[i]) @@ -81,25 +78,48 @@ start_peer_and_dependent_services() { check_warm_boot if [[ x"$WARM_BOOT" != x"true" ]]; then - /bin/systemctl start ${PEER} + if [[ ! -z $DEV ]]; then + /bin/systemctl start ${PEER}@$DEV + else + /bin/systemctl start ${PEER} + fi for dep in ${DEPENDENT}; do /bin/systemctl start ${dep} done + for dep in ${MULTI_INST_DEPENDENT}; do + if [[ ! -z $DEV ]]; then + /bin/systemctl start ${dep}@$DEV + else + /bin/systemctl start ${dep} + fi + done fi } stop_peer_and_dependent_services() { # if warm start enabled or peer lock exists, don't stop peer service docker if [[ x"$WARM_BOOT" != x"true" ]]; then - /bin/systemctl stop ${PEER} + if [[ ! -z $DEV ]]; then + /bin/systemctl stop ${PEER}@$DEV + else + /bin/systemctl stop ${PEER} + fi for dep in ${DEPENDENT}; do /bin/systemctl stop ${dep} done + for dep in ${MULTI_INST_DEPENDENT}; do + if [[ ! -z $DEV ]]; then + /bin/systemctl stop ${dep}@$DEV + else + /bin/systemctl stop ${dep} + fi + done + fi } start() { - debug "Starting ${SERVICE} service..." + debug "Starting ${SERVICE}$DEV service..." lock_service_state_change @@ -107,21 +127,21 @@ start() { check_warm_boot validate_restore_count - debug "Warm boot flag: ${SERVICE} ${WARM_BOOT}." + debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}." # Don't flush DB during warm boot if [[ x"$WARM_BOOT" != x"true" ]]; then debug "Flushing APP, ASIC, COUNTER, CONFIG, and partial STATE databases ..." - sonic-db-cli APPL_DB FLUSHDB - sonic-db-cli ASIC_DB FLUSHDB - sonic-db-cli COUNTERS_DB FLUSHDB - sonic-db-cli FLEX_COUNTER_DB FLUSHDB + sonic-netns-exec "$NET_NS" sonic-db-cli APPL_DB FLUSHDB + sonic-netns-exec "$NET_NS" sonic-db-cli ASIC_DB FLUSHDB + sonic-netns-exec "$NET_NS" sonic-db-cli COUNTERS_DB FLUSHDB + sonic-netns-exec "$NET_NS" sonic-db-cli FLEX_COUNTER_DB FLUSHDB clean_up_tables STATE_DB "'PORT_TABLE*', 'MGMT_PORT_TABLE*', 'VLAN_TABLE*', 'VLAN_MEMBER_TABLE*', 'LAG_TABLE*', 'LAG_MEMBER_TABLE*', 'INTERFACE_TABLE*', 'MIRROR_SESSION*', 'VRF_TABLE*', 'FDB_TABLE*'" fi # start service docker - /usr/bin/${SERVICE}.sh start - debug "Started ${SERVICE} service..." + /usr/bin/${SERVICE}.sh start $DEV + debug "Started ${SERVICE}$DEV service..." # Unlock has to happen before reaching out to peer service unlock_service_state_change @@ -134,7 +154,11 @@ wait() { # NOTE: This assumes Docker containers share the same names as their # corresponding services for SECS in {1..60}; do - RUNNING=$(docker inspect -f '{{.State.Running}}' ${PEER}) + if [[ ! -z $DEV ]]; then + RUNNING=$(docker inspect -f '{{.State.Running}}' ${PEER}$DEV) + else + RUNNING=$(docker inspect -f '{{.State.Running}}' ${PEER}) + fi if [[ x"$RUNNING" == x"true" ]]; then break else @@ -144,20 +168,24 @@ wait() { # NOTE: This assumes Docker containers share the same names as their # corresponding services - /usr/bin/docker-wait-any ${SERVICE} ${PEER} + if [[ ! -z $DEV ]]; then + /usr/bin/docker-wait-any ${SERVICE}$DEV ${PEER}$DEV + else + /usr/bin/docker-wait-any ${SERVICE} ${PEER} + fi } stop() { - debug "Stopping ${SERVICE} service..." + debug "Stopping ${SERVICE}$DEV service..." [[ -f ${LOCKFILE} ]] || /usr/bin/touch ${LOCKFILE} lock_service_state_change check_warm_boot - debug "Warm boot flag: ${SERVICE} ${WARM_BOOT}." + debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}." - /usr/bin/${SERVICE}.sh stop - debug "Stopped ${SERVICE} service..." + /usr/bin/${SERVICE}.sh stop $DEV + debug "Stopped ${SERVICE}$DEV service..." # Flush FAST_REBOOT table when swss needs to stop. The only # time when this would take effect is when fast-reboot @@ -172,6 +200,18 @@ stop() { stop_peer_and_dependent_services } +DEV=$2 + +SERVICE="swss" +PEER="syncd" +DEBUGLOG="/tmp/swss-syncd-debug$DEV.log" +LOCKFILE="/tmp/swss-syncd-lock$DEV" +if [ "$DEV" ]; then + NET_NS="asic$DEV" #name of the network namespace +else + NET_NS="" +fi + case "$1" in start|wait|stop) $1 diff --git a/files/scripts/syncd.sh b/files/scripts/syncd.sh index 4b47e7ad4c45..9847cfec9406 100755 --- a/files/scripts/syncd.sh +++ b/files/scripts/syncd.sh @@ -1,9 +1,5 @@ #!/bin/bash -SERVICE="syncd" -PEER="swss" -DEBUGLOG="/tmp/swss-syncd-debug.log" -LOCKFILE="/tmp/swss-syncd-lock" function debug() { @@ -13,25 +9,25 @@ function debug() function lock_service_state_change() { - debug "Locking ${LOCKFILE} from ${SERVICE} service" + debug "Locking ${LOCKFILE} from ${SERVICE}$DEV service" exec {LOCKFD}>${LOCKFILE} /usr/bin/flock -x ${LOCKFD} trap "/usr/bin/flock -u ${LOCKFD}" 0 2 3 15 - debug "Locked ${LOCKFILE} (${LOCKFD}) from ${SERVICE} service" + debug "Locked ${LOCKFILE} (${LOCKFD}) from ${SERVICE}$DEV service" } function unlock_service_state_change() { - debug "Unlocking ${LOCKFILE} (${LOCKFD}) from ${SERVICE} service" + debug "Unlocking ${LOCKFILE} (${LOCKFD}) from ${SERVICE}$DEV service" /usr/bin/flock -u ${LOCKFD} } function check_warm_boot() { - SYSTEM_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` - SERVICE_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` + SYSTEM_WARM_START=`sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` + SERVICE_WARM_START=`sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` # SYSTEM_WARM_START could be empty, always make WARM_BOOT meaningful. if [[ x"$SYSTEM_WARM_START" == x"true" ]] || [[ x"$SERVICE_WARM_START" == x"true" ]]; then WARM_BOOT="true" @@ -43,10 +39,10 @@ function check_warm_boot() function wait_for_database_service() { # Wait for redis server start before database clean - /usr/bin/docker exec database ping_pong_db_insts + /usr/bin/docker exec database$DEV ping_pong_db_insts # Wait for configDB initialization - until [[ $(sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; + until [[ $(sonic-netns-exec "$NET_NS" sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; do sleep 1; done } @@ -63,7 +59,7 @@ function getBootType() ;; *SONIC_BOOT_TYPE=fast*|*fast-reboot*) # check that the key exists - if [[ $(sonic-db-cli STATE_DB GET "FAST_REBOOT|system") == "1" ]]; then + if [[ $(sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB GET "FAST_REBOOT|system") == "1" ]]; then TYPE='fast' else TYPE='cold' @@ -76,7 +72,7 @@ function getBootType() } start() { - debug "Starting ${SERVICE} service..." + debug "Starting ${SERVICE}$DEV service..." lock_service_state_change @@ -85,7 +81,7 @@ start() { wait_for_database_service check_warm_boot - debug "Warm boot flag: ${SERVICE} ${WARM_BOOT}." + debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}." if [[ x"$WARM_BOOT" == x"true" ]]; then # Leave a mark for syncd scripts running inside docker. @@ -127,7 +123,7 @@ start() { fi # start service docker - /usr/bin/${SERVICE}.sh start + /usr/bin/${SERVICE}.sh start $DEV debug "Started ${SERVICE} service..." unlock_service_state_change @@ -139,15 +135,15 @@ wait() { /bin/systemctl start pmon debug "Started pmon service" fi - /usr/bin/${SERVICE}.sh wait + /usr/bin/${SERVICE}.sh wait $DEV } stop() { - debug "Stopping ${SERVICE} service..." + debug "Stopping ${SERVICE}$DEV service..." lock_service_state_change check_warm_boot - debug "Warm boot flag: ${SERVICE} ${WARM_BOOT}." + debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}." if [[ x"$WARM_BOOT" == x"true" ]]; then TYPE=warm @@ -163,19 +159,19 @@ stop() { if [[ x$sonic_asic_platform != x"mellanox" ]] || [[ x$TYPE != x"cold" ]]; then debug "${TYPE} shutdown syncd process ..." - /usr/bin/docker exec -i syncd /usr/bin/syncd_request_shutdown --${TYPE} + /usr/bin/docker exec -i syncd$DEV /usr/bin/syncd_request_shutdown --${TYPE} # wait until syncd quits gracefully - while docker top syncd | grep -q /usr/bin/syncd; do + while docker top syncd$DEV | grep -q /usr/bin/syncd; do sleep 0.1 done - /usr/bin/docker exec -i syncd /bin/sync + /usr/bin/docker exec -i syncd$DEV /bin/sync debug "Finished ${TYPE} shutdown syncd process ..." fi - /usr/bin/${SERVICE}.sh stop - debug "Stopped ${SERVICE} service..." + /usr/bin/${SERVICE}.sh stop $DEV + debug "Stopped ${SERVICE}$DEV service..." # platform specific tasks @@ -192,6 +188,19 @@ stop() { unlock_service_state_change } +OP=$1 +DEV=$2 + +SERVICE="syncd" +PEER="swss" +DEBUGLOG="/tmp/swss-syncd-debug$DEV.log" +LOCKFILE="/tmp/swss-syncd-lock$DEV" +if [ "$DEV" ]; then + NET_NS="asic$DEV" #name of the network namespace +else + NET_NS="" +fi + case "$1" in start|wait|stop) $1 diff --git a/platform/vs/sonic_multiasic.xml b/platform/vs/sonic_multiasic.xml index b406bfd40475..b571b5122a52 100644 --- a/platform/vs/sonic_multiasic.xml +++ b/platform/vs/sonic_multiasic.xml @@ -1,7 +1,7 @@ sonic 8 - 2 + 8 /machine diff --git a/rules/docker-fpm-frr.mk b/rules/docker-fpm-frr.mk index 517aff3ea9fc..45a755a9289f 100644 --- a/rules/docker-fpm-frr.mk +++ b/rules/docker-fpm-frr.mk @@ -24,7 +24,6 @@ SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_FPM_FRR_DBG) $(DOCKER_FPM_FRR)_CONTAINER_NAME = bgp $(DOCKER_FPM_FRR)_RUN_OPT += --privileged -t $(DOCKER_FPM_FRR)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro -$(DOCKER_FPM_FRR)_RUN_OPT += -v /etc/sonic/frr:/etc/frr:rw $(DOCKER_FPM_FRR)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/slave.mk b/slave.mk index 16c4d4ef6a8b..9a154699cc20 100644 --- a/slave.mk +++ b/slave.mk @@ -667,6 +667,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export platform_common_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_COMMON_PY2))" export redis_dump_load_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(REDIS_DUMP_LOAD_PY2))" export install_debug_image="$(INSTALL_DEBUG_TOOLS)" + export multi_instance="false" $(foreach docker, $($*_DOCKERS),\ export docker_image="$(docker)" @@ -677,18 +678,21 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ if [ -f files/build_templates/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 ]; then j2 files/build_templates/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service - fi - - if [ -f files/build_templates/multi_instance/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME)@.service.j2 ]; then - j2 files/build_templates/multi_instance/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME)@.service.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME)@.service - # performs the same check as the elif above, except with make commands so eval behaves properly - $(if $(shell ls files/build_templates/multi_instance/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME)@.service.j2 2>/dev/null),\ - $(eval $(docker:-dbg.gz=.gz)_TEMPLATE = yes) - ) + # Set the flag GLOBAL for all the global system-wide dockers. + $(if $(shell ls files/build_templates/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 2>/dev/null),\ + $(eval $(docker:-dbg.gz=.gz)_GLOBAL = yes) + ) fi - if [ -f files/build_templates/single_instance/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 ]; then - j2 files/build_templates/single_instance/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service + # Any service template, inside instance directory, will be used to generate .service and @.service file. + if [ -f files/build_templates/per_namespace/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 ]; then + export multi_instance="true" + j2 files/build_templates/per_namespace/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME)@.service + $(if $(shell ls files/build_templates/per_namespace/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 2>/dev/null),\ + $(eval $(docker:-dbg.gz=.gz)_TEMPLATE = yes) + ) + export multi_instance="false" + j2 files/build_templates/per_namespace/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service fi j2 files/build_templates/docker_image_ctl.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).sh chmod +x $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).sh @@ -699,8 +703,12 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ # Marks template services with an "@" according to systemd convention # If the $($docker)_TEMPLATE) variable is set, the service will be treated as a template + # If the $($docker)_GLOBAL) and $($docker)_TEMPLATE) variables are set the service will be added both as a global and template service. $(foreach docker, $($*_DOCKERS),\ $(if $($(docker:-dbg.gz=.gz)_TEMPLATE),\ + $(if $($(docker:-dbg.gz=.gz)_GLOBAL),\ + $(eval SERVICES += "$(addsuffix .service, $($(docker:-dbg.gz=.gz)_CONTAINER_NAME))")\ + )\ $(eval SERVICES += "$(addsuffix @.service, $($(docker:-dbg.gz=.gz)_CONTAINER_NAME))"),\ $(eval SERVICES += "$(addsuffix .service, $($(docker:-dbg.gz=.gz)_CONTAINER_NAME))") ) From 88193222103f4c9aea43bdb3e56e73e5afc978aa Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Wed, 1 Apr 2020 23:26:42 -0700 Subject: [PATCH 139/178] [Arista] Update drivers submodules (#4353) * Update arista drivers submodules * Add device configs for 7060CX2-32S * Update boot0 and union-mount for 7060CX2-32S * Add 7170-32C and 7170-32CD support in boot0 * Sync after writting boot configs * Add 7170-32C and 7170-32CD device configurations Co-authored-by: Boyang Yu Co-authored-by: Boyang Yu --- .../Arista-7060CX2-32S-C32 | 1 + .../x86_64-arista_7060cx2_32s/default_sku | 1 + .../x86_64-arista_7060cx2_32s/fancontrol | 1 + .../x86_64-arista_7060cx2_32s/platform_reboot | 1 + .../arista/x86_64-arista_7060cx2_32s/plugins | 1 + .../x86_64-arista_7060cx2_32s/sensors.conf | 1 + .../Arista-7170-32C-C32/board_lane_map.json | 1734 +++++++++++++++++ .../Arista-7170-32C-C32/port_config.ini | 33 + .../Arista-7170-32C-C32/switch-sai.conf | 33 + .../Arista-7170-32C-C32/switch-tna-sai.conf | 39 + .../arista/x86_64-arista_7170_32c/default_sku | 1 + .../x86_64-arista_7170_32c/platform_reboot | 1 + device/arista/x86_64-arista_7170_32c/plugins | 1 + .../x86_64-arista_7170_32c/sensors.conf | 1 + .../Arista-7170-32CD-C32/board_lane_map.json | 1734 +++++++++++++++++ .../Arista-7170-32CD-C32/port_config.ini | 33 + .../Arista-7170-32CD-C32/switch-sai.conf | 33 + .../Arista-7170-32CD-C32/switch-tna-sai.conf | 39 + .../x86_64-arista_7170_32cd/default_sku | 1 + .../x86_64-arista_7170_32cd/platform_reboot | 1 + device/arista/x86_64-arista_7170_32cd/plugins | 1 + .../x86_64-arista_7170_32cd/sensors.conf | 1 + files/Aboot/boot0.j2 | 83 +- files/initramfs-tools/union-mount.j2 | 1 + .../barefoot/sonic-platform-modules-arista | 2 +- .../broadcom/sonic-platform-modules-arista | 2 +- 26 files changed, 3752 insertions(+), 28 deletions(-) create mode 120000 device/arista/x86_64-arista_7060cx2_32s/Arista-7060CX2-32S-C32 create mode 100644 device/arista/x86_64-arista_7060cx2_32s/default_sku create mode 120000 device/arista/x86_64-arista_7060cx2_32s/fancontrol create mode 120000 device/arista/x86_64-arista_7060cx2_32s/platform_reboot create mode 120000 device/arista/x86_64-arista_7060cx2_32s/plugins create mode 120000 device/arista/x86_64-arista_7060cx2_32s/sensors.conf create mode 100644 device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/board_lane_map.json create mode 100644 device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/port_config.ini create mode 100644 device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/switch-sai.conf create mode 100644 device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/switch-tna-sai.conf create mode 100644 device/arista/x86_64-arista_7170_32c/default_sku create mode 120000 device/arista/x86_64-arista_7170_32c/platform_reboot create mode 120000 device/arista/x86_64-arista_7170_32c/plugins create mode 120000 device/arista/x86_64-arista_7170_32c/sensors.conf create mode 100644 device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/board_lane_map.json create mode 100644 device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/port_config.ini create mode 100644 device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/switch-sai.conf create mode 100644 device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/switch-tna-sai.conf create mode 100644 device/arista/x86_64-arista_7170_32cd/default_sku create mode 120000 device/arista/x86_64-arista_7170_32cd/platform_reboot create mode 120000 device/arista/x86_64-arista_7170_32cd/plugins create mode 120000 device/arista/x86_64-arista_7170_32cd/sensors.conf diff --git a/device/arista/x86_64-arista_7060cx2_32s/Arista-7060CX2-32S-C32 b/device/arista/x86_64-arista_7060cx2_32s/Arista-7060CX2-32S-C32 new file mode 120000 index 000000000000..3ba3c5721b19 --- /dev/null +++ b/device/arista/x86_64-arista_7060cx2_32s/Arista-7060CX2-32S-C32 @@ -0,0 +1 @@ +../x86_64-arista_7060_cx32s/Arista-7060CX-32S-C32 \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060cx2_32s/default_sku b/device/arista/x86_64-arista_7060cx2_32s/default_sku new file mode 100644 index 000000000000..fb5071866c25 --- /dev/null +++ b/device/arista/x86_64-arista_7060cx2_32s/default_sku @@ -0,0 +1 @@ +Arista-7060CX2-32S-C32 t1 diff --git a/device/arista/x86_64-arista_7060cx2_32s/fancontrol b/device/arista/x86_64-arista_7060cx2_32s/fancontrol new file mode 120000 index 000000000000..c37f83f5ffb5 --- /dev/null +++ b/device/arista/x86_64-arista_7060cx2_32s/fancontrol @@ -0,0 +1 @@ +../x86_64-arista_7060_cx32s/fancontrol \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060cx2_32s/platform_reboot b/device/arista/x86_64-arista_7060cx2_32s/platform_reboot new file mode 120000 index 000000000000..7f94a49e38b0 --- /dev/null +++ b/device/arista/x86_64-arista_7060cx2_32s/platform_reboot @@ -0,0 +1 @@ +../x86_64-arista_common/platform_reboot \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060cx2_32s/plugins b/device/arista/x86_64-arista_7060cx2_32s/plugins new file mode 120000 index 000000000000..5fbbf98a6284 --- /dev/null +++ b/device/arista/x86_64-arista_7060cx2_32s/plugins @@ -0,0 +1 @@ +../x86_64-arista_common/plugins/ \ No newline at end of file diff --git a/device/arista/x86_64-arista_7060cx2_32s/sensors.conf b/device/arista/x86_64-arista_7060cx2_32s/sensors.conf new file mode 120000 index 000000000000..10be0183e3a7 --- /dev/null +++ b/device/arista/x86_64-arista_7060cx2_32s/sensors.conf @@ -0,0 +1 @@ +../x86_64-arista_7060_cx32s/sensors.conf \ No newline at end of file diff --git a/device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/board_lane_map.json b/device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/board_lane_map.json new file mode 100644 index 000000000000..6ab72e55ab47 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/board_lane_map.json @@ -0,0 +1,1734 @@ +{ + "board_name": "7170-32C", + "enable_debug_log": 0, + "board_lane_map_entry": [ + { + "connector": 1, + "device_id": 0, + "mac_block": 14, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 2, + "device_id": 0, + "mac_block": 12, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 3, + "device_id": 0, + "mac_block": 10, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 4, + "device_id": 0, + "mac_block": 8, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 5, + "device_id": 0, + "mac_block": 6, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 6, + "device_id": 0, + "mac_block": 4, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 7, + "device_id": 0, + "mac_block": 2, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 8, + "device_id": 0, + "mac_block": 0, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 9, + "device_id": 0, + "mac_block": 62, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 10, + "device_id": 0, + "mac_block": 60, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 11, + "device_id": 0, + "mac_block": 58, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 12, + "device_id": 0, + "mac_block": 56, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 13, + "device_id": 0, + "mac_block": 54, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 14, + "device_id": 0, + "mac_block": 52, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 15, + "device_id": 0, + "mac_block": 50, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 16, + "device_id": 0, + "mac_block": 48, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 17, + "device_id": 0, + "mac_block": 46, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 18, + "device_id": 0, + "mac_block": 44, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 19, + "device_id": 0, + "mac_block": 42, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 20, + "device_id": 0, + "mac_block": 40, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 21, + "device_id": 0, + "mac_block": 38, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 22, + "device_id": 0, + "mac_block": 36, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 23, + "device_id": 0, + "mac_block": 34, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 24, + "device_id": 0, + "mac_block": 32, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 25, + "device_id": 0, + "mac_block": 30, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 26, + "device_id": 0, + "mac_block": 28, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 27, + "device_id": 0, + "mac_block": 26, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 28, + "device_id": 0, + "mac_block": 24, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 29, + "device_id": 0, + "mac_block": 22, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 30, + "device_id": 0, + "mac_block": 20, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 31, + "device_id": 0, + "mac_block": 18, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 32, + "device_id": 0, + "mac_block": 16, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + } + ] +} diff --git a/device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/port_config.ini b/device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/port_config.ini new file mode 100644 index 000000000000..d983617f1891 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias speed index +Ethernet0 0,1,2,3 Ethernet1/1 100000 1 +Ethernet4 4,5,6,7 Ethernet2/1 100000 2 +Ethernet8 8,9,10,11 Ethernet3/1 100000 3 +Ethernet12 12,13,14,15 Ethernet4/1 100000 4 +Ethernet16 16,17,18,19 Ethernet5/1 100000 5 +Ethernet20 20,21,22,23 Ethernet6/1 100000 6 +Ethernet24 24,25,26,27 Ethernet7/1 100000 7 +Ethernet28 28,29,30,31 Ethernet8/1 100000 8 +Ethernet32 32,33,34,35 Ethernet9/1 100000 9 +Ethernet36 36,37,38,39 Ethernet10/1 100000 10 +Ethernet40 40,41,42,43 Ethernet11/1 100000 11 +Ethernet44 44,45,46,47 Ethernet12/1 100000 12 +Ethernet48 48,49,50,51 Ethernet13/1 100000 13 +Ethernet52 52,53,54,55 Ethernet14/1 100000 14 +Ethernet56 56,57,58,59 Ethernet15/1 100000 15 +Ethernet60 60,61,62,63 Ethernet16/1 100000 16 +Ethernet64 64,65,66,67 Ethernet17/1 100000 17 +Ethernet68 68,69,70,71 Ethernet18/1 100000 18 +Ethernet72 72,73,74,75 Ethernet19/1 100000 19 +Ethernet76 76,77,78,79 Ethernet20/1 100000 20 +Ethernet80 80,81,82,83 Ethernet21/1 100000 21 +Ethernet84 84,85,86,87 Ethernet22/1 100000 22 +Ethernet88 88,89,90,91 Ethernet23/1 100000 23 +Ethernet92 92,93,94,95 Ethernet24/1 100000 24 +Ethernet96 96,97,98,99 Ethernet25/1 100000 25 +Ethernet100 100,101,102,103 Ethernet26/1 100000 26 +Ethernet104 104,105,106,107 Ethernet27/1 100000 27 +Ethernet108 108,109,110,111 Ethernet28/1 100000 28 +Ethernet112 112,113,114,115 Ethernet29/1 100000 29 +Ethernet116 116,117,118,119 Ethernet30/1 100000 30 +Ethernet120 120,121,122,123 Ethernet31/1 100000 31 +Ethernet124 124,125,126,127 Ethernet32/1 100000 32 diff --git a/device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/switch-sai.conf b/device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/switch-sai.conf new file mode 100644 index 000000000000..0a807b1c9ea7 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/switch-sai.conf @@ -0,0 +1,33 @@ +{ + "chip_list": [ + { + "id": "asic-0", + "chip_family": "Tofino", + "instance": 0, + "pcie_sysfs_prefix": "/sys/devices/pci0000:00/0000:00:1c.4/0000:07:00.0", + "pcie_domain": 0, + "pcie_bus": 7, + "pcie_fn": 0, + "pcie_dev": 0, + "pcie_int_mode": 1, + "sds_fw_path": "share/tofino_sds_fw/avago/firmware" + } + ], + "instance": 0, + "p4_program_list": [ + { + "id": "pgm-0", + "instance": 0, + "path": "switch", + "program-name": "switch", + "pd": "lib/tofinopd/switch/libpd.so", + "pd-thrift": "lib/tofinopd/switch/libpdthrift.so", + "table-config": "share/tofinopd/switch/context.json", + "tofino-bin": "share/tofinopd/switch/tofino.bin", + "switchapi": "lib/libswitchapi.so", + "sai": "lib/libsai.so", + "switchapi_port_add": false, + "non_default_port_ppgs": 5 + } + ] +} diff --git a/device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/switch-tna-sai.conf b/device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/switch-tna-sai.conf new file mode 100644 index 000000000000..ece3fcbe6a90 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/switch-tna-sai.conf @@ -0,0 +1,39 @@ +{ + "instance": 0, + "chip_list": [ + { + "id": "asic-0", + "chip_family": "Tofino", + "instance": 0, + "pcie_sysfs_prefix": "/sys/devices/pci0000:00/0000:00:03.0/0000:05:00.0", + "pcie_domain": 0, + "pcie_bus": 5, + "pcie_fn": 0, + "pcie_dev": 0, + "pcie_int_mode": 1, + "sds_fw_path": "share/tofino_sds_fw/avago/firmware" + } + ], + "p4_devices": [ + { + "device-id": 0, + "p4_programs": [ + { + "p4_pipelines": [ + { + "p4_pipeline_name": "pipe", + "config": "share/switch/pipe/tofino.bin", + "context": "share/switch/pipe/context.json" + } + ], + "program-name": "switch", + "sai": "lib/libsai.so", + "bfrt-config": "share/switch/bf-rt.json", + "model_json_path" : "share/switch/aug_model.json", + "switchapi_port_add": false, + "non_default_port_ppgs": 5 + } + ] + } + ] +} diff --git a/device/arista/x86_64-arista_7170_32c/default_sku b/device/arista/x86_64-arista_7170_32c/default_sku new file mode 100644 index 000000000000..536bad44f086 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32c/default_sku @@ -0,0 +1 @@ +Arista-7170-32CD-C32 t1 diff --git a/device/arista/x86_64-arista_7170_32c/platform_reboot b/device/arista/x86_64-arista_7170_32c/platform_reboot new file mode 120000 index 000000000000..7f94a49e38b0 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32c/platform_reboot @@ -0,0 +1 @@ +../x86_64-arista_common/platform_reboot \ No newline at end of file diff --git a/device/arista/x86_64-arista_7170_32c/plugins b/device/arista/x86_64-arista_7170_32c/plugins new file mode 120000 index 000000000000..789a45fcace9 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32c/plugins @@ -0,0 +1 @@ +../x86_64-arista_common/plugins \ No newline at end of file diff --git a/device/arista/x86_64-arista_7170_32c/sensors.conf b/device/arista/x86_64-arista_7170_32c/sensors.conf new file mode 120000 index 000000000000..1ab9e0f47704 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32c/sensors.conf @@ -0,0 +1 @@ +../x86_64-arista_7170_64c/sensors.conf \ No newline at end of file diff --git a/device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/board_lane_map.json b/device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/board_lane_map.json new file mode 100644 index 000000000000..58a78c5fc4c9 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/board_lane_map.json @@ -0,0 +1,1734 @@ +{ + "board_name": "7170-32CD", + "enable_debug_log": 0, + "board_lane_map_entry": [ + { + "connector": 1, + "device_id": 0, + "mac_block": 7, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 2, + "device_id": 0, + "mac_block": 6, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 3, + "device_id": 0, + "mac_block": 5, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 4, + "device_id": 0, + "mac_block": 4, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 5, + "device_id": 0, + "mac_block": 3, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 6, + "device_id": 0, + "mac_block": 2, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 7, + "device_id": 0, + "mac_block": 1, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 8, + "device_id": 0, + "mac_block": 0, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 9, + "device_id": 0, + "mac_block": 31, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 10, + "device_id": 0, + "mac_block": 30, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 11, + "device_id": 0, + "mac_block": 29, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 12, + "device_id": 0, + "mac_block": 28, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 13, + "device_id": 0, + "mac_block": 27, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 14, + "device_id": 0, + "mac_block": 26, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 15, + "device_id": 0, + "mac_block": 25, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 16, + "device_id": 0, + "mac_block": 24, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 17, + "device_id": 0, + "mac_block": 23, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 18, + "device_id": 0, + "mac_block": 22, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 19, + "device_id": 0, + "mac_block": 21, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 20, + "device_id": 0, + "mac_block": 20, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 21, + "device_id": 0, + "mac_block": 19, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 22, + "device_id": 0, + "mac_block": 18, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 23, + "device_id": 0, + "mac_block": 17, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 24, + "device_id": 0, + "mac_block": 16, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 25, + "device_id": 0, + "mac_block": 15, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 26, + "device_id": 0, + "mac_block": 14, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 27, + "device_id": 0, + "mac_block": 13, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 28, + "device_id": 0, + "mac_block": 12, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 29, + "device_id": 0, + "mac_block": 11, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 30, + "device_id": 0, + "mac_block": 10, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 31, + "device_id": 0, + "mac_block": 9, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 1, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 1, + "rx_lane": 1, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 0, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 0, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + }, + { + "connector": 32, + "device_id": 0, + "mac_block": 8, + "media_type": "copper", + "lane0": { + "mac_ch": 0, + "tx_lane": 0, + "tx_pn_swap": 0, + "rx_lane": 0, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane1": { + "mac_ch": 1, + "tx_lane": 1, + "tx_pn_swap": 0, + "rx_lane": 1, + "rx_pn_swap": 0, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane2": { + "mac_ch": 2, + "tx_lane": 2, + "tx_pn_swap": 1, + "rx_lane": 2, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + }, + "lane3": { + "mac_ch": 3, + "tx_lane": 3, + "tx_pn_swap": 1, + "rx_lane": 3, + "rx_pn_swap": 1, + "serdes_params": { + "tx_eq_pre": 2, + "tx_eq_post": 4, + "tx_eq_attn": 0 + } + } + } + ] +} diff --git a/device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/port_config.ini b/device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/port_config.ini new file mode 100644 index 000000000000..d983617f1891 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/port_config.ini @@ -0,0 +1,33 @@ +# name lanes alias speed index +Ethernet0 0,1,2,3 Ethernet1/1 100000 1 +Ethernet4 4,5,6,7 Ethernet2/1 100000 2 +Ethernet8 8,9,10,11 Ethernet3/1 100000 3 +Ethernet12 12,13,14,15 Ethernet4/1 100000 4 +Ethernet16 16,17,18,19 Ethernet5/1 100000 5 +Ethernet20 20,21,22,23 Ethernet6/1 100000 6 +Ethernet24 24,25,26,27 Ethernet7/1 100000 7 +Ethernet28 28,29,30,31 Ethernet8/1 100000 8 +Ethernet32 32,33,34,35 Ethernet9/1 100000 9 +Ethernet36 36,37,38,39 Ethernet10/1 100000 10 +Ethernet40 40,41,42,43 Ethernet11/1 100000 11 +Ethernet44 44,45,46,47 Ethernet12/1 100000 12 +Ethernet48 48,49,50,51 Ethernet13/1 100000 13 +Ethernet52 52,53,54,55 Ethernet14/1 100000 14 +Ethernet56 56,57,58,59 Ethernet15/1 100000 15 +Ethernet60 60,61,62,63 Ethernet16/1 100000 16 +Ethernet64 64,65,66,67 Ethernet17/1 100000 17 +Ethernet68 68,69,70,71 Ethernet18/1 100000 18 +Ethernet72 72,73,74,75 Ethernet19/1 100000 19 +Ethernet76 76,77,78,79 Ethernet20/1 100000 20 +Ethernet80 80,81,82,83 Ethernet21/1 100000 21 +Ethernet84 84,85,86,87 Ethernet22/1 100000 22 +Ethernet88 88,89,90,91 Ethernet23/1 100000 23 +Ethernet92 92,93,94,95 Ethernet24/1 100000 24 +Ethernet96 96,97,98,99 Ethernet25/1 100000 25 +Ethernet100 100,101,102,103 Ethernet26/1 100000 26 +Ethernet104 104,105,106,107 Ethernet27/1 100000 27 +Ethernet108 108,109,110,111 Ethernet28/1 100000 28 +Ethernet112 112,113,114,115 Ethernet29/1 100000 29 +Ethernet116 116,117,118,119 Ethernet30/1 100000 30 +Ethernet120 120,121,122,123 Ethernet31/1 100000 31 +Ethernet124 124,125,126,127 Ethernet32/1 100000 32 diff --git a/device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/switch-sai.conf b/device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/switch-sai.conf new file mode 100644 index 000000000000..0a807b1c9ea7 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/switch-sai.conf @@ -0,0 +1,33 @@ +{ + "chip_list": [ + { + "id": "asic-0", + "chip_family": "Tofino", + "instance": 0, + "pcie_sysfs_prefix": "/sys/devices/pci0000:00/0000:00:1c.4/0000:07:00.0", + "pcie_domain": 0, + "pcie_bus": 7, + "pcie_fn": 0, + "pcie_dev": 0, + "pcie_int_mode": 1, + "sds_fw_path": "share/tofino_sds_fw/avago/firmware" + } + ], + "instance": 0, + "p4_program_list": [ + { + "id": "pgm-0", + "instance": 0, + "path": "switch", + "program-name": "switch", + "pd": "lib/tofinopd/switch/libpd.so", + "pd-thrift": "lib/tofinopd/switch/libpdthrift.so", + "table-config": "share/tofinopd/switch/context.json", + "tofino-bin": "share/tofinopd/switch/tofino.bin", + "switchapi": "lib/libswitchapi.so", + "sai": "lib/libsai.so", + "switchapi_port_add": false, + "non_default_port_ppgs": 5 + } + ] +} diff --git a/device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/switch-tna-sai.conf b/device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/switch-tna-sai.conf new file mode 100644 index 000000000000..ece3fcbe6a90 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32cd/Arista-7170-32CD-C32/switch-tna-sai.conf @@ -0,0 +1,39 @@ +{ + "instance": 0, + "chip_list": [ + { + "id": "asic-0", + "chip_family": "Tofino", + "instance": 0, + "pcie_sysfs_prefix": "/sys/devices/pci0000:00/0000:00:03.0/0000:05:00.0", + "pcie_domain": 0, + "pcie_bus": 5, + "pcie_fn": 0, + "pcie_dev": 0, + "pcie_int_mode": 1, + "sds_fw_path": "share/tofino_sds_fw/avago/firmware" + } + ], + "p4_devices": [ + { + "device-id": 0, + "p4_programs": [ + { + "p4_pipelines": [ + { + "p4_pipeline_name": "pipe", + "config": "share/switch/pipe/tofino.bin", + "context": "share/switch/pipe/context.json" + } + ], + "program-name": "switch", + "sai": "lib/libsai.so", + "bfrt-config": "share/switch/bf-rt.json", + "model_json_path" : "share/switch/aug_model.json", + "switchapi_port_add": false, + "non_default_port_ppgs": 5 + } + ] + } + ] +} diff --git a/device/arista/x86_64-arista_7170_32cd/default_sku b/device/arista/x86_64-arista_7170_32cd/default_sku new file mode 100644 index 000000000000..536bad44f086 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32cd/default_sku @@ -0,0 +1 @@ +Arista-7170-32CD-C32 t1 diff --git a/device/arista/x86_64-arista_7170_32cd/platform_reboot b/device/arista/x86_64-arista_7170_32cd/platform_reboot new file mode 120000 index 000000000000..7f94a49e38b0 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32cd/platform_reboot @@ -0,0 +1 @@ +../x86_64-arista_common/platform_reboot \ No newline at end of file diff --git a/device/arista/x86_64-arista_7170_32cd/plugins b/device/arista/x86_64-arista_7170_32cd/plugins new file mode 120000 index 000000000000..789a45fcace9 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32cd/plugins @@ -0,0 +1 @@ +../x86_64-arista_common/plugins \ No newline at end of file diff --git a/device/arista/x86_64-arista_7170_32cd/sensors.conf b/device/arista/x86_64-arista_7170_32cd/sensors.conf new file mode 120000 index 000000000000..1ab9e0f47704 --- /dev/null +++ b/device/arista/x86_64-arista_7170_32cd/sensors.conf @@ -0,0 +1 @@ +../x86_64-arista_7170_64c/sensors.conf \ No newline at end of file diff --git a/files/Aboot/boot0.j2 b/files/Aboot/boot0.j2 index 9ac100cc4248..3c61c631af93 100644 --- a/files/Aboot/boot0.j2 +++ b/files/Aboot/boot0.j2 @@ -216,9 +216,31 @@ EOF chmod a+r "${target_path}/machine.conf" } +in_array() { + local value="$1" + shift + + for other in $@; do + if [ "$value" = "$other" ]; then + return 0 + fi + done + + return 1 +} + +read_system_eeprom() { + if [ -x /bin/readprefdl ]; then + readprefdl -f /tmp/.system-prefdl -d > $target_path/.system-prefdl + elif [ -f /etc/prefdl ]; then + cp /etc/prefdl $target_path/.system-prefdl + chmod a+r $target_path/.system-prefdl + fi +} + platform_specific() { - local platform="$(grep -Eo 'platform=[^ ]+' "$cmdline_base" | cut -f2 -d=)" - local sid="$(grep -Eo 'sid=[^ ]+' "$cmdline_base" | cut -f2 -d=)" + local platform="$(sed -nr 's/.*platform=([^ ]+).*/\1/p' "$cmdline_base")" + local sid="$(sed -nr 's/.*sid=([^ ]+).*/\1/p' "$cmdline_base" | sed 's/Ssd$//')" # set varlog size to 100MB local varlog_size=100 @@ -227,31 +249,49 @@ platform_specific() { local flash_size=$(($(df | grep -E "$flash_re" | tr -s ' ' | cut -f2 -d' ') / 1000)) if [ "$platform" = "raven" ]; then + # Assuming sid=Cloverdale aboot_machine=arista_7050_qx32 flash_size=2000 docker_inram=on echo "modprobe.blacklist=radeon,sp5100_tco acpi=off docker_inram=on" >>/tmp/append fi if [ "$platform" = "crow" ]; then + # Assuming sid=Clearlake aboot_machine=arista_7050_qx32s flash_size=3700 echo "modprobe.blacklist=radeon,sp5100_tco" >>/tmp/append fi - if [ "$sid" = "Upperlake" ] || [ "$sid" = "UpperlakeES" ] || - [ "$sid" = "UpperlakeSsd" ]; then + if [ "$sid" = "Upperlake" ] || [ "$sid" = "UpperlakeES" ]; then aboot_machine=arista_7060_cx32s flash_size=3700 - echo "amd_iommu=off" >> /tmp/append fi - if [ "$sid" = "Gardena" ] || [ "$sid" = "GardenaSsd" ]; then + if [ "$sid" = "UpperlakePlus" ]; then + aboot_machine=arista_7060cx2_32s + flash_size=3700 + fi + if [ "$sid" = "Gardena" ] || [ "$sid" = "GardenaE" ]; then aboot_machine=arista_7260cx3_64 flash_size=28000 fi - if [ "$sid" = "Alhambra" ] || [ "$sid" = "AlhambraSsd" ]; then + if [ "$sid" = "Alhambra" ]; then aboot_machine=arista_7170_64c flash_size=28000 echo "hugepages=128" >> /tmp/append fi + if [ "$sid" = "Mineral" ]; then + aboot_machine=arista_7170_32c + flash_size=28000 + echo "hugepages=128" >> /tmp/append + fi + if [ "$sid" = "MineralD" ]; then + aboot_machine=arista_7170_32cd + flash_size=28000 + echo "hugepages=128" >> /tmp/append + fi + if [ "$sid" = "Lodoga" ]; then + aboot_machine=arista_7050cx3_32s + flash_size=3700 + fi if [ "$sid" = "BlackhawkO" ]; then aboot_machine=arista_7060px4_32 flash_size=28000 @@ -260,40 +300,30 @@ platform_specific() { aboot_machine=arista_7060dx4_32 flash_size=28000 fi - if [ "$sid" = "Smartsville" ] || [ "$sid" = "SmartsvilleSsd" ]; then + if [ "$sid" = "Smartsville" ]; then aboot_machine=arista_7280cr3_32p4 flash_size=7382 fi - if [ "$sid" = "SmartsvilleBK" ] || [ "$sid" = "SmartsvilleBKSsd" ]; then + if [ "$sid" = "SmartsvilleBK" ]; then aboot_machine=arista_7280cr3k_32p4 flash_size=7382 fi - if [ "$sid" = "SmartsvilleDD" ] || [ "$sid" = "SmartsvilleDDSsd" ]; then + if [ "$sid" = "SmartsvilleDD" ]; then aboot_machine=arista_7280cr3_32d4 flash_size=7382 fi - if [ "$sid" = "Lodoga" ] || [ "$sid" = "LodogaSsd" ]; then - aboot_machine=arista_7050cx3_32s - flash_size=3700 - echo "amd_iommu=off" >> /tmp/append - fi - if [ "$platform" = "rook" ] || [ "$platform" = "magpie" ] || - [ "$platform" = "woodpecker" ]; then + if in_array "$platform" "rook" "magpie" "woodpecker"; then echo "tsc=reliable pcie_ports=native" >>/tmp/append echo "rhash_entries=1 usb-storage.delay_use=0" >>/tmp/append - if [ -x /bin/readprefdl ]; then - readprefdl -f /tmp/.system-prefdl -d > /mnt/flash/.system-prefdl - elif [ -f /etc/prefdl ]; then - cp /etc/prefdl /mnt/flash/.system-prefdl - chmod a+r /mnt/flash/.system-prefdl - fi echo "reassign_prefmem" >> /tmp/append fi - if [ "$platform" = "rook" ] || [ "$platform" = "magpie" ]; then + if in_array "$platform" "rook"; then echo "iommu=on intel_iommu=on" >>/tmp/append + read_system_eeprom fi - if [ "$platform" = "woodpecker" ]; then + if in_array "$platform" "crow" "woodpecker" "magpie"; then echo "amd_iommu=off modprobe.blacklist=snd_hda_intel,hdaudio" >> /tmp/append + read_system_eeprom fi if [ $flash_size -ge 28000 ]; then @@ -363,7 +393,8 @@ write_boot_configs() { mkdir -p "$image_path" cat /tmp/append > $cmdline_image - [ -e ${target_path}/machine.conf ] || write_machine_config + [ -s ${target_path}/machine.conf ] || write_machine_config + sync } run_kexec() { diff --git a/files/initramfs-tools/union-mount.j2 b/files/initramfs-tools/union-mount.j2 index f6f1deff4220..39a514b0669e 100644 --- a/files/initramfs-tools/union-mount.j2 +++ b/files/initramfs-tools/union-mount.j2 @@ -21,6 +21,7 @@ set_tmpfs_log_partition_size() [ X"$aboot_platform" = X"x86_64-arista_7050_qx32" ] && return [ X"$aboot_platform" = X"x86_64-arista_7050_qx32s" ] && return [ X"$aboot_platform" = X"x86_64-arista_7060_cx32s" ] && return + [ X"$aboot_platform" = X"x86_64-arista_7060cx2_32s" ] && return # set varlogsize to existing var-log.ext4 size if [ -f ${rootmnt}/host/disk-img/var-log.ext4 ]; then diff --git a/platform/barefoot/sonic-platform-modules-arista b/platform/barefoot/sonic-platform-modules-arista index e9cabadb4272..39860a109853 160000 --- a/platform/barefoot/sonic-platform-modules-arista +++ b/platform/barefoot/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit e9cabadb42725d3c86eb93c3d766cfb5d58e6d29 +Subproject commit 39860a109853b2f37367dfe68905e019b509d5bf diff --git a/platform/broadcom/sonic-platform-modules-arista b/platform/broadcom/sonic-platform-modules-arista index e9cabadb4272..39860a109853 160000 --- a/platform/broadcom/sonic-platform-modules-arista +++ b/platform/broadcom/sonic-platform-modules-arista @@ -1 +1 @@ -Subproject commit e9cabadb42725d3c86eb93c3d766cfb5d58e6d29 +Subproject commit 39860a109853b2f37367dfe68905e019b509d5bf From aa30030fd1718fd644021e7d5f9d9669b3bc42ab Mon Sep 17 00:00:00 2001 From: Mykola F <37578614+mykolaf@users.noreply.github.com> Date: Tue, 31 Mar 2020 21:25:52 +0300 Subject: [PATCH 140/178] [devices][Mellanox] create sai.xml for MSN3800-D112-C8 (#4334) sai_xml contains info about port splits, previously it simply linked to the MSN3800 sai xml, which does not have splits. New version describes splits and speeds according to Mellanox-SN3800-D112-C8 SKU. Practically it can cause port recreation on SAI init. Signed-off-by: Mykola Faryma --- .../Mellanox-SN3800-D112C8/sai.profile | 2 +- .../Mellanox-SN3800-D112C8/sai_3800.xml | 1 - .../sai_3800_112x50g_8x100g.xml | 507 ++++++++++++++++++ 3 files changed, 508 insertions(+), 2 deletions(-) delete mode 120000 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai_3800.xml create mode 100644 device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai_3800_112x50g_8x100g.xml diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai.profile b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai.profile index 367f6c4e99c0..c5bb0c90f3d7 100644 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai.profile +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai.profile @@ -1 +1 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/sai_3800.xml +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/sai_3800_112x50g_8x100g.xml diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai_3800.xml b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai_3800.xml deleted file mode 120000 index 686d6298865c..000000000000 --- a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai_3800.xml +++ /dev/null @@ -1 +0,0 @@ -../ACS-MSN3800/sai_3800.xml \ No newline at end of file diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai_3800_112x50g_8x100g.xml b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai_3800_112x50g_8x100g.xml new file mode 100644 index 000000000000..102842d72275 --- /dev/null +++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/sai_3800_112x50g_8x100g.xml @@ -0,0 +1,507 @@ + + + + + + 00:02:03:04:05:00 + + + 64 + + + + + 1 + 4 + 48 + + + 3 + 2 + + + 384 + + + 3 + 4 + 49 + 3 + 2 + 384 + + + 5 + 4 + 50 + 3 + 2 + 384 + + + 7 + 4 + 51 + 3 + 384 + + + 9 + 4 + 52 + 3 + 2 + 384 + + + 11 + 4 + 53 + 3 + 2 + 384 + + + 13 + 4 + 54 + 3 + 2 + 384 + + + 15 + 4 + 55 + 3 + 384 + + + 17 + 4 + 56 + 3 + 2 + 384 + + + 19 + 4 + 57 + 3 + 2 + 384 + + + 21 + 4 + 58 + 3 + 2 + 384 + + + 23 + 4 + 59 + 3 + 384 + + + 25 + 4 + 60 + 3 + 2 + 384 + + + 27 + 4 + 61 + 3 + 2 + 384 + + + 29 + 4 + 62 + 3 + 2 + 384 + + + 31 + 4 + 63 + 3 + 384 + + + 33 + 4 + 12 + 3 + 2 + 384 + + + 35 + 4 + 13 + 3 + 2 + 384 + + + 37 + 4 + 14 + 3 + 2 + 384 + + + 39 + 4 + 15 + 3 + 384 + + + 41 + 4 + 8 + 3 + 2 + 384 + + + 43 + 4 + 9 + 3 + 2 + 384 + + + 45 + 4 + 10 + 3 + 2 + 384 + + + 47 + 4 + 11 + 3 + 384 + + + 49 + 4 + 4 + 3 + 2 + 384 + + + 51 + 4 + 5 + 3 + 2 + 384 + + + 53 + 4 + 6 + 3 + 2 + 384 + + + 55 + 4 + 7 + 3 + 384 + + + 57 + 4 + 0 + 3 + 2 + 384 + + + 59 + 4 + 1 + 3 + 2 + 384 + + + 61 + 4 + 2 + 3 + 2 + 384 + + + 63 + 4 + 3 + 3 + 384 + + + 65 + 4 + 44 + 3 + 2 + 384 + + + 67 + 4 + 45 + 3 + 2 + 384 + + + 69 + 4 + 46 + 3 + 2 + 384 + + + 71 + 4 + 47 + 3 + 384 + + + 73 + 4 + 40 + 3 + 2 + 384 + + + 75 + 4 + 41 + 3 + 2 + 384 + + + 77 + 4 + 42 + 3 + 2 + 384 + + + 79 + 4 + 43 + 3 + 384 + + + 81 + 4 + 36 + 3 + 1536 + + + 83 + 4 + 37 + 3 + 1536 + + + 85 + 4 + 38 + 3 + 2 + 384 + + + 87 + 4 + 39 + 3 + 384 + + + 89 + 4 + 32 + 3 + 1536 + + + 91 + 4 + 33 + 3 + 1536 + + + 93 + 4 + 34 + 3 + 2 + 384 + + + 95 + 4 + 35 + 3 + 384 + + + 97 + 4 + 16 + 3 + 2 + 384 + + + 99 + 4 + 17 + 3 + 2 + 384 + + + 101 + 4 + 18 + 3 + 2 + 384 + + + 103 + 4 + 19 + 3 + 384 + + + 105 + 4 + 20 + 3 + 2 + 384 + + + 107 + 4 + 21 + 3 + 2 + 384 + + + 109 + 4 + 22 + 3 + 2 + 384 + + + 111 + 4 + 23 + 3 + 384 + + + 113 + 4 + 24 + 3 + 1536 + + + 115 + 4 + 25 + 3 + 1536 + + + 117 + 4 + 26 + 3 + 2 + 384 + + + 119 + 4 + 27 + 3 + 384 + + + 121 + 4 + 28 + 3 + 1536 + + + 123 + 4 + 29 + 3 + 1536 + + + 125 + 4 + 30 + 3 + 2 + 384 + + + 127 + 4 + 31 + 3 + 384 + + + + From 6839d14129d7b7c48ae72917028780d54fd865d8 Mon Sep 17 00:00:00 2001 From: Ze Gan Date: Fri, 3 Apr 2020 09:17:08 +0800 Subject: [PATCH 141/178] Fixbug: EVPN issue in FRR template (#4260) * Fixbug: EVPN issue in FRR template --- dockers/docker-fpm-frr/bgpcfgd | 155 +++++++++++++++++++++++ dockers/docker-fpm-frr/bgpd.peer.conf.j2 | 3 +- 2 files changed, 156 insertions(+), 2 deletions(-) mode change 100644 => 100755 dockers/docker-fpm-frr/bgpd.peer.conf.j2 diff --git a/dockers/docker-fpm-frr/bgpcfgd b/dockers/docker-fpm-frr/bgpcfgd index 4348d22bcb8f..4e638def47b7 100755 --- a/dockers/docker-fpm-frr/bgpcfgd +++ b/dockers/docker-fpm-frr/bgpcfgd @@ -272,6 +272,8 @@ class BGPPeerMgr(Manager): [ ("meta", "localhost/bgp_asn"), ("neigmeta", ""), + ("local_addresses", ""), + ("interfaces", ""), ], "CONFIG_DB", swsscommon.CFG_BGP_NEIGHBOR_TABLE_NAME @@ -290,8 +292,42 @@ class BGPPeerMgr(Manager): vrf, nbr = key.split('|', 1) if key not in self.peers: cmd = None + + if "local_addr" not in data: + syslog.syslog(syslog.LOG_WARNING, 'Peer {}. Error in missing required attribute "local_addr"'.format(key)) + else: + # The bgp session that belongs to a vnet cannot be advertised as the default BGP session. + # So we need to check whether this bgp session belongs to a vnet. + interface = InterfaceMgr.get_local_interface(self.directory, data["local_addr"]) + if not interface: + syslog.syslog(syslog.LOG_INFO, + 'Peer {} with local address {} wait for the corresponding interface to be set'.format( + key, + data["local_addr"] + ) + ) + return False + vnet = InterfaceMgr.get_vnet(interface) + if vnet: + # Ignore the bgp session that is in a vnet + syslog.syslog( + syslog.LOG_INFO, + 'Ignore the BGP peer {} as the interface {} is in vnet {}'.format( + key, + interface, + vnet + ) + ) + return True + neigmeta = self.directory.get_slot("neigmeta") if 'name' in data and data["name"] not in neigmeta: + syslog.syslog(syslog.LOG_INFO, + 'Peer {} with neighbor name {} wait for the corresponding neighbor metadata to be set'.format( + key, + data["name"] + ) + ) return False try: cmd = self.templates["add"].render( @@ -390,6 +426,121 @@ class BGPPeerMgr(Manager): return peers +class InterfaceMgr(Manager): + def __init__(self, daemon, directory, interface_table = swsscommon.CFG_INTF_TABLE_NAME): + super(InterfaceMgr, self).__init__( + daemon, + directory, + [], + "CONFIG_DB", + interface_table + ) + + def set_handler(self, key, data): + # Interface table can have two keys, + # one with ip prefix and one without ip prefix + if '|' in key: + data = {} + data["interface"], network = key.split('|', 1) + try: + network = netaddr.IPNetwork(str(network)) + except: + syslog.syslog( + syslog.LOG_WARNING, + 'Subnet {} format is wrong for interface {}'.format( + network, + data["interface"] + ) + ) + return False + data["prefixlen"] = str(network.prefixlen) + ip = str(network.ip) + self.directory.put("local_addresses", ip, data) + else: + self.directory.put("interfaces", key, data) + return True + + def del_handler(self, key): + if '|' in key: + interface, network = key.split('|', 1) + try: + network = netaddr.IPNetwork(str(network)) + except: + syslog.syslog( + syslog.LOG_WARNING, + 'Subnet {} format is wrong for interface {}'.format( + network, + interface + ) + ) + return False + ip = str(network.ip) + self.directory.remove("local_addresses", ip) + else: + self.directory.remove("interfaces", key) + + @staticmethod + def get_local_interface(directory, local_addr): + """ + @summary: Get interface according to the local address from the directory + @param directory: Directory object that stored metadata of interfaces + @param local_addr: Local address of the interface + @return: Return the metadata of the interface with the local address + If the interface has not been set, return None + """ + local_addresses = directory.get_slot("local_addresses") + # Check if the local address of this bgp session has been set + if local_addr not in local_addresses: + return None + local_address = local_addresses[local_addr] + interfaces = directory.get_slot("interfaces") + # Check if the information for the interface of this local address has been set + if local_address.has_key("interface") and local_address["interface"] in interfaces: + return interfaces[local_address["interface"]] + else: + return None + + @staticmethod + def get_vnet(interface): + """ + @summary: Get the VNet name of the interface + @param interface: The metadata of the interface + @return: Return the vnet name of the interface if this interface belongs to a vnet, + Otherwise return None + """ + if interface.has_key("vnet_name") and interface["vnet_name"]: + return interface["vnet_name"] + else: + return None + + +class LoopbackInterfaceMgr(InterfaceMgr): + def __init__(self, daemon, directory): + super(LoopbackInterfaceMgr, self).__init__( + daemon, + directory, + swsscommon.CFG_LOOPBACK_INTERFACE_TABLE_NAME + ) + + +class VlanInterfaceMgr(InterfaceMgr): + def __init__(self, daemon, directory): + super(VlanInterfaceMgr, self).__init__( + daemon, + directory, + swsscommon.CFG_VLAN_INTF_TABLE_NAME + ) + + +class PortChannelInterfaceMgr(InterfaceMgr): + def __init__(self, daemon, directory): + super(PortChannelInterfaceMgr, self).__init__( + daemon, + directory, + swsscommon.CFG_LAG_INTF_TABLE_NAME + ) + + def wait_for_bgpd(): # wait for 20 seconds stop_time = datetime.datetime.now() + datetime.timedelta(seconds=20) @@ -408,6 +559,10 @@ def main(): BGPDeviceMetaMgr, BGPNeighborMetaMgr, BGPPeerMgr, + InterfaceMgr, + LoopbackInterfaceMgr, + VlanInterfaceMgr, + PortChannelInterfaceMgr, ] wait_for_bgpd() daemon = Daemon() diff --git a/dockers/docker-fpm-frr/bgpd.peer.conf.j2 b/dockers/docker-fpm-frr/bgpd.peer.conf.j2 old mode 100644 new mode 100755 index c3dc50449d35..bcc520f6b2df --- a/dockers/docker-fpm-frr/bgpd.peer.conf.j2 +++ b/dockers/docker-fpm-frr/bgpd.peer.conf.j2 @@ -26,8 +26,7 @@ neighbor {{ neighbor_addr }} next-hop-self {% endif %} {% if bgp_session["asn"] == DEVICE_METADATA['localhost']['bgp_asn'] - and DEVICE_METADATA['localhost']['type'] == "SpineChassisFrontendRouter" - and (not bgp_session.has_key("local_addr") or bgp_session["local_addr"] not in interfaces_in_vnets) %} + and DEVICE_METADATA['localhost']['type'] == "SpineChassisFrontendRouter" %} address-family l2vpn evpn neighbor {{ neighbor_addr }} activate advertise-all-vni From 249265ad99fb0df8dd51dc274dea70499cc7cfa6 Mon Sep 17 00:00:00 2001 From: Abhishek Dosi Date: Fri, 3 Apr 2020 14:34:38 -0700 Subject: [PATCH 142/178] Revert "Multi-ASIC implementation (#3888)" This reverts commit 2e87a16941a5624c701baa39044ff14eadc6c0da. --- .../msft_multi_asic_vs/0/lanemap.ini | 32 ------ .../msft_multi_asic_vs/0/sai.profile | 7 +- .../msft_multi_asic_vs/1/lanemap.ini | 32 ------ .../msft_multi_asic_vs/1/sai.profile | 7 +- .../msft_multi_asic_vs/2/lanemap.ini | 32 ------ .../msft_multi_asic_vs/2/sai.profile | 7 +- .../msft_multi_asic_vs/3/lanemap.ini | 32 ------ .../msft_multi_asic_vs/3/sai.profile | 7 +- .../msft_multi_asic_vs/4/lanemap.ini | 32 ------ .../msft_multi_asic_vs/4/sai.profile | 7 +- .../msft_multi_asic_vs/5/lanemap.ini | 32 ------ .../msft_multi_asic_vs/5/sai.profile | 7 +- .../msft_multi_asic_vs/topology.sh | 13 ++- dockers/docker-fpm-frr/bgpd.conf.default.j2 | 20 ---- files/build_templates/database.service.j2 | 1 - files/build_templates/docker_image_ctl.j2 | 69 +++++------- files/build_templates/lldp.service.j2 | 18 ++++ .../per_namespace/bgp.service.j2 | 21 ---- .../per_namespace/database.service.j2 | 22 ---- .../per_namespace/lldp.service.j2 | 22 ---- .../per_namespace/swss.service.j2 | 31 ------ .../per_namespace/syncd.service.j2 | 33 ------ .../per_namespace/teamd.service.j2 | 19 ---- .../single_instance/bgp.service.j2 | 18 ++++ .../single_instance/database.service.j2 | 18 ++++ .../single_instance/swss.service.j2 | 25 +++++ .../single_instance/syncd.service.j2 | 30 ++++++ .../single_instance/teamd.service.j2 | 18 ++++ .../build_templates/sonic_debian_extension.j2 | 4 - files/image_config/topology/topology.sh | 18 ++-- files/scripts/sonic-netns-exec | 12 --- files/scripts/swss.sh | 100 ++++++------------ files/scripts/syncd.sh | 55 ++++------ platform/vs/sonic_multiasic.xml | 2 +- rules/docker-fpm-frr.mk | 1 + slave.mk | 28 ++--- 36 files changed, 246 insertions(+), 586 deletions(-) delete mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/lanemap.ini delete mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/lanemap.ini delete mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/lanemap.ini delete mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/lanemap.ini delete mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/lanemap.ini delete mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/lanemap.ini delete mode 120000 files/build_templates/database.service.j2 create mode 100644 files/build_templates/lldp.service.j2 delete mode 100644 files/build_templates/per_namespace/bgp.service.j2 delete mode 100644 files/build_templates/per_namespace/database.service.j2 delete mode 100644 files/build_templates/per_namespace/lldp.service.j2 delete mode 100644 files/build_templates/per_namespace/swss.service.j2 delete mode 100644 files/build_templates/per_namespace/syncd.service.j2 delete mode 100644 files/build_templates/per_namespace/teamd.service.j2 create mode 100644 files/build_templates/single_instance/bgp.service.j2 create mode 100644 files/build_templates/single_instance/database.service.j2 create mode 100644 files/build_templates/single_instance/swss.service.j2 create mode 100644 files/build_templates/single_instance/syncd.service.j2 create mode 100644 files/build_templates/single_instance/teamd.service.j2 delete mode 100755 files/scripts/sonic-netns-exec diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/lanemap.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/lanemap.ini deleted file mode 100644 index 36278a01778c..000000000000 --- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/lanemap.ini +++ /dev/null @@ -1,32 +0,0 @@ -eth1:25,26,27,28 -eth2:29,30,31,32 -eth3:33,34,35,36 -eth4:37,38,39,40 -eth5:45,46,47,48 -eth6:41,42,43,44 -eth7:1,2,3,4 -eth8:5,6,7,8 -eth9:13,14,15,16 -eth10:9,10,11,12 -eth11:17,18,19,20 -eth12:21,22,23,24 -eth13:53,54,55,56 -eth14:49,50,51,52 -eth15:57,58,59,60 -eth16:61,62,63,64 -eth17:69,70,71,72 -eth18:65,66,67,68 -eth19:73,74,75,76 -eth20:77,78,79,80 -eth21:109,110,111,112 -eth22:105,106,107,108 -eth23:113,114,115,116 -eth24:117,118,119,120 -eth25:125,126,127,128 -eth26:121,122,123,124 -eth27:81,82,83,84 -eth28:85,86,87,88 -eth29:93,94,95,96 -eth30:89,90,91,92 -eth31:101,102,103,104 -eth32:97,98,99,100 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/sai.profile index bfc466f27e54..52e2e289af60 100644 --- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/sai.profile +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/sai.profile @@ -1,5 +1,2 @@ -SAI_WARM_BOOT_READ_FILE=/var/cache/sai_warmboot.bin -SAI_WARM_BOOT_WRITE_FILE=/var/cache/sai_warmboot.bin -SAI_VS_SWITCH_TYPE=SAI_VS_SWITCH_TYPE_BCM56850 -SAI_VS_HOSTIF_USE_TAP_DEVICE=true -SAI_VS_INTERFACE_LANE_MAP_FILE=/usr/share/sonic/hwsku/lanemap.ini +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm +SAI_NUM_ECMP_MEMBERS=32 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/lanemap.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/lanemap.ini deleted file mode 100644 index 36278a01778c..000000000000 --- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/lanemap.ini +++ /dev/null @@ -1,32 +0,0 @@ -eth1:25,26,27,28 -eth2:29,30,31,32 -eth3:33,34,35,36 -eth4:37,38,39,40 -eth5:45,46,47,48 -eth6:41,42,43,44 -eth7:1,2,3,4 -eth8:5,6,7,8 -eth9:13,14,15,16 -eth10:9,10,11,12 -eth11:17,18,19,20 -eth12:21,22,23,24 -eth13:53,54,55,56 -eth14:49,50,51,52 -eth15:57,58,59,60 -eth16:61,62,63,64 -eth17:69,70,71,72 -eth18:65,66,67,68 -eth19:73,74,75,76 -eth20:77,78,79,80 -eth21:109,110,111,112 -eth22:105,106,107,108 -eth23:113,114,115,116 -eth24:117,118,119,120 -eth25:125,126,127,128 -eth26:121,122,123,124 -eth27:81,82,83,84 -eth28:85,86,87,88 -eth29:93,94,95,96 -eth30:89,90,91,92 -eth31:101,102,103,104 -eth32:97,98,99,100 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/sai.profile index bfc466f27e54..52e2e289af60 100644 --- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/sai.profile +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/sai.profile @@ -1,5 +1,2 @@ -SAI_WARM_BOOT_READ_FILE=/var/cache/sai_warmboot.bin -SAI_WARM_BOOT_WRITE_FILE=/var/cache/sai_warmboot.bin -SAI_VS_SWITCH_TYPE=SAI_VS_SWITCH_TYPE_BCM56850 -SAI_VS_HOSTIF_USE_TAP_DEVICE=true -SAI_VS_INTERFACE_LANE_MAP_FILE=/usr/share/sonic/hwsku/lanemap.ini +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm +SAI_NUM_ECMP_MEMBERS=32 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/lanemap.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/lanemap.ini deleted file mode 100644 index 36278a01778c..000000000000 --- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/lanemap.ini +++ /dev/null @@ -1,32 +0,0 @@ -eth1:25,26,27,28 -eth2:29,30,31,32 -eth3:33,34,35,36 -eth4:37,38,39,40 -eth5:45,46,47,48 -eth6:41,42,43,44 -eth7:1,2,3,4 -eth8:5,6,7,8 -eth9:13,14,15,16 -eth10:9,10,11,12 -eth11:17,18,19,20 -eth12:21,22,23,24 -eth13:53,54,55,56 -eth14:49,50,51,52 -eth15:57,58,59,60 -eth16:61,62,63,64 -eth17:69,70,71,72 -eth18:65,66,67,68 -eth19:73,74,75,76 -eth20:77,78,79,80 -eth21:109,110,111,112 -eth22:105,106,107,108 -eth23:113,114,115,116 -eth24:117,118,119,120 -eth25:125,126,127,128 -eth26:121,122,123,124 -eth27:81,82,83,84 -eth28:85,86,87,88 -eth29:93,94,95,96 -eth30:89,90,91,92 -eth31:101,102,103,104 -eth32:97,98,99,100 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/sai.profile index bfc466f27e54..52e2e289af60 100644 --- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/sai.profile +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/sai.profile @@ -1,5 +1,2 @@ -SAI_WARM_BOOT_READ_FILE=/var/cache/sai_warmboot.bin -SAI_WARM_BOOT_WRITE_FILE=/var/cache/sai_warmboot.bin -SAI_VS_SWITCH_TYPE=SAI_VS_SWITCH_TYPE_BCM56850 -SAI_VS_HOSTIF_USE_TAP_DEVICE=true -SAI_VS_INTERFACE_LANE_MAP_FILE=/usr/share/sonic/hwsku/lanemap.ini +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm +SAI_NUM_ECMP_MEMBERS=32 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/lanemap.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/lanemap.ini deleted file mode 100644 index 36278a01778c..000000000000 --- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/lanemap.ini +++ /dev/null @@ -1,32 +0,0 @@ -eth1:25,26,27,28 -eth2:29,30,31,32 -eth3:33,34,35,36 -eth4:37,38,39,40 -eth5:45,46,47,48 -eth6:41,42,43,44 -eth7:1,2,3,4 -eth8:5,6,7,8 -eth9:13,14,15,16 -eth10:9,10,11,12 -eth11:17,18,19,20 -eth12:21,22,23,24 -eth13:53,54,55,56 -eth14:49,50,51,52 -eth15:57,58,59,60 -eth16:61,62,63,64 -eth17:69,70,71,72 -eth18:65,66,67,68 -eth19:73,74,75,76 -eth20:77,78,79,80 -eth21:109,110,111,112 -eth22:105,106,107,108 -eth23:113,114,115,116 -eth24:117,118,119,120 -eth25:125,126,127,128 -eth26:121,122,123,124 -eth27:81,82,83,84 -eth28:85,86,87,88 -eth29:93,94,95,96 -eth30:89,90,91,92 -eth31:101,102,103,104 -eth32:97,98,99,100 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/sai.profile index bfc466f27e54..52e2e289af60 100644 --- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/sai.profile +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/sai.profile @@ -1,5 +1,2 @@ -SAI_WARM_BOOT_READ_FILE=/var/cache/sai_warmboot.bin -SAI_WARM_BOOT_WRITE_FILE=/var/cache/sai_warmboot.bin -SAI_VS_SWITCH_TYPE=SAI_VS_SWITCH_TYPE_BCM56850 -SAI_VS_HOSTIF_USE_TAP_DEVICE=true -SAI_VS_INTERFACE_LANE_MAP_FILE=/usr/share/sonic/hwsku/lanemap.ini +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm +SAI_NUM_ECMP_MEMBERS=32 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/lanemap.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/lanemap.ini deleted file mode 100644 index 36278a01778c..000000000000 --- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/lanemap.ini +++ /dev/null @@ -1,32 +0,0 @@ -eth1:25,26,27,28 -eth2:29,30,31,32 -eth3:33,34,35,36 -eth4:37,38,39,40 -eth5:45,46,47,48 -eth6:41,42,43,44 -eth7:1,2,3,4 -eth8:5,6,7,8 -eth9:13,14,15,16 -eth10:9,10,11,12 -eth11:17,18,19,20 -eth12:21,22,23,24 -eth13:53,54,55,56 -eth14:49,50,51,52 -eth15:57,58,59,60 -eth16:61,62,63,64 -eth17:69,70,71,72 -eth18:65,66,67,68 -eth19:73,74,75,76 -eth20:77,78,79,80 -eth21:109,110,111,112 -eth22:105,106,107,108 -eth23:113,114,115,116 -eth24:117,118,119,120 -eth25:125,126,127,128 -eth26:121,122,123,124 -eth27:81,82,83,84 -eth28:85,86,87,88 -eth29:93,94,95,96 -eth30:89,90,91,92 -eth31:101,102,103,104 -eth32:97,98,99,100 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/sai.profile index bfc466f27e54..52e2e289af60 100644 --- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/sai.profile +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/sai.profile @@ -1,5 +1,2 @@ -SAI_WARM_BOOT_READ_FILE=/var/cache/sai_warmboot.bin -SAI_WARM_BOOT_WRITE_FILE=/var/cache/sai_warmboot.bin -SAI_VS_SWITCH_TYPE=SAI_VS_SWITCH_TYPE_BCM56850 -SAI_VS_HOSTIF_USE_TAP_DEVICE=true -SAI_VS_INTERFACE_LANE_MAP_FILE=/usr/share/sonic/hwsku/lanemap.ini +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm +SAI_NUM_ECMP_MEMBERS=32 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/lanemap.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/lanemap.ini deleted file mode 100644 index 36278a01778c..000000000000 --- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/lanemap.ini +++ /dev/null @@ -1,32 +0,0 @@ -eth1:25,26,27,28 -eth2:29,30,31,32 -eth3:33,34,35,36 -eth4:37,38,39,40 -eth5:45,46,47,48 -eth6:41,42,43,44 -eth7:1,2,3,4 -eth8:5,6,7,8 -eth9:13,14,15,16 -eth10:9,10,11,12 -eth11:17,18,19,20 -eth12:21,22,23,24 -eth13:53,54,55,56 -eth14:49,50,51,52 -eth15:57,58,59,60 -eth16:61,62,63,64 -eth17:69,70,71,72 -eth18:65,66,67,68 -eth19:73,74,75,76 -eth20:77,78,79,80 -eth21:109,110,111,112 -eth22:105,106,107,108 -eth23:113,114,115,116 -eth24:117,118,119,120 -eth25:125,126,127,128 -eth26:121,122,123,124 -eth27:81,82,83,84 -eth28:85,86,87,88 -eth29:93,94,95,96 -eth30:89,90,91,92 -eth31:101,102,103,104 -eth32:97,98,99,100 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/sai.profile index bfc466f27e54..52e2e289af60 100644 --- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/sai.profile +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/sai.profile @@ -1,5 +1,2 @@ -SAI_WARM_BOOT_READ_FILE=/var/cache/sai_warmboot.bin -SAI_WARM_BOOT_WRITE_FILE=/var/cache/sai_warmboot.bin -SAI_VS_SWITCH_TYPE=SAI_VS_SWITCH_TYPE_BCM56850 -SAI_VS_HOSTIF_USE_TAP_DEVICE=true -SAI_VS_INTERFACE_LANE_MAP_FILE=/usr/share/sonic/hwsku/lanemap.ini +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm +SAI_NUM_ECMP_MEMBERS=32 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/topology.sh b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/topology.sh index cf70f3063189..378f794190d4 100755 --- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/topology.sh +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/topology.sh @@ -14,10 +14,9 @@ start () { # eth48 - eth63: asic5 for ASIC in `seq $FIRST_FRONTEND_ASIC $LAST_FRONTEND_ASIC`; do for NUM in `seq 1 16`; do - ORIG="eth$((16 * $ASIC + $NUM))" + ORIG="eth$((16 * $ASIC + $NUM - 1))" TEMP="ethTemp999" - NEW="eth$(($NUM))" - echo "$ASIC : $NEW old $ORIG" + NEW="eth$(($NUM + 16))" ip link set dev $ORIG down ip link set dev $ORIG name $TEMP # rename to prevent conflicts before renaming in new namespace ip link set dev $TEMP netns asic$ASIC @@ -30,9 +29,8 @@ start () { for BACKEND in `seq $FIRST_BACKEND_ASIC $LAST_BACKEND_ASIC`; do for FRONTEND in `seq $FIRST_FRONTEND_ASIC $LAST_FRONTEND_ASIC`; do for LINK in `seq 1 8`; do - FRONT_NAME="eth$((8 * $(($BACKEND - $FIRST_BACKEND_ASIC)) + $LINK + 16))" - BACK_NAME="eth$((8 * $FRONTEND + $LINK))" - echo "$FRONTEND:$FRONT_NAME - $BACKEND:$BACK_NAME" + BACK_NAME="eth$((8 * $FRONTEND + $LINK))" + FRONT_NAME="eth$((8 * $(($LAST_BACKEND_ASIC - $BACKEND)) + $LINK))" TEMP_BACK="ethBack999" TEMP_FRONT="ethFront999" @@ -54,7 +52,7 @@ stop() { for ASIC in `seq $FIRST_FRONTEND_ASIC $LAST_FRONTEND_ASIC`; do for NUM in `seq 1 16`; do TEMP="eth999" - OLD="eth$((16 * $ASIC + $NUM))" + OLD="eth$(($NUM + 16))" NAME="eth$((16 * $ASIC + $NUM - 1))" sudo ip netns exec asic$ASIC ip link set dev $OLD down sudo ip netns exec asic$ASIC ip link set dev $OLD name $TEMP @@ -80,3 +78,4 @@ case "$1" in echo "Usage: $0 {start|stop}" ;; esac + diff --git a/dockers/docker-fpm-frr/bgpd.conf.default.j2 b/dockers/docker-fpm-frr/bgpd.conf.default.j2 index 2bf80b80a787..e12782b035aa 100644 --- a/dockers/docker-fpm-frr/bgpd.conf.default.j2 +++ b/dockers/docker-fpm-frr/bgpd.conf.default.j2 @@ -23,20 +23,6 @@ route-map TO_BGP_PEER_V4 permit 100 ! route-map TO_BGP_PEER_V6 permit 100 ! -{% if DEVICE_METADATA['localhost']['type'] == 'InternalFrontend' %} -route-map HIDE_INTERNAL permit 10 - set community local-AS -! -{% endif %} -{% if DEVICE_METADATA['localhost']['type'] == 'InternalBackend' %} -route-map OVERRIDE_ORIGINATOR_ID permit 10 -{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} -{% if prefix | ipv4 and name == 'Loopback0' %} - set originator-id {{ prefix | ip }} -{% endif %} -{% endfor %} -! -{% endif %} {% if BGP_MONITORS is defined and BGP_MONITORS|length > 0 %} route-map FROM_BGPMON deny 10 ! @@ -51,9 +37,6 @@ route-map set-next-hop-global-v6 permit 10 set ipv6 next-hop prefer-global ! router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} -{% if DEVICE_METADATA['localhost']['type'] == 'InternalFrontend' %} - redistribute connected route-map HIDE_INTERNAL -{% endif %} bgp log-neighbor-changes bgp bestpath as-path multipath-relax no bgp default ipv4-unicast @@ -168,9 +151,6 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} neighbor {{ neighbor_addr }} peer-group BGPMON neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} neighbor {{ neighbor_addr }} activate -{% if DEVICE_METADATA['localhost']['type'] == 'InternalBackend' %} - neighbor {{ neighbor_addr }} route-map OVERRIDE_ORIGINATOR_ID in -{% endif %} address-family ipv6 neighbor {{ neighbor_addr }} activate exit-address-family diff --git a/files/build_templates/database.service.j2 b/files/build_templates/database.service.j2 deleted file mode 120000 index 63340abef881..000000000000 --- a/files/build_templates/database.service.j2 +++ /dev/null @@ -1 +0,0 @@ -per_namespace/database.service.j2 \ No newline at end of file diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 297c9dd1c2bd..5de892555a1b 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -14,16 +14,15 @@ link_namespace() { mkdir -p /var/run/netns PID="$(docker inspect -f {{"'{{.State.Pid}}'"}} "{{docker_container_name}}$DEV")" - PIDS=`ip netns pids "$NET_NS" 2>/dev/null` - if [ "$?" -eq "0" ]; then # namespace exists - if `echo $PIDS | grep --quiet -w $PID`; then # namespace is correctly linked + if `ip netns | grep --quiet -w "{{docker_container_name}}$DEV"`; then # namespace exists + if [ $(readlink -f /var/run/netns/$NET_NS$DEV) = $(readlink -f /proc/$PID/ns/net) ]; then # namespace is correctly linked return 0 else # if it's incorrectly linked remove it - ip netns delete $NET_NS + ip netns delete "{{docker_container_name}}$DEV" fi fi - ln -s /proc/$PID/ns/net /var/run/netns/$NET_NS + ln -s /proc/$PID/ns/net /var/run/netns/$NET_NS$DEV } {%- endif %} @@ -57,14 +56,14 @@ function preStartAction() WARM_DIR=/host/warmboot if [[ ("$BOOT_TYPE" == "warm" || "$BOOT_TYPE" == "fastfast") && -f $WARM_DIR/dump.rdb ]]; then # Load redis content from /host/warmboot/dump.rdb - docker cp $WARM_DIR/dump.rdb database$DEV:/var/lib/redis/dump.rdb + docker cp $WARM_DIR/dump.rdb database:/var/lib/redis/dump.rdb else # 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:/var/lib/redis/ fi {%- elif docker_container_name == "snmp" %} - sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB HSET 'DEVICE_METADATA|localhost' chassis_serial_number $(decode-syseeprom -s) + sonic-db-cli STATE_DB HSET 'DEVICE_METADATA|localhost' chassis_serial_number $(decode-syseeprom -s) {%- else %} : # nothing {%- endif %} @@ -77,25 +76,25 @@ function postStartAction() link_namespace $DEV fi # Wait until redis starts - /usr/bin/docker exec database$DEV ping_pong_db_insts + /usr/bin/docker exec database ping_pong_db_insts if [[ ("$BOOT_TYPE" == "warm" || "$BOOT_TYPE" == "fastfast") && -f $WARM_DIR/dump.rdb ]]; then rm -f $WARM_DIR/dump.rdb else # If there is a config_db.json dump file, load it. - if [ -r /etc/sonic/config_db$DEV.json ]; then + if [ -r /etc/sonic/config_db.json ]; then if [ -r /etc/sonic/init_cfg.json ]; then - sonic-netns-exec "$NET_NS" sonic-cfggen -j /etc/sonic/init_cfg.json -j /etc/sonic/config_db$DEV.json --write-to-db + sonic-cfggen -j /etc/sonic/init_cfg.json -j /etc/sonic/config_db.json --write-to-db else - sonic-netns-exec "$NET_NS" sonic-cfggen -j /etc/sonic/config_db$DEV.json --write-to-db + sonic-cfggen -j /etc/sonic/config_db.json --write-to-db fi fi if [[ "$BOOT_TYPE" == "fast" ]]; then # set the key to expire in 3 minutes - /usr/bin/sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB SET "FAST_REBOOT|system" "1" "EX" "180" + sonic-db-cli STATE_DB SET "FAST_REBOOT|system" "1" "EX" "180" fi - /usr/bin/sonic-netns-exec "$NET_NS" sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" + sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" fi if [[ -x /usr/bin/db_migrator.py ]]; then @@ -103,14 +102,14 @@ function postStartAction() /usr/bin/db_migrator.py -o migrate fi {%- elif docker_container_name == "swss" %} - docker exec swss$DEV rm -f /ready # remove cruft + docker exec swss rm -f /ready # remove cruft if [[ "$BOOT_TYPE" == "fast" ]] && [[ -d /host/fast-reboot ]]; then - test -e /host/fast-reboot/fdb.json && docker cp /host/fast-reboot/fdb.json swss$DEV:/ - test -e /host/fast-reboot/arp.json && docker cp /host/fast-reboot/arp.json swss$DEV:/ - test -e /host/fast-reboot/default_routes.json && docker cp /host/fast-reboot/default_routes.json swss$DEV:/ + test -e /host/fast-reboot/fdb.json && docker cp /host/fast-reboot/fdb.json swss:/ + test -e /host/fast-reboot/arp.json && docker cp /host/fast-reboot/arp.json swss:/ + test -e /host/fast-reboot/default_routes.json && docker cp /host/fast-reboot/default_routes.json swss:/ rm -fr /host/fast-reboot fi - docker exec swss$DEV touch /ready # signal swssconfig.sh to go + docker exec swss touch /ready # signal swssconfig.sh to go {%- elif docker_container_name == "pmon" %} DEVPATH="/usr/share/sonic/device" @@ -132,14 +131,14 @@ start() { BOOT_TYPE=`getBootType` # Obtain our platform as we will mount directories with these names in each docker - PLATFORM=`sonic-netns-exec "$NET_NS" sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` + PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` {%- if docker_container_name == "database" %} # Don't mount HWSKU in {{docker_container_name}} container. HWSKU="" {%- else %} # Obtain our HWSKU as we will mount directories with these names in each docker - HWSKU=`sonic-netns-exec "$NET_NS" sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hwsku"]'` + HWSKU=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hwsku"]'` {%- endif %} DOCKERCHECK=`docker inspect --type container {{docker_container_name}}$DEV 2>/dev/null` @@ -186,14 +185,7 @@ start() { NET="container:database$DEV" {%- endif %} fi -{%- if docker_container_name == "bgp" %} - if [ "$DEV" ]; then - if [ ! -d "/etc/sonic/frr/$DEV" ]; then - mkdir /etc/sonic/frr/$DEV - cp -r /etc/sonic/frr/*.conf /etc/sonic/frr/$DEV - fi - fi -{%- endif %} + {%- if sonic_asic_platform == "mellanox" %} # TODO: Mellanox will remove the --tmpfs exception after SDK socket path changed in new SDK version {%- endif %} @@ -223,13 +215,10 @@ start() { --tmpfs /tmp \ {%- endif %} {%- endif %} -{%- if docker_container_name == "bgp" %} - -v /etc/sonic/frr/$DEV:/etc/frr:rw \ -{%- endif %} - -v /var/run/redis$DEV:/var/run/redis:rw \ + -v /var/run/redis:/var/run/redis:rw \ -v /usr/share/sonic/device/$PLATFORM:/usr/share/sonic/platform:ro \ {%- if docker_container_name != "database" %} - -v /usr/share/sonic/device/$PLATFORM/$HWSKU/$DEV:/usr/share/sonic/hwsku:ro \ + -v /usr/share/sonic/device/$PLATFORM/$HWSKU:/usr/share/sonic/hwsku:ro \ {%- endif %} {%- if sonic_asic_platform != "mellanox" %} --tmpfs /tmp \ @@ -241,7 +230,7 @@ start() { } preStartAction - docker start {{docker_container_name}}$DEV + docker start {{docker_container_name}} postStartAction } @@ -252,19 +241,13 @@ wait() { stop() { docker stop {{docker_container_name}}$DEV {%- if docker_container_name == "database" %} - if [ "$DEV" ]; then - ip netns delete "$NET_NS" - fi + ip netns delete "$NET_NS$DEV" {%- endif %} } OP=$1 DEV=$2 # namespace/device number to operate on -if [ "$DEV" ]; then - NET_NS="asic$DEV" #name of the network namespace -else - NET_NS="" -fi +NET_NS="asic" #name of the network namespace case "$1" in start|wait|stop) diff --git a/files/build_templates/lldp.service.j2 b/files/build_templates/lldp.service.j2 new file mode 100644 index 000000000000..2599fc5c5bdc --- /dev/null +++ b/files/build_templates/lldp.service.j2 @@ -0,0 +1,18 @@ +[Unit] +Description=LLDP container +Requires=updategraph.service +After=updategraph.service swss.service syncd.service +Before=ntp-config.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 + +[Service] +User={{ sonicadmin_user }} +ExecStartPre=/usr/bin/{{docker_container_name}}.sh start +ExecStart=/usr/bin/{{docker_container_name}}.sh wait +ExecStop=/usr/bin/{{docker_container_name}}.sh stop +Restart=always +RestartSec=30 + +[Install] +WantedBy=multi-user.target diff --git a/files/build_templates/per_namespace/bgp.service.j2 b/files/build_templates/per_namespace/bgp.service.j2 deleted file mode 100644 index 79e9afc4ebc1..000000000000 --- a/files/build_templates/per_namespace/bgp.service.j2 +++ /dev/null @@ -1,21 +0,0 @@ -[Unit] -Description=BGP container -Requires=database{% if multi_instance == 'true' %}@%i{% endif %}.service -After=database{% if multi_instance == 'true' %}@%i{% endif %}.service -Requires=updategraph.service -After=updategraph.service -Before=ntp-config.service -StartLimitIntervalSec=1200 -StartLimitBurst=3 - -[Service] -User={{ sonicadmin_user }} -ExecStartPre=/usr/bin/{{docker_container_name}}.sh start{% if multi_instance == 'true' %} %i{% endif %} -ExecStart=/usr/bin/{{docker_container_name}}.sh wait{% if multi_instance == 'true' %} %i{% endif %} -ExecStop=/usr/bin/{{docker_container_name}}.sh stop{% if multi_instance == 'true' %} %i{% endif %} - -Restart=always -RestartSec=30 - -[Install] -WantedBy=multi-user.target diff --git a/files/build_templates/per_namespace/database.service.j2 b/files/build_templates/per_namespace/database.service.j2 deleted file mode 100644 index 396fdc6678c2..000000000000 --- a/files/build_templates/per_namespace/database.service.j2 +++ /dev/null @@ -1,22 +0,0 @@ -[Unit] -Description=Database container -{% if multi_instance == 'true' %} -Requires=database.service -After=database.service -{% endif %} -Requires=docker.service -After=docker.service -After=rc-local.service -StartLimitIntervalSec=1200 -StartLimitBurst=3 - -[Service] -User=root -ExecStartPre=/usr/bin/{{docker_container_name}}.sh start{% if multi_instance == 'true' %} %i{% endif %} -ExecStart=/usr/bin/{{docker_container_name}}.sh wait{% if multi_instance == 'true' %} %i{% endif %} -ExecStop=/usr/bin/{{docker_container_name}}.sh stop{% if multi_instance == 'true' %} %i{% endif %} -Restart=always -RestartSec=30 - -[Install] -WantedBy=multi-user.target diff --git a/files/build_templates/per_namespace/lldp.service.j2 b/files/build_templates/per_namespace/lldp.service.j2 deleted file mode 100644 index b48675b03202..000000000000 --- a/files/build_templates/per_namespace/lldp.service.j2 +++ /dev/null @@ -1,22 +0,0 @@ -[Unit] -Description=LLDP container -Requires=database{% if multi_instance == 'true' %}@%i{% endif %}.service -After=database{% if multi_instance == 'true' %}@%i{% endif %}.service -After=swss{% if multi_instance == 'true' %}@%i{% endif %}.service -After=syncd{% if multi_instance == 'true' %}@%i{% endif %}.service -Requires=updategraph.service -After=updategraph.service -Before=ntp-config.service -StartLimitIntervalSec=1200 -StartLimitBurst=3 - -[Service] -User={{ sonicadmin_user }} -ExecStartPre=/usr/bin/{{docker_container_name}}.sh start{% if multi_instance == 'true' %} %i{% endif %} -ExecStart=/usr/bin/{{docker_container_name}}.sh wait{% if multi_instance == 'true' %} %i{% endif %} -ExecStop=/usr/bin/{{docker_container_name}}.sh stop{% if multi_instance == 'true' %} %i{% endif %} -Restart=always -RestartSec=30 - -[Install] -WantedBy=multi-user.target diff --git a/files/build_templates/per_namespace/swss.service.j2 b/files/build_templates/per_namespace/swss.service.j2 deleted file mode 100644 index 53d6b4497df7..000000000000 --- a/files/build_templates/per_namespace/swss.service.j2 +++ /dev/null @@ -1,31 +0,0 @@ -[Unit] -Description=switch state service -Requires=database{% if multi_instance == 'true' %}@%i{% endif %}.service -After=database{% if multi_instance == 'true' %}@%i{% endif %}.service -{% if multi_instance == 'true' and sonic_asic_platform == 'vs' %} -Requires=topology.service -After=topology.service -{% endif %} -{% if sonic_asic_platform == 'broadcom' %} -Requires=opennsl-modules.service -{% elif sonic_asic_platform == 'nephos' %} -Requires=nps-modules-4.9.0-11-2-amd64.service -{% endif %} -Requires=updategraph.service -After=updategraph.service -After=interfaces-config.service -Before=ntp-config.service -StartLimitIntervalSec=1200 -StartLimitBurst=3 - -[Service] -User=root -Environment=sonic_asic_platform={{ sonic_asic_platform }} -ExecStartPre=/usr/local/bin/swss.sh start{% if multi_instance == 'true' %} %i{% endif %} -ExecStart=/usr/local/bin/swss.sh wait{% if multi_instance == 'true' %} %i{% endif %} -ExecStop=/usr/local/bin/swss.sh stop{% if multi_instance == 'true' %} %i{% endif %} -Restart=always -RestartSec=30 - -[Install] -WantedBy=multi-user.target diff --git a/files/build_templates/per_namespace/syncd.service.j2 b/files/build_templates/per_namespace/syncd.service.j2 deleted file mode 100644 index b2922e0d12b6..000000000000 --- a/files/build_templates/per_namespace/syncd.service.j2 +++ /dev/null @@ -1,33 +0,0 @@ -[Unit] -Description=syncd service -Requires=database{% if multi_instance == 'true' %}@%i{% endif %}.service -After=database{% if multi_instance == 'true' %}@%i{% endif %}.service -After=swss{% if multi_instance == 'true' %}@%i{% endif %}.service -{% if multi_instance == 'true' and sonic_asic_platform == 'vs' %} -Requires=topology.service -After=topology.service -{% endif %} -{% if sonic_asic_platform == 'broadcom' %} -Requires=opennsl-modules.service -After=opennsl-modules.service -{% elif sonic_asic_platform == 'nephos' %} -Requires=nps-modules-4.9.0-11-2-amd64.service -After=nps-modules-4.9.0-11-2-amd64.service -{% endif %} -Requires=updategraph.service -After=updategraph.service -After=interfaces-config.service -Before=ntp-config.service - -[Service] -User=root -Environment=sonic_asic_platform={{ sonic_asic_platform }} -ExecStartPre=/usr/local/bin/syncd.sh start{% if multi_instance == 'true' %} %i{% endif %} -ExecStart=/usr/local/bin/syncd.sh wait{% if multi_instance == 'true' %} %i{% endif %} -ExecStop=/usr/local/bin/syncd.sh stop{% if multi_instance == 'true' %} %i{% endif %} -{% if sonic_asic_platform == 'mellanox' %} -TimeoutStartSec=150 -{% endif %} - -[Install] -WantedBy=multi-user.target diff --git a/files/build_templates/per_namespace/teamd.service.j2 b/files/build_templates/per_namespace/teamd.service.j2 deleted file mode 100644 index 092f9d2ebde2..000000000000 --- a/files/build_templates/per_namespace/teamd.service.j2 +++ /dev/null @@ -1,19 +0,0 @@ -[Unit] -Description=TEAMD container -After=swss{% if multi_instance == 'true' %}@%i{% endif %}.service -Requires=updategraph.service -After=updategraph.service -Before=ntp-config.service -StartLimitIntervalSec=1200 -StartLimitBurst=3 - -[Service] -User={{ sonicadmin_user }} -ExecStartPre=/usr/bin/{{docker_container_name}}.sh start{% if multi_instance == 'true' %} %i{% endif %} -ExecStart=/usr/bin/{{docker_container_name}}.sh wait{% if multi_instance == 'true' %} %i{% endif %} -ExecStop=/usr/bin/{{docker_container_name}}.sh stop{% if multi_instance == 'true' %} %i{% endif %} -Restart=always -RestartSec=30 - -[Install] -WantedBy=multi-user.target diff --git a/files/build_templates/single_instance/bgp.service.j2 b/files/build_templates/single_instance/bgp.service.j2 new file mode 100644 index 000000000000..fdf9d9c78c04 --- /dev/null +++ b/files/build_templates/single_instance/bgp.service.j2 @@ -0,0 +1,18 @@ +[Unit] +Description=BGP container +Requires=updategraph.service +After=updategraph.service +Before=ntp-config.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 + +[Service] +User={{ sonicadmin_user }} +ExecStartPre=/usr/bin/{{docker_container_name}}.sh start +ExecStart=/usr/bin/{{docker_container_name}}.sh wait +ExecStop=/usr/bin/{{docker_container_name}}.sh stop +Restart=always +RestartSec=30 + +[Install] +WantedBy=multi-user.target diff --git a/files/build_templates/single_instance/database.service.j2 b/files/build_templates/single_instance/database.service.j2 new file mode 100644 index 000000000000..fd0063195e31 --- /dev/null +++ b/files/build_templates/single_instance/database.service.j2 @@ -0,0 +1,18 @@ +[Unit] +Description=Database container +Requires=docker.service +After=docker.service +After=rc-local.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 + +[Service] +User=root +ExecStartPre=/usr/bin/{{docker_container_name}}.sh start +ExecStart=/usr/bin/{{docker_container_name}}.sh wait +ExecStop=/usr/bin/{{docker_container_name}}.sh stop +Restart=always +RestartSec=30 + +[Install] +WantedBy=multi-user.target diff --git a/files/build_templates/single_instance/swss.service.j2 b/files/build_templates/single_instance/swss.service.j2 new file mode 100644 index 000000000000..44206b08ebce --- /dev/null +++ b/files/build_templates/single_instance/swss.service.j2 @@ -0,0 +1,25 @@ +[Unit] +Description=switch state service +Requires=database.service updategraph.service +{% if sonic_asic_platform == 'broadcom' %} +Requires=opennsl-modules.service +{% elif sonic_asic_platform == 'nephos' %} +Requires=nps-modules-4.9.0-11-2-amd64.service +{% endif %} +After=database.service updategraph.service +After=interfaces-config.service +Before=ntp-config.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 + +[Service] +User=root +Environment=sonic_asic_platform={{ sonic_asic_platform }} +ExecStartPre=/usr/local/bin/swss.sh start +ExecStart=/usr/local/bin/swss.sh wait +ExecStop=/usr/local/bin/swss.sh stop +Restart=always +RestartSec=30 + +[Install] +WantedBy=multi-user.target diff --git a/files/build_templates/single_instance/syncd.service.j2 b/files/build_templates/single_instance/syncd.service.j2 new file mode 100644 index 000000000000..7a7d27114b07 --- /dev/null +++ b/files/build_templates/single_instance/syncd.service.j2 @@ -0,0 +1,30 @@ +[Unit] +Description=syncd service +Requires=database.service updategraph.service +{% if sonic_asic_platform == 'broadcom' %} +Requires=opennsl-modules.service +{% elif sonic_asic_platform == 'nephos' %} +Requires=nps-modules-4.9.0-11-2-amd64.service +{% endif %} +After=database.service updategraph.service +After=interfaces-config.service +{% if sonic_asic_platform == 'broadcom' %} +After=opennsl-modules.service +{% elif sonic_asic_platform == 'nephos' %} +After=nps-modules-4.9.0-11-2-amd64.service +{% endif %} +After=swss.service +Before=ntp-config.service + +[Service] +User=root +Environment=sonic_asic_platform={{ sonic_asic_platform }} +ExecStartPre=/usr/local/bin/syncd.sh start +ExecStart=/usr/local/bin/syncd.sh wait +ExecStop=/usr/local/bin/syncd.sh stop +{% if sonic_asic_platform == 'mellanox' %} +TimeoutStartSec=150 +{% endif %} + +[Install] +WantedBy=multi-user.target diff --git a/files/build_templates/single_instance/teamd.service.j2 b/files/build_templates/single_instance/teamd.service.j2 new file mode 100644 index 000000000000..be0521a4fbec --- /dev/null +++ b/files/build_templates/single_instance/teamd.service.j2 @@ -0,0 +1,18 @@ +[Unit] +Description=TEAMD container +Requires=updategraph.service +After=updategraph.service swss.service +Before=ntp-config.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 + +[Service] +User={{ sonicadmin_user }} +ExecStartPre=/usr/bin/{{docker_container_name}}.sh start +ExecStart=/usr/bin/{{docker_container_name}}.sh wait +ExecStop=/usr/bin/{{docker_container_name}}.sh stop +Restart=always +RestartSec=30 + +[Install] +WantedBy=multi-user.target diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index abc5361910be..66391c7bac8d 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -284,7 +284,6 @@ j2 files/build_templates/init_cfg.json.j2 | sudo tee $FILESYSTEM_ROOT/etc/sonic/ # Copy config-setup script and service file j2 files/build_templates/config-setup.service.j2 | sudo tee $FILESYSTEM_ROOT/etc/systemd/system/config-setup.service sudo cp $IMAGE_CONFIGS/config-setup/config-setup $FILESYSTEM_ROOT/usr/bin/config-setup -echo "config-setup.service" | sudo tee -a $GENERATED_SERVICE_FILE sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable config-setup.service # Copy SNMP configuration files @@ -431,9 +430,6 @@ sudo LANG=C chroot $FILESYSTEM_ROOT umount -lf /sys sudo LANG=C cp $SCRIPTS_DIR/swss.sh $FILESYSTEM_ROOT/usr/local/bin/swss.sh sudo LANG=C cp $SCRIPTS_DIR/syncd.sh $FILESYSTEM_ROOT/usr/local/bin/syncd.sh -# Copy sonic-netns-exec script -sudo LANG=C cp $SCRIPTS_DIR/sonic-netns-exec $FILESYSTEM_ROOT/usr/bin/sonic-netns-exec - # Copy systemd timer configuration # It implements delayed start of services sudo cp $BUILD_TEMPLATES/snmp.timer $FILESYSTEM_ROOT/etc/systemd/system/ diff --git a/files/image_config/topology/topology.sh b/files/image_config/topology/topology.sh index dde7da247484..7013920ec016 100755 --- a/files/image_config/topology/topology.sh +++ b/files/image_config/topology/topology.sh @@ -6,16 +6,18 @@ # start() { - TOPOLOGY_SCRIPT="topology.sh" - PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` - HWSKU=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hwsku"]'` - /usr/share/sonic/device/$PLATFORM/$HWSKU/$TOPOLOGY_SCRIPT start + DB_FIRST_INSTANCE="/var/run/redis0/redis.sock" + TOPOLOGY_SCRIPT="topology.sh" + PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform -s $DB_FIRST_INSTANCE` + HWSKU=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hwsku"]' -s $DB_FIRST_INSTANCE` + /usr/share/sonic/device/$PLATFORM/$HWSKU/$TOPOLOGY_SCRIPT start } stop() { - TOPOLOGY_SCRIPT="topology.sh" - PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` - HWSKU=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hwsku"]'` - usr/share/sonic/device/$PLATFORM/$HWSKU/$TOPOLOGY_SCRIPT stop + DB_FIRST_INSTANCE="/var/run/redis0/redis.sock" + TOPOLOGY_SCRIPT="topology.sh" + PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform -s $DB_FIRST_INSTANCE` + HWSKU=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hwsku"]' -s $DB_FIRST_INSTANCE` + /usr/share/sonic/device/$PLATFORM/$HWSKU/$TOPOLOGY_SCRIPT stop } case "$1" in diff --git a/files/scripts/sonic-netns-exec b/files/scripts/sonic-netns-exec deleted file mode 100755 index 166a2c7e4a2f..000000000000 --- a/files/scripts/sonic-netns-exec +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash -# Wrapper to execute any command in a specific -# network namespace. -# Usage: -# sonic-netns-exec -NS="$1" -shift -if [ "$NS" != "" ]; then - ip netns exec $NS $@ -else - $@ -fi diff --git a/files/scripts/swss.sh b/files/scripts/swss.sh index 360e331f3636..a14d03e40f50 100755 --- a/files/scripts/swss.sh +++ b/files/scripts/swss.sh @@ -1,7 +1,10 @@ #!/bin/bash -DEPENDENT="radv dhcp_relay" -MULTI_INST_DEPENDENT="teamd" +SERVICE="swss" +PEER="syncd" +DEPENDENT="teamd radv dhcp_relay" +DEBUGLOG="/tmp/swss-syncd-debug.log" +LOCKFILE="/tmp/swss-syncd-lock" function debug() { @@ -11,25 +14,25 @@ function debug() function lock_service_state_change() { - debug "Locking ${LOCKFILE} from ${SERVICE}$DEV service" + debug "Locking ${LOCKFILE} from ${SERVICE} service" exec {LOCKFD}>${LOCKFILE} /usr/bin/flock -x ${LOCKFD} trap "/usr/bin/flock -u ${LOCKFD}" 0 2 3 15 - debug "Locked ${LOCKFILE} (${LOCKFD}) from ${SERVICE}$DEV service" + debug "Locked ${LOCKFILE} (${LOCKFD}) from ${SERVICE} service" } function unlock_service_state_change() { - debug "Unlocking ${LOCKFILE} (${LOCKFD}) from ${SERVICE}$DEV service" + debug "Unlocking ${LOCKFILE} (${LOCKFD}) from ${SERVICE} service" /usr/bin/flock -u ${LOCKFD} } function check_warm_boot() { - SYSTEM_WARM_START=`sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` - SERVICE_WARM_START=`sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` + SYSTEM_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` + SERVICE_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` if [[ x"$SYSTEM_WARM_START" == x"true" ]] || [[ x"$SERVICE_WARM_START" == x"true" ]]; then WARM_BOOT="true" else @@ -40,7 +43,7 @@ function check_warm_boot() function validate_restore_count() { if [[ x"$WARM_BOOT" == x"true" ]]; then - RESTORE_COUNT=`sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB hget "WARM_RESTART_TABLE|orchagent" restore_count` + RESTORE_COUNT=`sonic-db-cli STATE_DB hget "WARM_RESTART_TABLE|orchagent" restore_count` # We have to make sure db data has not been flushed. if [[ -z "$RESTORE_COUNT" ]]; then WARM_BOOT="false" @@ -51,10 +54,10 @@ function validate_restore_count() function wait_for_database_service() { # Wait for redis server start before database clean - /usr/bin/docker exec database$DEV ping_pong_db_insts + /usr/bin/docker exec database ping_pong_db_insts # Wait for configDB initialization - until [[ $(sonic-netns-exec "$NET_NS" sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; + until [[ $(sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; do sleep 1; done } @@ -64,7 +67,7 @@ function wait_for_database_service() # $2 the string of a list of table prefixes function clean_up_tables() { - sonic-netns-exec "$NET_NS" sonic-db-cli $1 EVAL " + sonic-db-cli $1 EVAL " local tables = {$2} for i = 1, table.getn(tables) do local matches = redis.call('KEYS', tables[i]) @@ -78,48 +81,25 @@ start_peer_and_dependent_services() { check_warm_boot if [[ x"$WARM_BOOT" != x"true" ]]; then - if [[ ! -z $DEV ]]; then - /bin/systemctl start ${PEER}@$DEV - else - /bin/systemctl start ${PEER} - fi + /bin/systemctl start ${PEER} for dep in ${DEPENDENT}; do /bin/systemctl start ${dep} done - for dep in ${MULTI_INST_DEPENDENT}; do - if [[ ! -z $DEV ]]; then - /bin/systemctl start ${dep}@$DEV - else - /bin/systemctl start ${dep} - fi - done fi } stop_peer_and_dependent_services() { # if warm start enabled or peer lock exists, don't stop peer service docker if [[ x"$WARM_BOOT" != x"true" ]]; then - if [[ ! -z $DEV ]]; then - /bin/systemctl stop ${PEER}@$DEV - else - /bin/systemctl stop ${PEER} - fi + /bin/systemctl stop ${PEER} for dep in ${DEPENDENT}; do /bin/systemctl stop ${dep} done - for dep in ${MULTI_INST_DEPENDENT}; do - if [[ ! -z $DEV ]]; then - /bin/systemctl stop ${dep}@$DEV - else - /bin/systemctl stop ${dep} - fi - done - fi } start() { - debug "Starting ${SERVICE}$DEV service..." + debug "Starting ${SERVICE} service..." lock_service_state_change @@ -127,21 +107,21 @@ start() { check_warm_boot validate_restore_count - debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}." + debug "Warm boot flag: ${SERVICE} ${WARM_BOOT}." # Don't flush DB during warm boot if [[ x"$WARM_BOOT" != x"true" ]]; then debug "Flushing APP, ASIC, COUNTER, CONFIG, and partial STATE databases ..." - sonic-netns-exec "$NET_NS" sonic-db-cli APPL_DB FLUSHDB - sonic-netns-exec "$NET_NS" sonic-db-cli ASIC_DB FLUSHDB - sonic-netns-exec "$NET_NS" sonic-db-cli COUNTERS_DB FLUSHDB - sonic-netns-exec "$NET_NS" sonic-db-cli FLEX_COUNTER_DB FLUSHDB + sonic-db-cli APPL_DB FLUSHDB + sonic-db-cli ASIC_DB FLUSHDB + sonic-db-cli COUNTERS_DB FLUSHDB + sonic-db-cli FLEX_COUNTER_DB FLUSHDB clean_up_tables STATE_DB "'PORT_TABLE*', 'MGMT_PORT_TABLE*', 'VLAN_TABLE*', 'VLAN_MEMBER_TABLE*', 'LAG_TABLE*', 'LAG_MEMBER_TABLE*', 'INTERFACE_TABLE*', 'MIRROR_SESSION*', 'VRF_TABLE*', 'FDB_TABLE*'" fi # start service docker - /usr/bin/${SERVICE}.sh start $DEV - debug "Started ${SERVICE}$DEV service..." + /usr/bin/${SERVICE}.sh start + debug "Started ${SERVICE} service..." # Unlock has to happen before reaching out to peer service unlock_service_state_change @@ -154,11 +134,7 @@ wait() { # NOTE: This assumes Docker containers share the same names as their # corresponding services for SECS in {1..60}; do - if [[ ! -z $DEV ]]; then - RUNNING=$(docker inspect -f '{{.State.Running}}' ${PEER}$DEV) - else - RUNNING=$(docker inspect -f '{{.State.Running}}' ${PEER}) - fi + RUNNING=$(docker inspect -f '{{.State.Running}}' ${PEER}) if [[ x"$RUNNING" == x"true" ]]; then break else @@ -168,24 +144,20 @@ wait() { # NOTE: This assumes Docker containers share the same names as their # corresponding services - if [[ ! -z $DEV ]]; then - /usr/bin/docker-wait-any ${SERVICE}$DEV ${PEER}$DEV - else - /usr/bin/docker-wait-any ${SERVICE} ${PEER} - fi + /usr/bin/docker-wait-any ${SERVICE} ${PEER} } stop() { - debug "Stopping ${SERVICE}$DEV service..." + debug "Stopping ${SERVICE} service..." [[ -f ${LOCKFILE} ]] || /usr/bin/touch ${LOCKFILE} lock_service_state_change check_warm_boot - debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}." + debug "Warm boot flag: ${SERVICE} ${WARM_BOOT}." - /usr/bin/${SERVICE}.sh stop $DEV - debug "Stopped ${SERVICE}$DEV service..." + /usr/bin/${SERVICE}.sh stop + debug "Stopped ${SERVICE} service..." # Flush FAST_REBOOT table when swss needs to stop. The only # time when this would take effect is when fast-reboot @@ -200,18 +172,6 @@ stop() { stop_peer_and_dependent_services } -DEV=$2 - -SERVICE="swss" -PEER="syncd" -DEBUGLOG="/tmp/swss-syncd-debug$DEV.log" -LOCKFILE="/tmp/swss-syncd-lock$DEV" -if [ "$DEV" ]; then - NET_NS="asic$DEV" #name of the network namespace -else - NET_NS="" -fi - case "$1" in start|wait|stop) $1 diff --git a/files/scripts/syncd.sh b/files/scripts/syncd.sh index 9847cfec9406..4b47e7ad4c45 100755 --- a/files/scripts/syncd.sh +++ b/files/scripts/syncd.sh @@ -1,5 +1,9 @@ #!/bin/bash +SERVICE="syncd" +PEER="swss" +DEBUGLOG="/tmp/swss-syncd-debug.log" +LOCKFILE="/tmp/swss-syncd-lock" function debug() { @@ -9,25 +13,25 @@ function debug() function lock_service_state_change() { - debug "Locking ${LOCKFILE} from ${SERVICE}$DEV service" + debug "Locking ${LOCKFILE} from ${SERVICE} service" exec {LOCKFD}>${LOCKFILE} /usr/bin/flock -x ${LOCKFD} trap "/usr/bin/flock -u ${LOCKFD}" 0 2 3 15 - debug "Locked ${LOCKFILE} (${LOCKFD}) from ${SERVICE}$DEV service" + debug "Locked ${LOCKFILE} (${LOCKFD}) from ${SERVICE} service" } function unlock_service_state_change() { - debug "Unlocking ${LOCKFILE} (${LOCKFD}) from ${SERVICE}$DEV service" + debug "Unlocking ${LOCKFILE} (${LOCKFD}) from ${SERVICE} service" /usr/bin/flock -u ${LOCKFD} } function check_warm_boot() { - SYSTEM_WARM_START=`sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` - SERVICE_WARM_START=`sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` + SYSTEM_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` + SERVICE_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` # SYSTEM_WARM_START could be empty, always make WARM_BOOT meaningful. if [[ x"$SYSTEM_WARM_START" == x"true" ]] || [[ x"$SERVICE_WARM_START" == x"true" ]]; then WARM_BOOT="true" @@ -39,10 +43,10 @@ function check_warm_boot() function wait_for_database_service() { # Wait for redis server start before database clean - /usr/bin/docker exec database$DEV ping_pong_db_insts + /usr/bin/docker exec database ping_pong_db_insts # Wait for configDB initialization - until [[ $(sonic-netns-exec "$NET_NS" sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; + until [[ $(sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; do sleep 1; done } @@ -59,7 +63,7 @@ function getBootType() ;; *SONIC_BOOT_TYPE=fast*|*fast-reboot*) # check that the key exists - if [[ $(sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB GET "FAST_REBOOT|system") == "1" ]]; then + if [[ $(sonic-db-cli STATE_DB GET "FAST_REBOOT|system") == "1" ]]; then TYPE='fast' else TYPE='cold' @@ -72,7 +76,7 @@ function getBootType() } start() { - debug "Starting ${SERVICE}$DEV service..." + debug "Starting ${SERVICE} service..." lock_service_state_change @@ -81,7 +85,7 @@ start() { wait_for_database_service check_warm_boot - debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}." + debug "Warm boot flag: ${SERVICE} ${WARM_BOOT}." if [[ x"$WARM_BOOT" == x"true" ]]; then # Leave a mark for syncd scripts running inside docker. @@ -123,7 +127,7 @@ start() { fi # start service docker - /usr/bin/${SERVICE}.sh start $DEV + /usr/bin/${SERVICE}.sh start debug "Started ${SERVICE} service..." unlock_service_state_change @@ -135,15 +139,15 @@ wait() { /bin/systemctl start pmon debug "Started pmon service" fi - /usr/bin/${SERVICE}.sh wait $DEV + /usr/bin/${SERVICE}.sh wait } stop() { - debug "Stopping ${SERVICE}$DEV service..." + debug "Stopping ${SERVICE} service..." lock_service_state_change check_warm_boot - debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}." + debug "Warm boot flag: ${SERVICE} ${WARM_BOOT}." if [[ x"$WARM_BOOT" == x"true" ]]; then TYPE=warm @@ -159,19 +163,19 @@ stop() { if [[ x$sonic_asic_platform != x"mellanox" ]] || [[ x$TYPE != x"cold" ]]; then debug "${TYPE} shutdown syncd process ..." - /usr/bin/docker exec -i syncd$DEV /usr/bin/syncd_request_shutdown --${TYPE} + /usr/bin/docker exec -i syncd /usr/bin/syncd_request_shutdown --${TYPE} # wait until syncd quits gracefully - while docker top syncd$DEV | grep -q /usr/bin/syncd; do + while docker top syncd | grep -q /usr/bin/syncd; do sleep 0.1 done - /usr/bin/docker exec -i syncd$DEV /bin/sync + /usr/bin/docker exec -i syncd /bin/sync debug "Finished ${TYPE} shutdown syncd process ..." fi - /usr/bin/${SERVICE}.sh stop $DEV - debug "Stopped ${SERVICE}$DEV service..." + /usr/bin/${SERVICE}.sh stop + debug "Stopped ${SERVICE} service..." # platform specific tasks @@ -188,19 +192,6 @@ stop() { unlock_service_state_change } -OP=$1 -DEV=$2 - -SERVICE="syncd" -PEER="swss" -DEBUGLOG="/tmp/swss-syncd-debug$DEV.log" -LOCKFILE="/tmp/swss-syncd-lock$DEV" -if [ "$DEV" ]; then - NET_NS="asic$DEV" #name of the network namespace -else - NET_NS="" -fi - case "$1" in start|wait|stop) $1 diff --git a/platform/vs/sonic_multiasic.xml b/platform/vs/sonic_multiasic.xml index b571b5122a52..b406bfd40475 100644 --- a/platform/vs/sonic_multiasic.xml +++ b/platform/vs/sonic_multiasic.xml @@ -1,7 +1,7 @@ sonic 8 - 8 + 2 /machine diff --git a/rules/docker-fpm-frr.mk b/rules/docker-fpm-frr.mk index 45a755a9289f..517aff3ea9fc 100644 --- a/rules/docker-fpm-frr.mk +++ b/rules/docker-fpm-frr.mk @@ -24,6 +24,7 @@ SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_FPM_FRR_DBG) $(DOCKER_FPM_FRR)_CONTAINER_NAME = bgp $(DOCKER_FPM_FRR)_RUN_OPT += --privileged -t $(DOCKER_FPM_FRR)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro +$(DOCKER_FPM_FRR)_RUN_OPT += -v /etc/sonic/frr:/etc/frr:rw $(DOCKER_FPM_FRR)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/slave.mk b/slave.mk index 9a154699cc20..16c4d4ef6a8b 100644 --- a/slave.mk +++ b/slave.mk @@ -667,7 +667,6 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export platform_common_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_COMMON_PY2))" export redis_dump_load_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(REDIS_DUMP_LOAD_PY2))" export install_debug_image="$(INSTALL_DEBUG_TOOLS)" - export multi_instance="false" $(foreach docker, $($*_DOCKERS),\ export docker_image="$(docker)" @@ -678,21 +677,18 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ if [ -f files/build_templates/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 ]; then j2 files/build_templates/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service - - # Set the flag GLOBAL for all the global system-wide dockers. - $(if $(shell ls files/build_templates/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 2>/dev/null),\ - $(eval $(docker:-dbg.gz=.gz)_GLOBAL = yes) - ) fi - # Any service template, inside instance directory, will be used to generate .service and @.service file. - if [ -f files/build_templates/per_namespace/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 ]; then - export multi_instance="true" - j2 files/build_templates/per_namespace/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME)@.service - $(if $(shell ls files/build_templates/per_namespace/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 2>/dev/null),\ + + if [ -f files/build_templates/multi_instance/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME)@.service.j2 ]; then + j2 files/build_templates/multi_instance/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME)@.service.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME)@.service + + # performs the same check as the elif above, except with make commands so eval behaves properly + $(if $(shell ls files/build_templates/multi_instance/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME)@.service.j2 2>/dev/null),\ $(eval $(docker:-dbg.gz=.gz)_TEMPLATE = yes) - ) - export multi_instance="false" - j2 files/build_templates/per_namespace/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service + ) + fi + if [ -f files/build_templates/single_instance/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 ]; then + j2 files/build_templates/single_instance/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service fi j2 files/build_templates/docker_image_ctl.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).sh chmod +x $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).sh @@ -703,12 +699,8 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ # Marks template services with an "@" according to systemd convention # If the $($docker)_TEMPLATE) variable is set, the service will be treated as a template - # If the $($docker)_GLOBAL) and $($docker)_TEMPLATE) variables are set the service will be added both as a global and template service. $(foreach docker, $($*_DOCKERS),\ $(if $($(docker:-dbg.gz=.gz)_TEMPLATE),\ - $(if $($(docker:-dbg.gz=.gz)_GLOBAL),\ - $(eval SERVICES += "$(addsuffix .service, $($(docker:-dbg.gz=.gz)_CONTAINER_NAME))")\ - )\ $(eval SERVICES += "$(addsuffix @.service, $($(docker:-dbg.gz=.gz)_CONTAINER_NAME))"),\ $(eval SERVICES += "$(addsuffix .service, $($(docker:-dbg.gz=.gz)_CONTAINER_NAME))") ) From 0a4f164754ff0e7ae955db8091423aa9f623568b Mon Sep 17 00:00:00 2001 From: zhenggen-xu Date: Sat, 4 Apr 2020 22:52:34 -0700 Subject: [PATCH 143/178] [Seastone] Add new HWSKU for 48x50G+8x40G (#4156) Add the port_config.ini and sai.profile, leveraging the same bcm file. Signed-off-by: Zhenggen Xu --- .../Seastone-DX010-50-50-40/port_config.ini | 57 +++++++++++++++++++ .../Seastone-DX010-50-50-40/sai.profile | 1 + 2 files changed, 58 insertions(+) create mode 100644 device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-50-50-40/port_config.ini create mode 100644 device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-50-50-40/sai.profile diff --git a/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-50-50-40/port_config.ini b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-50-50-40/port_config.ini new file mode 100644 index 000000000000..4bc2ce344039 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-50-50-40/port_config.ini @@ -0,0 +1,57 @@ +# name lanes alias index speed +Ethernet0 65,66 Eth1/1 1 50000 +Ethernet2 67,68 Eth1/2 1 50000 +Ethernet4 69,70 Eth2/1 2 50000 +Ethernet6 71,72 Eth2/2 2 50000 +Ethernet8 73,74 Eth3/1 3 50000 +Ethernet10 75,76 Eth3/2 3 50000 +Ethernet12 77,78 Eth4/1 4 50000 +Ethernet14 79,80 Eth4/2 4 50000 +Ethernet16 33,34 Eth5/1 5 50000 +Ethernet18 35,36 Eth5/2 5 50000 +Ethernet20 37,38 Eth6/1 6 50000 +Ethernet22 39,40 Eth6/2 6 50000 +Ethernet24 41,42 Eth7/1 7 50000 +Ethernet26 43,44 Eth7/2 7 50000 +Ethernet28 45,46 Eth8/1 8 50000 +Ethernet30 47,48 Eth8/2 8 50000 +Ethernet32 49,50 Eth9/1 9 50000 +Ethernet34 51,52 Eth9/2 9 50000 +Ethernet36 53,54 Eth10/1 10 50000 +Ethernet38 55,56 Eth10/2 10 50000 +Ethernet40 57,58 Eth11/1 11 50000 +Ethernet42 59,60 Eth11/2 11 50000 +Ethernet44 61,62 Eth12/1 12 50000 +Ethernet46 63,64 Eth12/2 12 50000 +Ethernet48 81,82 Eth13/1 13 50000 +Ethernet50 83,84 Eth13/2 13 50000 +Ethernet52 85,86 Eth14/1 14 50000 +Ethernet54 87,88 Eth14/2 14 50000 +Ethernet56 89,90 Eth15/1 15 50000 +Ethernet58 91,92 Eth15/2 15 50000 +Ethernet60 93,94 Eth16/1 16 50000 +Ethernet62 95,96 Eth16/2 16 50000 +Ethernet64 97,98 Eth17/1 17 50000 +Ethernet66 99,100 Eth17/2 17 50000 +Ethernet68 101,102 Eth18/1 18 50000 +Ethernet70 103,104 Eth18/2 18 50000 +Ethernet72 105,106 Eth19/1 19 50000 +Ethernet74 107,108 Eth19/2 19 50000 +Ethernet76 109,110 Eth20/1 20 50000 +Ethernet78 111,112 Eth20/2 20 50000 +Ethernet80 1,2 Eth21/1 21 50000 +Ethernet82 3,4 Eth21/2 21 50000 +Ethernet84 5,6 Eth22/1 22 50000 +Ethernet86 7,8 Eth22/2 22 50000 +Ethernet88 9,10 Eth23/1 23 50000 +Ethernet90 11,12 Eth23/2 23 50000 +Ethernet92 13,14 Eth24/1 24 50000 +Ethernet94 15,16 Eth24/2 24 50000 +Ethernet96 17,18,19,20 Eth25 25 40000 +Ethernet100 21,22,23,24 Eth26 26 40000 +Ethernet104 25,26,27,28 Eth27 27 40000 +Ethernet108 29,30,31,32 Eth28 28 40000 +Ethernet112 113,114,115,116 Eth29 29 40000 +Ethernet116 117,118,119,120 Eth30 30 40000 +Ethernet120 121,122,123,124 Eth31 31 40000 +Ethernet124 125,126,127,128 Eth32 32 40000 diff --git a/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-50-50-40/sai.profile b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-50-50-40/sai.profile new file mode 100644 index 000000000000..7342ae8002e8 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/Seastone-DX010-50-50-40/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/platform/th-seastone-dx010-config-flex-all.bcm From 63450d7d21a5a2c59d00ae88e16917d3e57df8c6 Mon Sep 17 00:00:00 2001 From: CharlieChenEC <49221644+CharlieChenEC@users.noreply.github.com> Date: Sat, 4 Apr 2020 03:48:47 +0800 Subject: [PATCH 144/178] Fix the error that 'sensord' daemon cannot be spawn correctly in pmon container (#4354) - This commit fixes the issue #4021 (Sensord not able to start up on both master and 201911 branches) - Add the new patch file for "lm-sensors" to perform dh_installinit to include sensord.init in the packed deb. So that the missing init script file for 'sensord' will be included in the created 'sensord' deb. Signed-off-by: Charlie Chen --- ...dh_installinit-to-include-sensord.in.patch | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/lm-sensors/0002-Patch-to-peform-dh_installinit-to-include-sensord.in.patch diff --git a/src/lm-sensors/0002-Patch-to-peform-dh_installinit-to-include-sensord.in.patch b/src/lm-sensors/0002-Patch-to-peform-dh_installinit-to-include-sensord.in.patch new file mode 100644 index 000000000000..6d3e279ea5e7 --- /dev/null +++ b/src/lm-sensors/0002-Patch-to-peform-dh_installinit-to-include-sensord.in.patch @@ -0,0 +1,23 @@ +From b11fd3d516b62c01513d289bc901820aa150c63e Mon Sep 17 00:00:00 2001 +From: Charlie Chen +Date: Wed, 1 Apr 2020 06:59:06 +0000 +Subject: Patch to peform dh_installinit to include sensord.install in the + packed deb + +Signed-off-by: Charlie Chen +--- + debian/rules | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/lm-sensors/lm-sensors-3.4.0/debian/rules b/src/lm-sensors/lm-sensors-3.4.0/debian/rules +index 5ebda06..1d77e28 100755 +--- a/src/lm-sensors/lm-sensors-3.4.0/debian/rules ++++ b/src/lm-sensors/lm-sensors-3.4.0/debian/rules +@@ -56,3 +56,4 @@ override_dh_auto_install-arch: + + override_dh_installinit-arch: + dh_installinit -plm-sensors --no-start ++ dh_installinit -psensord --no-start +-- +2.17.1 + From be0e923ca1ee733f9692233c7686d3ef6c4ea5a9 Mon Sep 17 00:00:00 2001 From: Mykola F <37578614+mykolaf@users.noreply.github.com> Date: Fri, 3 Apr 2020 22:41:37 +0300 Subject: [PATCH 145/178] [Mellanox] update eeprom.py plugin for SimX (#4364) Signed-off-by: Mykola Faryma --- .../x86_64-mlnx_msn2700-r0/plugins/eeprom.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/eeprom.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/eeprom.py index 63303c13a244..c9ae1a335421 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/eeprom.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/eeprom.py @@ -21,6 +21,7 @@ from cStringIO import StringIO from sonic_eeprom import eeprom_base from sonic_eeprom import eeprom_tlvinfo + from sonic_device_util import get_machine_info import subprocess except ImportError, e: raise ImportError (str(e) + "- required module not found") @@ -34,6 +35,14 @@ def log_error(msg): syslog.syslog(syslog.LOG_ERR, msg) syslog.closelog() + +machine_info = get_machine_info() +onie_platform = machine_info['onie_platform'] +if 'simx' in onie_platform: + platform_path = os.path.join('/usr/share/sonic/device', onie_platform) + subprocess.check_call(['/usr/bin/xxd', '-r', '-p', 'syseeprom.hex', 'syseeprom.bin'], cwd=platform_path) + CACHE_FILE = os.path.join(platform_path, 'syseeprom.bin') + class board(eeprom_tlvinfo.TlvInfoDecoder): _TLV_INFO_MAX_LEN = 256 @@ -45,12 +54,12 @@ def __init__(self, name, path, cpld_root, ro): time.sleep(1) else: break - + if not (os.path.exists(EEPROM_SYMLINK) or os.path.isfile(CACHE_FILE)): log_error("Nowhere to read syseeprom from! No symlink or cache file found") raise RuntimeError("No syseeprom symlink or cache file found") - self.eeprom_path = EEPROM_SYMLINK + self.eeprom_path = EEPROM_SYMLINK if 'simx' not in onie_platform else CACHE_FILE super(board, self).__init__(self.eeprom_path, 0, '', True) def decode_eeprom(self, e): @@ -60,3 +69,4 @@ def decode_eeprom(self, e): decode_output = sys.stdout.getvalue() sys.stdout = original_stdout print(decode_output.replace('\0', '')) + From d4bcd3305a07ae608a06e19b27ef49de51cfaa30 Mon Sep 17 00:00:00 2001 From: Abhishek Dosi Date: Mon, 6 Apr 2020 17:29:49 -0700 Subject: [PATCH 146/178] [sonic-utilities] submodule update with PR's: [watermarkstat] Fix issue of fields overwritten before display (#862) --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 1adf83c1a0df..8f08a1550afb 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 1adf83c1a0dfc888f0d4765d03fd59fac0b5ed1e +Subproject commit 8f08a1550afbfab1706bd3ec347795b36e367ed2 From a78789f15ad3c4c956c55a64bf379869298ff2e6 Mon Sep 17 00:00:00 2001 From: Abhishek Dosi Date: Mon, 6 Apr 2020 17:30:36 -0700 Subject: [PATCH 147/178] [sonic-swss] sunmodule update with PR's: [portsorch] Enable port-level buffer drop counters (#1237) [vnet]: Fix double route installation for BITMAP VNET interface (#1114) --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index 1e29fa4c200f..f61f484d5d4f 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 1e29fa4c200ff2fe3c733be7289a64740fa51d88 +Subproject commit f61f484d5d4fa82d7dd7c7634efcc22ee9bbbb7b From fb06360501a4c45b4c64f0668c4ead424f5ee1a6 Mon Sep 17 00:00:00 2001 From: Renuka Manavalan <47282725+renukamanavalan@users.noreply.github.com> Date: Wed, 8 Apr 2020 14:24:08 -0700 Subject: [PATCH 148/178] Pass image_type to build_debian.sh, so it can do any required customizations. (#4401) --- slave.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/slave.mk b/slave.mk index 16c4d4ef6a8b..16bc790f0b81 100644 --- a/slave.mk +++ b/slave.mk @@ -726,6 +726,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ DEBUG_SRC_ARCHIVE_FILE="$(DBG_SRC_ARCHIVE_FILE)" \ USERNAME="$(USERNAME)" \ PASSWORD="$(PASSWORD)" \ + IMAGE_TYPE=$($*_IMAGE_TYPE) \ ./build_debian.sh $(LOG) USERNAME="$(USERNAME)" \ From 0d5c9aadcbd5b0e8161d2c7fcd088e4e0973b00c Mon Sep 17 00:00:00 2001 From: Andriy Kokhan <43479230+akokhan@users.noreply.github.com> Date: Thu, 9 Apr 2020 08:49:45 +0300 Subject: [PATCH 149/178] [BFN] Update Barefoot SDK packages (#4397) Signed-off-by: Andriy Kokhan --- platform/barefoot/bfn-platform.mk | 2 +- platform/barefoot/bfn-sai.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/barefoot/bfn-platform.mk b/platform/barefoot/bfn-platform.mk index 622563e09853..1abbedffd6c6 100644 --- a/platform/barefoot/bfn-platform.mk +++ b/platform/barefoot/bfn-platform.mk @@ -1,4 +1,4 @@ -BFN_PLATFORM = bfnplatform_20200205_deb9.deb +BFN_PLATFORM = bfnplatform_20200407_deb9.deb $(BFN_PLATFORM)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/$(BFN_PLATFORM)" SONIC_ONLINE_DEBS += $(BFN_PLATFORM) diff --git a/platform/barefoot/bfn-sai.mk b/platform/barefoot/bfn-sai.mk index 2f2429845f5d..b58cce6fcf47 100644 --- a/platform/barefoot/bfn-sai.mk +++ b/platform/barefoot/bfn-sai.mk @@ -1,4 +1,4 @@ -BFN_SAI = bfnsdk_20200205_deb9.deb +BFN_SAI = bfnsdk_20200407_deb9.deb $(BFN_SAI)_URL = "https://github.com/barefootnetworks/sonic-release-pkgs/raw/dev/$(BFN_SAI)" $(BFN_SAI)_DEPENDS += $(LIBNL_GENL3_DEV) From c8ad045770bdf1ac37bbce68680f762694da9b6d Mon Sep 17 00:00:00 2001 From: Renuka Manavalan <47282725+renukamanavalan@users.noreply.github.com> Date: Thu, 9 Apr 2020 21:18:14 -0700 Subject: [PATCH 150/178] Update dockers with platform & SONiC version as part of name/tag. (#4337) * Include platform info in name. Get SONiC Version as parameter and use Make additional tag as optional. Avoid repetitions by using function. * Per review comments, make SONIC_VERSION optional and added some comments. * 1) Added additional params are optional 2) Handle DOCKER_IMAGE_TAG only if given 3) Use BUILD_NUMBER only if SONIC_VERSION not given 4) Tag with SONIC_VERSION if given. Current behavior is not changed, unless SONIC_VERSION is given. * Update per review comments 1) Added new args with options 2) Handle PORT possible being empty 3) Exhibit new behavior only if both version & platform are given. * Drop redundant quotes --- push_docker.sh | 91 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 64 insertions(+), 27 deletions(-) diff --git a/push_docker.sh b/push_docker.sh index 3ba9abfae5bf..3e2da08d0b83 100755 --- a/push_docker.sh +++ b/push_docker.sh @@ -1,42 +1,79 @@ +#! /bin/bash + +sonic_version="" +sonic_platform="" + +while getopts ":v:p:" opt +do + case ${opt} in + v ) # SONiC image version + sonic_version=${OPTARG} + ;; + p ) # Platform info + sonic_platform=${OPTARG} + ;; + \? ) echo "\ +Usage: [-v ] [ -p ] \ + []" + ;; + esac +done + +shift $((OPTIND -1)) + DOCKER_IMAGE_FILE=$1 REGISTRY_SERVER=$2 REGISTRY_PORT=$3 REGISTRY_USERNAME=$4 REGISTRY_PASSWD=$5 DOCKER_IMAGE_TAG=$6 +REGISTRY_SERVER_WITH_PORT=${REGISTRY_SERVER}${REGISTRY_PORT:+:$REGISTRY_PORT} -set -e -docker load < $DOCKER_IMAGE_FILE +push_it() { + # $1 - Given image name + # $2 - Remote image name -## Fetch the Jenkins build number if inside it -[ ${BUILD_NUMBER} ] || { - echo "No BUILD_NUMBER found, setting to 0." - BUILD_NUMBER="0" + docker tag $1 $2 + echo "Pushing $2" + image_sha=$(docker push $2 | sed -n "s/.*: digest: sha256:\([0-9a-f]*\).*/\\1/p") + echo "Remove $2" + docker rmi $2 || true + echo "Image sha256: $image_sha" } -## Prepare tag -docker_image_name=$(basename $DOCKER_IMAGE_FILE | cut -d. -f1) -remote_image_name=$REGISTRY_SERVER:$REGISTRY_PORT/$docker_image_name:$DOCKER_IMAGE_TAG -timestamp="$(date -u +%Y%m%d)" -build_version="${timestamp}.bld-${BUILD_NUMBER}" -build_remote_image_name=$REGISTRY_SERVER:$REGISTRY_PORT/$docker_image_name:$build_version +set -e -## Add registry information as tag, so will push as latest -## Add additional tag with build information -docker tag $docker_image_name $remote_image_name -docker tag $docker_image_name $build_remote_image_name +echo "Loading image ${DOCKER_IMAGE_FILE}" +docker load < ${DOCKER_IMAGE_FILE} ## Login the docker image registry server ## Note: user name and password are passed from command line -docker login -u $REGISTRY_USERNAME -p "$REGISTRY_PASSWD" $REGISTRY_SERVER:$REGISTRY_PORT - -## Push image to registry server -## And get the image digest SHA256 -echo "Pushing $remote_image_name" -image_sha=$(docker push $remote_image_name | sed -n "s/.*: digest: sha256:\([0-9a-f]*\).*/\\1/p") -docker rmi $remote_image_name || true -echo "Image sha256: $image_sha" -echo "Pushing $build_remote_image_name" -docker push $build_remote_image_name -docker rmi $build_remote_image_name || true +docker login -u ${REGISTRY_USERNAME} -p "${REGISTRY_PASSWD}" ${REGISTRY_SERVER_WITH_PORT} + +## Get Docker image name +docker_image_name=$(basename ${DOCKER_IMAGE_FILE} | cut -d. -f1) +remote_image_name=${REGISTRY_SERVER_WITH_PORT}/${docker_image_name} + +[ -z "${DOCKER_IMAGE_TAG}" ] || { + push_it ${docker_image_name} ${remote_image_name}:${DOCKER_IMAGE_TAG} +} + +if [ -n "${sonic_version}" ] && [ -n "${sonic_platform}" ] +then + remote_image_name=${REGISTRY_SERVER_WITH_PORT}/sonic-dockers/${sonic_platform}/${docker_image_name}:${sonic_version} + push_it ${docker_image_name} ${remote_image_name} +else + ## Fetch the Jenkins build number if inside it + [ ${BUILD_NUMBER} ] || { + echo "No BUILD_NUMBER found, setting to 0." + BUILD_NUMBER="0" + } + + timestamp="$(date -u +%Y%m%d)" + build_version="${timestamp}.bld-${BUILD_NUMBER}" + push_it ${docker_image_name} ${remote_image_name}:${build_version} +fi + docker rmi $docker_image_name || true +echo "Job completed" + From c080e80165741de444b8bf85ef083990ddfe6aa0 Mon Sep 17 00:00:00 2001 From: Srideep Date: Wed, 8 Apr 2020 03:41:56 -0600 Subject: [PATCH 151/178] [DellEMC] S5232 platform updates (#4360) FPGA driver crash fix for stale buffer in i2c transfer LED firmware load issue fix. 10G port swapfix psu/sfp bug fixes to report correct states/status of hw --- .../DellEMC-S5232f-C32/port_config.ini | 4 +- .../DellEMC-S5232f-C32/sai_preinit_cmd.soc | 2 + .../td3-s5232f-32x100G.config.bcm | 2 + .../DellEMC-S5232f-P-100G/sai_preinit_cmd.soc | 2 + .../td3-s5232f-32x100G.config.bcm | 1 + .../DellEMC-S5232f-P-10G/sai_preinit_cmd.soc | 2 + .../td3-s5232f-96x10G+8x100G.config.bcm | 1 + .../DellEMC-S5232f-P-25G/sai_preinit_cmd.soc | 2 + .../td3-s5232f-96x25G+8x100G.config.bcm | 1 + .../led_proc_init.soc | 4 +- .../plugins/psuutil.py | 86 +- .../plugins/sfputil.py | 9 +- .../pmon_daemon_control.json | 3 +- .../s5232f/modules/dell_s5232f_fpga_ocores.c | 1609 +++++++++-------- .../s5232f/scripts/platform_sensors.py | 112 +- .../s5232f/scripts/s5232f_platform.sh | 44 + 16 files changed, 1034 insertions(+), 850 deletions(-) create mode 100644 device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/sai_preinit_cmd.soc create mode 100644 device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/sai_preinit_cmd.soc create mode 100644 device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/sai_preinit_cmd.soc create mode 100644 device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/sai_preinit_cmd.soc diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/port_config.ini b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/port_config.ini index 55c8fb3dcf64..2b24bea93107 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/port_config.ini +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/port_config.ini @@ -31,5 +31,5 @@ Ethernet112 113,114,115,116 hundredGigE1/29 29 100000 Ethernet116 117,118,119,120 hundredGigE1/30 30 100000 Ethernet120 121,122,123,124 hundredGigE1/31 31 100000 Ethernet124 125,126,127,128 hundredGigE1/32 32 100000 -Ethernet128 128 tenGigE1/33 33 10000 -Ethernet129 129 tenGigE1/34 34 10000 +Ethernet128 129 tenGigE1/33 33 10000 +Ethernet129 128 tenGigE1/34 34 10000 diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/sai_preinit_cmd.soc b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/sai_preinit_cmd.soc new file mode 100644 index 000000000000..4d62900f898f --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/sai_preinit_cmd.soc @@ -0,0 +1,2 @@ +m0 load 0 0x0 /usr/share/sonic/hwsku/linkscan_led_fw.bin +m0 load 0 0x3800 /usr/share/sonic/hwsku/custom_led.bin diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/td3-s5232f-32x100G.config.bcm b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/td3-s5232f-32x100G.config.bcm index e5b61b7f1b58..9b1035a942b3 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/td3-s5232f-32x100G.config.bcm +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/td3-s5232f-32x100G.config.bcm @@ -542,3 +542,5 @@ dport_map_port_66=127 dport_map_port_130=128 mmu_init_config="TD3-DEFAULT-LOSSLESS-P3P4" +sai_preinit_cmd_file=/usr/share/sonic/hwsku/sai_preinit_cmd.soc + diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/sai_preinit_cmd.soc b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/sai_preinit_cmd.soc new file mode 100644 index 000000000000..4d62900f898f --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/sai_preinit_cmd.soc @@ -0,0 +1,2 @@ +m0 load 0 0x0 /usr/share/sonic/hwsku/linkscan_led_fw.bin +m0 load 0 0x3800 /usr/share/sonic/hwsku/custom_led.bin diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/td3-s5232f-32x100G.config.bcm b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/td3-s5232f-32x100G.config.bcm index 533e19aca1c2..e2735ded69e8 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/td3-s5232f-32x100G.config.bcm +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/td3-s5232f-32x100G.config.bcm @@ -542,3 +542,4 @@ dport_map_port_66=127 dport_map_port_130=128 mmu_init_config="TD3-DEFAULT" +sai_preinit_cmd_file=/usr/share/sonic/hwsku/sai_preinit_cmd.soc diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/sai_preinit_cmd.soc b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/sai_preinit_cmd.soc new file mode 100644 index 000000000000..4d62900f898f --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/sai_preinit_cmd.soc @@ -0,0 +1,2 @@ +m0 load 0 0x0 /usr/share/sonic/hwsku/linkscan_led_fw.bin +m0 load 0 0x3800 /usr/share/sonic/hwsku/custom_led.bin diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/td3-s5232f-96x10G+8x100G.config.bcm b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/td3-s5232f-96x10G+8x100G.config.bcm index 0da20afc2203..0346c47749cb 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/td3-s5232f-96x10G+8x100G.config.bcm +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/td3-s5232f-96x10G+8x100G.config.bcm @@ -615,3 +615,4 @@ dport_map_port_66=127 dport_map_port_130=128 mmu_init_config="TD3-DEFAULT" +sai_preinit_cmd_file=/usr/share/sonic/hwsku/sai_preinit_cmd.soc diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/sai_preinit_cmd.soc b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/sai_preinit_cmd.soc new file mode 100644 index 000000000000..4d62900f898f --- /dev/null +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/sai_preinit_cmd.soc @@ -0,0 +1,2 @@ +m0 load 0 0x0 /usr/share/sonic/hwsku/linkscan_led_fw.bin +m0 load 0 0x3800 /usr/share/sonic/hwsku/custom_led.bin diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/td3-s5232f-96x25G+8x100G.config.bcm b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/td3-s5232f-96x25G+8x100G.config.bcm index 47cbb41f4073..ca81379ae512 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/td3-s5232f-96x25G+8x100G.config.bcm +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/td3-s5232f-96x25G+8x100G.config.bcm @@ -615,3 +615,4 @@ dport_map_port_66=127 dport_map_port_130=128 mmu_init_config="TD3-DEFAULT" +sai_preinit_cmd_file=/usr/share/sonic/hwsku/sai_preinit_cmd.soc diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/led_proc_init.soc b/device/dell/x86_64-dellemc_s5232f_c3538-r0/led_proc_init.soc index 7105381ecdbc..098d5d4fd131 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/led_proc_init.soc +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/led_proc_init.soc @@ -2,8 +2,8 @@ # # #Led0 -#led stop -m0 load 0 0x0 /usr/share/sonic/hwsku/linkscan_led_fw.bin +led stop +#m0 load 0 0x0 /usr/share/sonic/hwsku/linkscan_led_fw.bin m0 load 0 0x3800 /usr/share/sonic/hwsku/custom_led.bin #led auto on led start diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/psuutil.py b/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/psuutil.py index bf10ef129626..c3e2a6d73bd0 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/psuutil.py +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/psuutil.py @@ -11,12 +11,13 @@ S5232F_MAX_PSUS = 2 -IPMI_PSU_DATA = "docker exec -it pmon ipmitool sdr list" -IPMI_PSU_DATA_DOCKER = "ipmitool sdr list" +IPMI_PSU1_DATA = "docker exec -it pmon ipmitool raw 0x04 0x2d 0x31 | awk '{print substr($0,9,1)}'" +IPMI_PSU1_DATA_DOCKER = "ipmitool raw 0x04 0x2d 0x31 | awk '{print substr($0,9,1)}'" +IPMI_PSU2_DATA = "docker exec -it pmon ipmitool raw 0x04 0x2d 0x32 | awk '{print substr($0,9,1)}'" +IPMI_PSU2_DATA_DOCKER = "ipmitool raw 0x04 0x2d 0x32 | awk '{print substr($0,9,1)}'" PSU_PRESENCE = "PSU{0}_stat" # Use this for older firmware # PSU_PRESENCE="PSU{0}_prsnt" -ipmi_sdr_list = "" try: @@ -42,30 +43,26 @@ def isDockerEnv(self): def get_pmc_register(self, reg_name): status = 1 - global ipmi_sdr_list - ipmi_dev_node = "/dev/pmi0" - ipmi_cmd = IPMI_PSU_DATA + ipmi_cmd_1 = IPMI_PSU1_DATA + ipmi_cmd_2 = IPMI_PSU1_DATA dockerenv = self.isDockerEnv() if dockerenv == True: - ipmi_cmd = IPMI_PSU_DATA_DOCKER - - status, ipmi_sdr_list = commands.getstatusoutput(ipmi_cmd) + if index == 1: + status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU1_DATA_DOCKER) + elif index == 2: + status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU2_DATA_DOCKER) + else: + if index == 1: + status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU1_DATA) + elif index == 2: + status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU2_DATA) if status: - logging.error('Failed to execute:' + ipmi_sdr_list) - sys.exit(0) - - for item in ipmi_sdr_list.split("\n"): - if reg_name in item: - output = item.strip() - - if not output: - print('\nFailed to fetch: ' + reg_name + ' sensor ') + logging.error('Failed to execute ipmitool') sys.exit(0) - output = output.split('|')[1] + output = ipmi_sdr_list - logging.basicConfig(level=logging.DEBUG) return output def get_num_psus(self): @@ -86,8 +83,26 @@ def get_psu_status(self, index): """ # Until psu_status is implemented this is hardcoded temporarily - status = 1 - return status + psu_status = 'f' + ret_status = 1 + dockerenv = self.isDockerEnv() + if dockerenv == True: + if index == 1: + ret_status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU1_DATA_DOCKER) + elif index == 2: + ret_status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU2_DATA_DOCKER) + else: + if index == 1: + ret_status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU1_DATA) + elif index == 2: + ret_status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU2_DATA) + + if ret_status: + logging.error('Failed to execute ipmitool : ') + sys.exit(0) + + psu_status = ipmi_sdr_list + return (not int(psu_status, 16) > 1) def get_psu_presence(self, index): """ @@ -96,12 +111,23 @@ def get_psu_presence(self, index): :param index: An integer, index of the PSU of which to query status :return: Boolean, True if PSU is plugged, False if not """ - status = 0 - psu_reg_name = PSU_PRESENCE.format(index) - psu_status = int(self.get_pmc_register(psu_reg_name), 16) - if (psu_status != 'ERR'): - # Check for PSU presence - if (psu_status == 0x00): - status = 1 - return status + psu_status = '0' + ret_status = 1 + dockerenv = self.isDockerEnv() + if dockerenv == True: + if index == 1: + ret_status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU1_DATA_DOCKER) + elif index == 2: + ret_status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU2_DATA_DOCKER) + else: + if index == 1: + ret_status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU1_DATA) + elif index == 2: + ret_status, ipmi_sdr_list = commands.getstatusoutput(IPMI_PSU2_DATA) + + if ret_status: + logging.error('Failed to execute ipmitool : ') + sys.exit(0) + psu_status = ipmi_sdr_list + return (int(psu_status, 16) & 1) diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/sfputil.py b/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/sfputil.py index 192fb80f6c56..b424cffc3f7c 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/sfputil.py +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/sfputil.py @@ -20,8 +20,8 @@ class SfpUtil(SfpUtilBase): """Platform-specific SfpUtil class""" PORT_START = 1 - PORT_END = 64 - PORTS_IN_BLOCK = 64 + PORT_END = 34 + PORTS_IN_BLOCK = 32 BASE_RES_PATH = "/sys/bus/pci/devices/0000:04:00.0/resource0" @@ -112,6 +112,11 @@ def get_presence(self, port_num): # Mask off 4th bit for presence mask = (1 << 4) + # Mask off 1st bit for presence 33,34 + if (port_num > 32): + mask = (1 << 0) + + # ModPrsL is active low if reg_value & mask == 0: return True diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/pmon_daemon_control.json b/device/dell/x86_64-dellemc_s5232f_c3538-r0/pmon_daemon_control.json index 94592fa8cebc..44871c057e82 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/pmon_daemon_control.json +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/pmon_daemon_control.json @@ -1,3 +1,4 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_thermalctld": true } diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/modules/dell_s5232f_fpga_ocores.c b/platform/broadcom/sonic-platform-modules-dell/s5232f/modules/dell_s5232f_fpga_ocores.c index f66f5f18a708..c50d07a05a53 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s5232f/modules/dell_s5232f_fpga_ocores.c +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/modules/dell_s5232f_fpga_ocores.c @@ -1,25 +1,25 @@ /* - * Copyright (C) 2018 Dell Inc - * - * Licensed under the GNU General Public License Version 2 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT 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) 2018 Dell Inc +* +* Licensed under the GNU General Public License Version 2 +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +*/ -/********************************************************************** - * @file fpga_ocores.c - * @brief This is a driver to interface with Linux Open Cores driver for FPGA i2c access - * - ************************************************************************/ +/** +* @file fpga_i2ccore.c +* @brief This is a driver to interface with Linux Open Cores drivber for FPGA i2c access +* +************************************************************************/ #include #include #include @@ -67,30 +67,29 @@ static const size_t BUF_SIZE = PAGE_SIZE; /* Device data used by this driver. */ struct fpgapci_dev { - /* the kernel pci device data structure */ - struct pci_dev *pci_dev; - - /* upstream root node */ - struct pci_dev *upstream; + /* the kernel pci device data structure */ + struct pci_dev *pci_dev; - /* kernels virtual addr. for the mapped BARs */ - void * __iomem bar[PCI_NUM_BARS]; + /* upstream root node */ + struct pci_dev *upstream; - /* length of each memory region. Used for error checking. */ - size_t bar_length[PCI_NUM_BARS]; + /* kernels virtual addr. for the mapped BARs */ + void * __iomem bar[PCI_NUM_BARS]; - /* Debug data */ - /* number of hw interrupts handled. */ - int num_handled_interrupts; - int num_undelivered_signals; - int pci_gen; - int pci_num_lanes; + /* length of each memory region. Used for error checking. */ + size_t bar_length[PCI_NUM_BARS]; - unsigned int irq_first; - unsigned int irq_length; - unsigned int irq_assigned; - unsigned int xcvr_intr_count; + /* Debug data */ + /* number of hw interrupts handled. */ + int num_handled_interrupts; + int num_undelivered_signals; + int pci_gen; + int pci_num_lanes; + unsigned int irq_first; + unsigned int irq_length; + unsigned int irq_assigned; + unsigned int xcvr_intr_count; }; static int use_irq = 1; @@ -100,7 +99,7 @@ MODULE_PARM_DESC(use_irq, "Get an use_irq value from user...\n"); static uint32_t num_bus = 0; module_param(num_bus, int, 0); MODULE_PARM_DESC(num_bus, - "Number of i2c busses supported by the FPGA on this platform."); + "Number of i2c busses supported by the FPGA on this platform."); /* Xilinx FPGA PCIE info: */ @@ -125,14 +124,14 @@ typedef unsigned long long u64; /* struct to hold data related to the pcie device */ struct pci_data_struct{ - struct pci_dev* dev; - unsigned long long phy_addr_bar0; - unsigned long long phy_len_bar0; - unsigned long long phy_flags_bar0; - unsigned int irq_first; - unsigned int irq_length; - unsigned int irq_assigned; - void * kvirt_addr_bar0; + struct pci_dev* dev; + unsigned long long phy_addr_bar0; + unsigned long long phy_len_bar0; + unsigned long long phy_flags_bar0; + unsigned int irq_first; + unsigned int irq_length; + unsigned int irq_assigned; + void * kvirt_addr_bar0; }; /* global variable declarations */ @@ -147,55 +146,55 @@ static void free_bars(struct fpgapci_dev *fpgapci, struct pci_dev *dev); struct fpgalogic_i2c { - void __iomem *base; - u32 reg_shift; - u32 reg_io_width; - wait_queue_head_t wait; - struct i2c_msg *msg; - int pos; - int nmsgs; - int state; /* see STATE_ */ - int ip_clock_khz; - int bus_clock_khz; - void (*reg_set)(struct fpgalogic_i2c *i2c, int reg, u8 value); - u8 (*reg_get)(struct fpgalogic_i2c *i2c, int reg); - u32 timeout; - struct mutex lock; + void __iomem *base; + u32 reg_shift; + u32 reg_io_width; + wait_queue_head_t wait; + struct i2c_msg *msg; + int pos; + int nmsgs; + int state; /* see STATE_ */ + int ip_clock_khz; + int bus_clock_khz; + void (*reg_set)(struct fpgalogic_i2c *i2c, int reg, u8 value); + u8 (*reg_get)(struct fpgalogic_i2c *i2c, int reg); + u32 timeout; + struct mutex lock; }; /* registers */ -#define FPGAI2C_REG_PRELOW 0 -#define FPGAI2C_REG_PREHIGH 1 -#define FPGAI2C_REG_CONTROL 2 -#define FPGAI2C_REG_DATA 3 -#define FPGAI2C_REG_CMD 4 /* write only */ -#define FPGAI2C_REG_STATUS 4 /* read only, same address as FPGAI2C_REG_CMD */ -#define FPGAI2C_REG_VER 5 +#define FPGAI2C_REG_PRELOW 0 +#define FPGAI2C_REG_PREHIGH 1 +#define FPGAI2C_REG_CONTROL 2 +#define FPGAI2C_REG_DATA 3 +#define FPGAI2C_REG_CMD 4 /* write only */ +#define FPGAI2C_REG_STATUS 4 /* read only, same address as FPGAI2C_REG_CMD */ +#define FPGAI2C_REG_VER 5 -#define FPGAI2C_REG_CTRL_IEN 0x40 -#define FPGAI2C_REG_CTRL_EN 0x80 +#define FPGAI2C_REG_CTRL_IEN 0x40 +#define FPGAI2C_REG_CTRL_EN 0x80 -#define FPGAI2C_REG_CMD_START 0x91 -#define FPGAI2C_REG_CMD_STOP 0x41 -#define FPGAI2C_REG_CMD_READ 0x21 -#define FPGAI2C_REG_CMD_WRITE 0x11 -#define FPGAI2C_REG_CMD_READ_ACK 0x21 -#define FPGAI2C_REG_CMD_READ_NACK 0x29 -#define FPGAI2C_REG_CMD_IACK 0x01 +#define FPGAI2C_REG_CMD_START 0x91 +#define FPGAI2C_REG_CMD_STOP 0x41 +#define FPGAI2C_REG_CMD_READ 0x21 +#define FPGAI2C_REG_CMD_WRITE 0x11 +#define FPGAI2C_REG_CMD_READ_ACK 0x21 +#define FPGAI2C_REG_CMD_READ_NACK 0x29 +#define FPGAI2C_REG_CMD_IACK 0x01 -#define FPGAI2C_REG_STAT_IF 0x01 -#define FPGAI2C_REG_STAT_TIP 0x02 -#define FPGAI2C_REG_STAT_ARBLOST 0x20 -#define FPGAI2C_REG_STAT_BUSY 0x40 -#define FPGAI2C_REG_STAT_NACK 0x80 +#define FPGAI2C_REG_STAT_IF 0x01 +#define FPGAI2C_REG_STAT_TIP 0x02 +#define FPGAI2C_REG_STAT_ARBLOST 0x20 +#define FPGAI2C_REG_STAT_BUSY 0x40 +#define FPGAI2C_REG_STAT_NACK 0x80 /* SR[7:0] - Status register */ -#define FPGAI2C_REG_SR_RXACK (1 << 7) /* Receive acknowledge from slave ‘1’ = No acknowledge received*/ -#define FPGAI2C_REG_SR_BUSY (1 << 6) /* Busy, I2C bus busy (as defined by start / stop bits) */ -#define FPGAI2C_REG_SR_AL (1 << 5) /* Arbitration lost - fpga i2c logic lost arbitration */ -#define FPGAI2C_REG_SR_TIP (1 << 1) /* Transfer in progress */ -#define FPGAI2C_REG_SR_IF (1 << 0) /* Interrupt flag */ +#define FPGAI2C_REG_SR_RXACK (1 << 7) /* Receive acknowledge from slave .1. = No acknowledge received*/ +#define FPGAI2C_REG_SR_BUSY (1 << 6) /* Busy, I2C bus busy (as defined by start / stop bits) */ +#define FPGAI2C_REG_SR_AL (1 << 5) /* Arbitration lost - fpga i2c logic lost arbitration */ +#define FPGAI2C_REG_SR_TIP (1 << 1) /* Transfer in progress */ +#define FPGAI2C_REG_SR_IF (1 << 0) /* Interrupt flag */ enum { STATE_DONE = 0, @@ -205,15 +204,16 @@ enum { STATE_START, STATE_WRITE, STATE_READ, + STATE_STOP, STATE_ERROR, }; -#define TYPE_FPGALOGIC 0 -#define TYPE_GRLIB 1 +#define TYPE_FPGALOGIC 0 +#define TYPE_GRLIB 1 /*I2C_CH1 Offset address from PCIE BAR 0*/ -#define FPGALOGIC_I2C_BASE 0x00006000 -#define FPGALOGIC_CH_OFFSET 0x10 +#define FPGALOGIC_I2C_BASE 0x00006000 +#define FPGALOGIC_CH_OFFSET 0x10 #define i2c_bus_controller_numb 1 #define I2C_PCI_MAX_BUS (16) @@ -316,58 +316,58 @@ enum { static int total_i2c_pci_bus = 0; static uint32_t board_rev_type = 0; -static struct fpgalogic_i2c fpgalogic_i2c[I2C_PCI_MAX_BUS]; -static struct i2c_adapter i2c_pci_adap[I2C_PCI_MAX_BUS]; -static struct mutex i2c_xfer_lock[I2C_PCI_MAX_BUS]; +static struct fpgalogic_i2c fpgalogic_i2c[I2C_PCI_MAX_BUS]; +static struct i2c_adapter i2c_pci_adap[I2C_PCI_MAX_BUS]; +static struct mutex i2c_xfer_lock[I2C_PCI_MAX_BUS]; static void fpgai2c_reg_set_8(struct fpgalogic_i2c *i2c, int reg, u8 value) { - iowrite8(value, i2c->base + (reg << i2c->reg_shift)); + iowrite8(value, i2c->base + (reg << i2c->reg_shift)); } static void fpgai2c_reg_set_16(struct fpgalogic_i2c *i2c, int reg, u8 value) { - iowrite16(value, i2c->base + (reg << i2c->reg_shift)); + iowrite16(value, i2c->base + (reg << i2c->reg_shift)); } static void fpgai2c_reg_set_32(struct fpgalogic_i2c *i2c, int reg, u8 value) { - iowrite32(value, i2c->base + (reg << i2c->reg_shift)); + iowrite32(value, i2c->base + (reg << i2c->reg_shift)); } static void fpgai2c_reg_set_16be(struct fpgalogic_i2c *i2c, int reg, u8 value) { - iowrite16be(value, i2c->base + (reg << i2c->reg_shift)); + iowrite16be(value, i2c->base + (reg << i2c->reg_shift)); } static void fpgai2c_reg_set_32be(struct fpgalogic_i2c *i2c, int reg, u8 value) { - iowrite32be(value, i2c->base + (reg << i2c->reg_shift)); + iowrite32be(value, i2c->base + (reg << i2c->reg_shift)); } static inline u8 fpgai2c_reg_get_8(struct fpgalogic_i2c *i2c, int reg) { - return ioread8(i2c->base + (reg << i2c->reg_shift)); + return ioread8(i2c->base + (reg << i2c->reg_shift)); } static inline u8 fpgai2c_reg_get_16(struct fpgalogic_i2c *i2c, int reg) { - return ioread16(i2c->base + (reg << i2c->reg_shift)); + return ioread16(i2c->base + (reg << i2c->reg_shift)); } static inline u8 fpgai2c_reg_get_32(struct fpgalogic_i2c *i2c, int reg) { - return ioread32(i2c->base + (reg << i2c->reg_shift)); + return ioread32(i2c->base + (reg << i2c->reg_shift)); } static inline u8 fpgai2c_reg_get_16be(struct fpgalogic_i2c *i2c, int reg) { - return ioread16be(i2c->base + (reg << i2c->reg_shift)); + return ioread16be(i2c->base + (reg << i2c->reg_shift)); } static inline u8 fpgai2c_reg_get_32be(struct fpgalogic_i2c *i2c, int reg) { - return ioread32be(i2c->base + (reg << i2c->reg_shift)); + return ioread32be(i2c->base + (reg << i2c->reg_shift)); } static inline void fpgai2c_reg_set(struct fpgalogic_i2c *i2c, int reg, u8 value) @@ -384,29 +384,29 @@ static inline u8 fpgai2c_reg_get(struct fpgalogic_i2c *i2c, int reg) static void fpgai2c_dump(struct fpgalogic_i2c *i2c) { - u8 tmp; + u8 tmp; - PRINT("Logic register dump:\n"); + PRINT("Logic register dump:\n"); - tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_PRELOW); - PRINT("FPGAI2C_REG_PRELOW (%d) = 0x%x\n",FPGAI2C_REG_PRELOW,tmp); + tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_PRELOW); + PRINT("FPGAI2C_REG_PRELOW (%d) = 0x%x\n",FPGAI2C_REG_PRELOW,tmp); - tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_PREHIGH); - PRINT("FPGAI2C_REG_PREHIGH(%d) = 0x%x\n",FPGAI2C_REG_PREHIGH,tmp); + tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_PREHIGH); + PRINT("FPGAI2C_REG_PREHIGH(%d) = 0x%x\n",FPGAI2C_REG_PREHIGH,tmp); - tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_CONTROL); - PRINT("FPGAI2C_REG_CONTROL(%d) = 0x%x\n",FPGAI2C_REG_CONTROL,tmp); + tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_CONTROL); + PRINT("FPGAI2C_REG_CONTROL(%d) = 0x%x\n",FPGAI2C_REG_CONTROL,tmp); - tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_DATA); - PRINT("FPGAI2C_REG_DATA (%d) = 0x%x\n",FPGAI2C_REG_DATA,tmp); + tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_DATA); + PRINT("FPGAI2C_REG_DATA (%d) = 0x%x\n",FPGAI2C_REG_DATA,tmp); - tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_CMD); - PRINT("FPGAI2C_REG_CMD (%d) = 0x%x\n",FPGAI2C_REG_CMD,tmp); + tmp = fpgai2c_reg_get(i2c, FPGAI2C_REG_CMD); + PRINT("FPGAI2C_REG_CMD (%d) = 0x%x\n",FPGAI2C_REG_CMD,tmp); } static void fpgai2c_stop(struct fpgalogic_i2c *i2c) { - fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); } /* @@ -414,117 +414,117 @@ static void fpgai2c_stop(struct fpgalogic_i2c *i2c) */ static int fpgai2c_poll(struct fpgalogic_i2c *i2c) { - u8 stat = fpgai2c_reg_get(i2c, FPGAI2C_REG_STATUS); - struct i2c_msg *msg = i2c->msg; - u8 addr; - - /* Ready? */ - if (stat & FPGAI2C_REG_STAT_TIP) - return -EBUSY; - - if (i2c->state == STATE_DONE || i2c->state == STATE_ERROR) { - /* Stop has been sent */ - fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); - if (i2c->state == STATE_ERROR) - return -EIO; - return 0; - } - - /* Error? */ - if (stat & FPGAI2C_REG_STAT_ARBLOST) { - i2c->state = STATE_ERROR; - fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); - return -EAGAIN; - } - - if (i2c->state == STATE_INIT) { - if (stat & FPGAI2C_REG_STAT_BUSY) - return -EBUSY; - - i2c->state = STATE_ADDR; - } - - if (i2c->state == STATE_ADDR) { - /* 10 bit address? */ - if (i2c->msg->flags & I2C_M_TEN) { - addr = 0xf0 | ((i2c->msg->addr >> 7) & 0x6); - i2c->state = STATE_ADDR10; - } else { - addr = (i2c->msg->addr << 1); - i2c->state = STATE_START; - } + u8 stat = fpgai2c_reg_get(i2c, FPGAI2C_REG_STATUS); + struct i2c_msg *msg = i2c->msg; + u8 addr; + + /* Ready? */ + if (stat & FPGAI2C_REG_STAT_TIP) + return -EBUSY; + + if (i2c->state == STATE_DONE || i2c->state == STATE_ERROR) { + /* Stop has been sent */ + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); + if (i2c->state == STATE_ERROR) + return -EIO; + return 0; + } + + /* Error? */ + if (stat & FPGAI2C_REG_STAT_ARBLOST) { + i2c->state = STATE_ERROR; + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); + return -EAGAIN; + } + + if (i2c->state == STATE_INIT) { + if (stat & FPGAI2C_REG_STAT_BUSY) + return -EBUSY; + + i2c->state = STATE_ADDR; + } + + if (i2c->state == STATE_ADDR) { + /* 10 bit address? */ + if (i2c->msg->flags & I2C_M_TEN) { + addr = 0xf0 | ((i2c->msg->addr >> 7) & 0x6); + i2c->state = STATE_ADDR10; + } else { + addr = (i2c->msg->addr << 1); + i2c->state = STATE_START; + } - /* Set read bit if necessary */ - addr |= (i2c->msg->flags & I2C_M_RD) ? 1 : 0; + /* Set read bit if necessary */ + addr |= (i2c->msg->flags & I2C_M_RD) ? 1 : 0; - fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, addr); - fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_START); + fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, addr); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_START); - return 0; - } + return 0; + } - /* Second part of 10 bit addressing */ - if (i2c->state == STATE_ADDR10) { - fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, i2c->msg->addr & 0xff); - fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_WRITE); + /* Second part of 10 bit addressing */ + if (i2c->state == STATE_ADDR10) { + fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, i2c->msg->addr & 0xff); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_WRITE); - i2c->state = STATE_START; - return 0; - } + i2c->state = STATE_START; + return 0; + } - if (i2c->state == STATE_START || i2c->state == STATE_WRITE) { - i2c->state = (msg->flags & I2C_M_RD) ? STATE_READ : STATE_WRITE; + if (i2c->state == STATE_START || i2c->state == STATE_WRITE) { + i2c->state = (msg->flags & I2C_M_RD) ? STATE_READ : STATE_WRITE; - if (stat & FPGAI2C_REG_STAT_NACK) { - i2c->state = STATE_ERROR; - fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); - return -ENXIO; - } - } else { - msg->buf[i2c->pos++] = fpgai2c_reg_get(i2c, FPGAI2C_REG_DATA); - } - - if (i2c->pos >= msg->len) { - i2c->nmsgs--; - i2c->msg++; - i2c->pos = 0; - msg = i2c->msg; - - if (i2c->nmsgs) { - if (!(msg->flags & I2C_M_NOSTART)) { - i2c->state = STATE_ADDR; - return 0; - } else { - i2c->state = (msg->flags & I2C_M_RD) - ? STATE_READ : STATE_WRITE; - } - } else { - i2c->state = STATE_DONE; - fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); - return 0; - } - } + if (stat & FPGAI2C_REG_STAT_NACK) { + i2c->state = STATE_ERROR; + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); + return -ENXIO; + } + } else { + msg->buf[i2c->pos++] = fpgai2c_reg_get(i2c, FPGAI2C_REG_DATA); + } + + if (i2c->pos >= msg->len) { + i2c->nmsgs--; + i2c->msg++; + i2c->pos = 0; + msg = i2c->msg; + + if (i2c->nmsgs) { + if (!(msg->flags & I2C_M_NOSTART)) { + i2c->state = STATE_ADDR; + return 0; + } else { + i2c->state = (msg->flags & I2C_M_RD) + ? STATE_READ : STATE_WRITE; + } + } else { + i2c->state = STATE_DONE; + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_STOP); + return 0; + } + } - if (i2c->state == STATE_READ) { - fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, i2c->pos == (msg->len - 1) ? - FPGAI2C_REG_CMD_READ_NACK : FPGAI2C_REG_CMD_READ_ACK); - } else { - fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, msg->buf[i2c->pos++]); - fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_WRITE); - } + if (i2c->state == STATE_READ) { + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, i2c->pos == (msg->len - 1) ? + FPGAI2C_REG_CMD_READ_NACK : FPGAI2C_REG_CMD_READ_ACK); + } else { + fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, msg->buf[i2c->pos++]); + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_WRITE); + } - return 0; + return 0; } static ssize_t get_mod_msi(struct device *dev, struct device_attribute *devattr, char *buf) { int ind = 0, port_status=0, port_irq_status=0; - struct fpgapci_dev *fpgapci = (struct fpgapci_dev*) dev_get_drvdata(dev); + struct fpgapci_dev *fpgapci = (struct fpgapci_dev*) dev_get_drvdata(dev); PRINT("%s:xcvr_intr_count:%u\n", __FUNCTION__, fpgapci->xcvr_intr_count); for(ind=0;ind<64;ind++) { - port_status = ioread32(fpga_ctl_addr + PORT_STS_OFFSET + (ind*16)); - port_irq_status = ioread32(fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); + port_status = ioread32(fpga_ctl_addr + PORT_STS_OFFSET + (ind*16)); + port_irq_status = ioread32(fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); PRINT("%s:port:%d, port_status:%#x, port_irq_status:%#x\n", __FUNCTION__, ind, port_status, port_irq_status); } return sprintf(buf,"0x%04x\n",fpgapci->xcvr_intr_count); @@ -532,31 +532,31 @@ static ssize_t get_mod_msi(struct device *dev, struct device_attribute *devattr, static DEVICE_ATTR(port_msi, S_IRUGO, get_mod_msi, NULL); static struct attribute *port_attrs[] = { - &dev_attr_port_msi.attr, - NULL, + &dev_attr_port_msi.attr, + NULL, }; static struct attribute_group port_attr_grp = { - .attrs = port_attrs, + .attrs = port_attrs, }; static irqreturn_t fpgaport_1_32_isr(int irq, void *dev) { struct pci_dev *pdev = dev; - struct fpgapci_dev *fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&pdev->dev); + struct fpgapci_dev *fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&pdev->dev); int ind = 0, port_status=0, port_irq_status=0; for(ind=0;ind<32;ind++) { - port_irq_status = ioread32(fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); + port_irq_status = ioread32(fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); if(port_irq_status&(IRQ_LTCH_STS|PRSNT_LTCH_STS)) { PRINT("%s:port:%d, port_status:%#x, port_irq_status:%#x\n", __FUNCTION__, ind, port_status, port_irq_status); - //write on clear - iowrite32( IRQ_LTCH_STS|PRSNT_LTCH_STS,fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); + //write on clear + iowrite32( IRQ_LTCH_STS|PRSNT_LTCH_STS,fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); } } - fpgapci->xcvr_intr_count++; + fpgapci->xcvr_intr_count++; PRINT("%s: xcvr_intr_count:%u\n", __FUNCTION__, fpgapci->xcvr_intr_count); sysfs_notify(&pdev->dev.kobj, NULL, "port_msi"); return IRQ_HANDLED; @@ -565,19 +565,18 @@ static irqreturn_t fpgaport_1_32_isr(int irq, void *dev) static irqreturn_t fpgaport_33_64_isr(int irq, void *dev) { struct pci_dev *pdev = dev; - struct fpgapci_dev *fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&pdev->dev); + struct fpgapci_dev *fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&pdev->dev); int ind = 0, port_status=0, port_irq_status=0; for(ind=32;ind<64;ind++) { - port_irq_status = ioread32(fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); + port_irq_status = ioread32(fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); if(port_irq_status| (IRQ_LTCH_STS|PRSNT_LTCH_STS)) { PRINT("%s:port:%d, port_status:%#x, port_irq_status:%#x\n", __FUNCTION__, ind, port_status, port_irq_status); - //write on clear - iowrite32( IRQ_LTCH_STS|PRSNT_LTCH_STS,fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); + iowrite32( IRQ_LTCH_STS|PRSNT_LTCH_STS,fpga_ctl_addr + PORT_IRQ_STS_OFFSET + (ind*16)); } } - fpgapci->xcvr_intr_count++; + fpgapci->xcvr_intr_count++; PRINT("%s: xcvr_intr_count:%u\n", __FUNCTION__, fpgapci->xcvr_intr_count); sysfs_notify(&pdev->dev.kobj, NULL, "port_msi"); return IRQ_HANDLED; @@ -590,10 +589,14 @@ static void fpgai2c_process(struct fpgalogic_i2c *i2c) PRINT("fpgai2c_process in. status reg :0x%x\n", stat); - if ((i2c->state == STATE_DONE) || (i2c->state == STATE_ERROR)) { + if ((i2c->state == STATE_STOP) || (i2c->state == STATE_ERROR)) { /* stop has been sent */ - PRINT("fpgai2c_process FPGAI2C_REG_CMD_IACK stat = 0x%x Set FPGAI2C_REG_CMD(0%x) FPGAI2C_REG_CMD_IACK = 0x%x\n",stat, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); + PRINT("fpgai2c_process FPGAI2C_REG_CMD_IACK stat = 0x%x Set FPGAI2C_REG_CMD(0%x) FPGAI2C_REG_CMD_IACK = 0x%x\n" \ + ,stat, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); + if(i2c->state == STATE_STOP) { + i2c->state = STATE_DONE; + } wake_up(&i2c->wait); return; } @@ -628,7 +631,7 @@ static void fpgai2c_process(struct fpgalogic_i2c *i2c) i2c->pos = 0; msg = i2c->msg; - if (i2c->nmsgs) { /* end? */ + if (i2c->nmsgs) { /* end? */ /* send start? */ if (!(msg->flags & I2C_M_NOSTART)) { @@ -647,7 +650,7 @@ static void fpgai2c_process(struct fpgalogic_i2c *i2c) ? STATE_READ : STATE_WRITE; } } else { - i2c->state = STATE_DONE; + i2c->state = STATE_STOP; fpgai2c_stop(i2c); return; } @@ -655,9 +658,9 @@ static void fpgai2c_process(struct fpgalogic_i2c *i2c) if (i2c->state == STATE_READ) { PRINT("fpgai2c_poll STATE_READ i2c->pos=%d msg->len-1 = 0x%x set FPGAI2C_REG_CMD = 0x%x\n",i2c->pos, msg->len-1, - i2c->pos == (msg->len-1) ? FPGAI2C_REG_CMD_READ_NACK : FPGAI2C_REG_CMD_READ_ACK); + i2c->pos == (msg->len-1) ? FPGAI2C_REG_CMD_READ_NACK : FPGAI2C_REG_CMD_READ_ACK); fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, i2c->pos == (msg->len-1) ? - FPGAI2C_REG_CMD_READ_NACK : FPGAI2C_REG_CMD_READ_ACK); + FPGAI2C_REG_CMD_READ_NACK : FPGAI2C_REG_CMD_READ_ACK); } else { PRINT("fpgai2c_process set FPGAI2C_REG_DATA(0x%x)\n",FPGAI2C_REG_DATA); fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, msg->buf[i2c->pos++]); @@ -667,14 +670,14 @@ static void fpgai2c_process(struct fpgalogic_i2c *i2c) static irqreturn_t fpgai2c_isr(int irq, void *dev_id) { - struct fpgalogic_i2c *i2c = dev_id; - fpgai2c_process(i2c); + struct fpgalogic_i2c *i2c = dev_id; + fpgai2c_process(i2c); - return IRQ_HANDLED; + return IRQ_HANDLED; } void dell_get_mutex(struct fpgalogic_i2c *i2c) { - mutex_lock(&i2c->lock); + mutex_lock(&i2c->lock); } /** @@ -682,7 +685,7 @@ void dell_get_mutex(struct fpgalogic_i2c *i2c) */ void dell_release_mutex(struct fpgalogic_i2c *i2c) { - mutex_unlock(&i2c->lock); + mutex_unlock(&i2c->lock); } static int fpgai2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) @@ -721,8 +724,9 @@ static int fpgai2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) } else { + ret = -ETIMEDOUT; PRINT("Set FPGAI2C_REG_DATA(0%x) val = 0x%x\n",FPGAI2C_REG_DATA, - (i2c->msg->addr << 1) | ((i2c->msg->flags & I2C_M_RD) ? 1:0)); + (i2c->msg->addr << 1) | ((i2c->msg->flags & I2C_M_RD) ? 1:0)); fpgai2c_reg_set(i2c, FPGAI2C_REG_DATA, (i2c->msg->addr << 1) | @@ -731,136 +735,135 @@ static int fpgai2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) /* Interrupt mode */ if (wait_event_timeout(i2c->wait, (i2c->state == STATE_ERROR) || - (i2c->state == STATE_DONE), HZ)) - return (i2c->state == STATE_DONE) ? num : -EIO; - else - return -ETIMEDOUT; + (i2c->state == STATE_DONE), HZ)) + ret = (i2c->state == STATE_DONE) ? num : -EIO; + return ret; } } static int fpgai2c_init(struct fpgalogic_i2c *i2c) { - int prescale; - int diff; - u8 ctrl; - - if (i2c->reg_io_width == 0) - i2c->reg_io_width = 1; /* Set to default value */ - - if (!i2c->reg_set || !i2c->reg_get) { - bool be = 0; //1:big_endian 0:little_endian - - switch (i2c->reg_io_width) { - case 1: - i2c->reg_set = fpgai2c_reg_set_8; - i2c->reg_get = fpgai2c_reg_get_8; - break; - - case 2: - i2c->reg_set = be ? fpgai2c_reg_set_16be : fpgai2c_reg_set_16; - i2c->reg_get = be ? fpgai2c_reg_get_16be : fpgai2c_reg_get_16; - break; - - case 4: - i2c->reg_set = be ? fpgai2c_reg_set_32be : fpgai2c_reg_set_32; - i2c->reg_get = be ? fpgai2c_reg_get_32be : fpgai2c_reg_get_32; - break; - - default: - PRINT("Unsupported I/O width (%d)\n", - i2c->reg_io_width); - return -EINVAL; - } - } + int prescale; + int diff; + u8 ctrl; + + if (i2c->reg_io_width == 0) + i2c->reg_io_width = 1; /* Set to default value */ + + if (!i2c->reg_set || !i2c->reg_get) { + bool be = 0; //1:big_endian 0:little_endian + + switch (i2c->reg_io_width) { + case 1: + i2c->reg_set = fpgai2c_reg_set_8; + i2c->reg_get = fpgai2c_reg_get_8; + break; + + case 2: + i2c->reg_set = be ? fpgai2c_reg_set_16be : fpgai2c_reg_set_16; + i2c->reg_get = be ? fpgai2c_reg_get_16be : fpgai2c_reg_get_16; + break; + + case 4: + i2c->reg_set = be ? fpgai2c_reg_set_32be : fpgai2c_reg_set_32; + i2c->reg_get = be ? fpgai2c_reg_get_32be : fpgai2c_reg_get_32; + break; + + default: + PRINT("Unsupported I/O width (%d)\n", + i2c->reg_io_width); + return -EINVAL; + } + } - ctrl = fpgai2c_reg_get(i2c, FPGAI2C_REG_CONTROL); + ctrl = fpgai2c_reg_get(i2c, FPGAI2C_REG_CONTROL); - PRINT("%s(), line:%d\n", __func__, __LINE__); - PRINT("i2c->base = 0x%p\n",i2c->base); - - PRINT("ctrl = 0x%x\n",ctrl); - PRINT("set ctrl = 0x%x\n",ctrl & ~(FPGAI2C_REG_CTRL_EN|FPGAI2C_REG_CTRL_IEN)); - - /* make sure the device is disabled */ - fpgai2c_reg_set(i2c, FPGAI2C_REG_CONTROL, ctrl & ~(FPGAI2C_REG_CTRL_EN|FPGAI2C_REG_CTRL_IEN)); - - /* - * I2C Frequency depends on host clock - * input clock of 100MHz - * prescale to 100MHz / ( 5*100kHz) -1 = 199 = 0x4F 100000/(5*100)-1=199=0xc7 - */ - prescale = (i2c->ip_clock_khz / (5 * i2c->bus_clock_khz)) - 1; - prescale = clamp(prescale, 0, 0xffff); - - diff = i2c->ip_clock_khz / (5 * (prescale + 1)) - i2c->bus_clock_khz; - if (abs(diff) > i2c->bus_clock_khz / 10) { - PRINT("Unsupported clock settings: core: %d KHz, bus: %d KHz\n", - i2c->ip_clock_khz, i2c->bus_clock_khz); - return -EINVAL; - } + PRINT("%s(), line:%d\n", __func__, __LINE__); + PRINT("i2c->base = 0x%p\n",i2c->base); - fpgai2c_reg_set(i2c, FPGAI2C_REG_PRELOW, prescale & 0xff); - fpgai2c_reg_set(i2c, FPGAI2C_REG_PREHIGH, prescale >> 8); + PRINT("ctrl = 0x%x\n",ctrl); + PRINT("set ctrl = 0x%x\n",ctrl & ~(FPGAI2C_REG_CTRL_EN|FPGAI2C_REG_CTRL_IEN)); - /* Init the device */ - fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); - if (!use_irq) - fpgai2c_reg_set(i2c, FPGAI2C_REG_CONTROL, ctrl | FPGAI2C_REG_CTRL_EN); - else - fpgai2c_reg_set(i2c, FPGAI2C_REG_CONTROL, ctrl | FPGAI2C_REG_CTRL_IEN | FPGAI2C_REG_CTRL_EN); + /* make sure the device is disabled */ + fpgai2c_reg_set(i2c, FPGAI2C_REG_CONTROL, ctrl & ~(FPGAI2C_REG_CTRL_EN|FPGAI2C_REG_CTRL_IEN)); - fpgai2c_dump(i2c); + /* + * I2C Frequency depends on host clock + * input clock of 100MHz + * prescale to 100MHz / ( 5*100kHz) -1 = 199 = 0x4F 100000/(5*100)-1=199=0xc7 + */ + prescale = (i2c->ip_clock_khz / (5 * i2c->bus_clock_khz)) - 1; + prescale = clamp(prescale, 0, 0xffff); - /* Initialize interrupt handlers if not already done */ - init_waitqueue_head(&i2c->wait); + diff = i2c->ip_clock_khz / (5 * (prescale + 1)) - i2c->bus_clock_khz; + if (abs(diff) > i2c->bus_clock_khz / 10) { + PRINT("Unsupported clock settings: core: %d KHz, bus: %d KHz\n", + i2c->ip_clock_khz, i2c->bus_clock_khz); + return -EINVAL; + } - return 0; + fpgai2c_reg_set(i2c, FPGAI2C_REG_PRELOW, prescale & 0xff); + fpgai2c_reg_set(i2c, FPGAI2C_REG_PREHIGH, prescale >> 8); + + /* Init the device */ + fpgai2c_reg_set(i2c, FPGAI2C_REG_CMD, FPGAI2C_REG_CMD_IACK); + if (!use_irq) + fpgai2c_reg_set(i2c, FPGAI2C_REG_CONTROL, ctrl | FPGAI2C_REG_CTRL_EN); + else + fpgai2c_reg_set(i2c, FPGAI2C_REG_CONTROL, ctrl | FPGAI2C_REG_CTRL_IEN | FPGAI2C_REG_CTRL_EN); + + fpgai2c_dump(i2c); + + /* Initialize interrupt handlers if not already done */ + init_waitqueue_head(&i2c->wait); + + return 0; } static u32 fpgai2c_func(struct i2c_adapter *adap) { - return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; } static const struct i2c_algorithm fpgai2c_algorithm = { - .master_xfer = fpgai2c_xfer, - .functionality = fpgai2c_func, + .master_xfer = fpgai2c_xfer, + .functionality = fpgai2c_func, }; static int i2c_pci_add_bus (struct i2c_adapter *adap) { - int ret = 0; - /* Register new adapter */ - adap->algo = &fpgai2c_algorithm; - ret = i2c_add_numbered_adapter(adap); - return ret; + int ret = 0; + /* Register new adapter */ + adap->algo = &fpgai2c_algorithm; + ret = i2c_add_numbered_adapter(adap); + return ret; } static int i2c_init_internal_data(void) { - int i; + int i; PRINT("%s(), line:%d\n", __func__, __LINE__); - for( i = 0; i < total_i2c_pci_bus; i++ ) - { - fpgalogic_i2c[i].reg_shift = 0; /* 8 bit registers */ - fpgalogic_i2c[i].reg_io_width = 1; /* 8 bit read/write */ - fpgalogic_i2c[i].timeout = 500;//1000;//1ms - fpgalogic_i2c[i].ip_clock_khz = 100000;//100000;/* input clock of 100MHz */ - fpgalogic_i2c[i].bus_clock_khz = 100; - fpgalogic_i2c[i].base = fpga_base_addr + i*FPGALOGIC_CH_OFFSET; - mutex_init(&fpgalogic_i2c[i].lock); - fpgai2c_init(&fpgalogic_i2c[i]); - } - - return 0; + for( i = 0; i < total_i2c_pci_bus; i++ ) + { + fpgalogic_i2c[i].reg_shift = 0; /* 8 bit registers */ + fpgalogic_i2c[i].reg_io_width = 1; /* 8 bit read/write */ + fpgalogic_i2c[i].timeout = 500;//1000;//1ms + fpgalogic_i2c[i].ip_clock_khz = 100000;//100000;/* input clock of 100MHz */ + fpgalogic_i2c[i].bus_clock_khz = 100; + fpgalogic_i2c[i].base = fpga_base_addr + i*FPGALOGIC_CH_OFFSET; + mutex_init(&fpgalogic_i2c[i].lock); + fpgai2c_init(&fpgalogic_i2c[i]); + } + + return 0; } static int i2c_pci_init (void) { - int i; + int i; if (num_bus == 0) { board_rev_type = ioread32(fpga_ctl_addr + MB_BRD_REV_TYPE); @@ -868,8 +871,8 @@ static int i2c_pci_init (void) if ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_00) { num_bus = I2C_PCI_MAX_BUS_REV00; } else if (((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_01) || - ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_02) || - ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_03)) { + ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_02) || + ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_03)) { switch (board_rev_type & MB_BRD_TYPE_MASK){ case BRD_TYPE_S5212_NON_NEBS: case BRD_TYPE_S5212_NEBS: @@ -907,46 +910,46 @@ static int i2c_pci_init (void) } } - printk("board_rev_type 0x%x, num_bus 0x%x\n", board_rev_type, num_bus); - total_i2c_pci_bus = num_bus; + printk("board_rev_type 0x%x, num_bus 0x%x\n", board_rev_type, num_bus); + total_i2c_pci_bus = num_bus; - memset (&i2c_pci_adap, 0, sizeof(i2c_pci_adap)); - memset (&fpgalogic_i2c, 0, sizeof(fpgalogic_i2c)); - for(i=0; i < i2c_bus_controller_numb; i++) - mutex_init(&i2c_xfer_lock[i]); + memset (&i2c_pci_adap, 0, sizeof(i2c_pci_adap)); + memset (&fpgalogic_i2c, 0, sizeof(fpgalogic_i2c)); + for(i=0; i < i2c_bus_controller_numb; i++) + mutex_init(&i2c_xfer_lock[i]); - /* Initialize driver's itnernal data structures */ - i2c_init_internal_data(); + /* Initialize driver's itnernal data structures */ + i2c_init_internal_data(); - for (i = 0 ; i < total_i2c_pci_bus; i ++) { + for (i = 0 ; i < total_i2c_pci_bus; i ++) { - i2c_pci_adap[i].owner = THIS_MODULE; - i2c_pci_adap[i].class = I2C_CLASS_HWMON | I2C_CLASS_SPD; + i2c_pci_adap[i].owner = THIS_MODULE; + i2c_pci_adap[i].class = I2C_CLASS_HWMON | I2C_CLASS_SPD; - i2c_pci_adap[i].algo_data = &fpgalogic_i2c[i]; - /* /dev/i2c-600 ~ /dev/i2c-615 for FPGA LOGIC I2C channel controller 1-7 */ - i2c_pci_adap[i].nr = i+600; - sprintf( i2c_pci_adap[ i ].name, "i2c-pci-%d", i ); - /* Add the bus via the algorithm code */ - if( i2c_pci_add_bus( &i2c_pci_adap[ i ] ) != 0 ) - { - PRINT("Cannot add bus %d to algorithm layer\n", i ); - return( -ENODEV ); - } - i2c_set_adapdata(&i2c_pci_adap[i], &fpgalogic_i2c[i]); + i2c_pci_adap[i].algo_data = &fpgalogic_i2c[i]; + /* /dev/i2c-600 ~ /dev/i2c-615 for FPGA LOGIC I2C channel controller 1-7 */ + i2c_pci_adap[i].nr = i+600; + sprintf( i2c_pci_adap[ i ].name, "i2c-pci-%d", i ); + /* Add the bus via the algorithm code */ + if( i2c_pci_add_bus( &i2c_pci_adap[ i ] ) != 0 ) + { + PRINT("Cannot add bus %d to algorithm layer\n", i ); + return( -ENODEV ); + } + i2c_set_adapdata(&i2c_pci_adap[i], &fpgalogic_i2c[i]); - PRINT( "Registered bus id: %s\n", kobject_name(&i2c_pci_adap[ i ].dev.kobj)); - } + PRINT( "Registered bus id: %s\n", kobject_name(&i2c_pci_adap[ i ].dev.kobj)); + } - return 0; + return 0; } static void i2c_pci_deinit(void) { - int i; - for( i = 0; i < total_i2c_pci_bus; i++ ){ - i2c_del_adapter(&i2c_pci_adap[i]); - } + int i; + for( i = 0; i < total_i2c_pci_bus; i++ ){ + i2c_del_adapter(&i2c_pci_adap[i]); + } } @@ -954,61 +957,61 @@ static void i2c_pci_deinit(void) * Used for re-training and disabling AER. */ static struct pci_dev* find_upstream_dev (struct pci_dev *dev) { - struct pci_bus *bus = 0; - struct pci_dev *bridge = 0; - struct pci_dev *cur = 0; - int found_dev = 0; - - bus = dev->bus; - if (bus == 0) { - PRINT ( "Device doesn't have an associated bus!\n"); - return 0; - } - - bridge = bus->self; - if (bridge == 0) { - PRINT ( "Can't get the bridge for the bus!\n"); - return 0; - } - - PRINT ( "Upstream device %x/%x, bus:slot.func %02x:%02x.%02x\n", - bridge->vendor, bridge->device, - bridge->bus->number, PCI_SLOT(bridge->devfn), PCI_FUNC(bridge->devfn)); - - PRINT ( "List of downstream devices:"); - list_for_each_entry (cur, &bus->devices, bus_list) { - if (cur != 0) { - PRINT ( " %x/%x", cur->vendor, cur->device); - if (cur == dev) { - found_dev = 1; - } - } - } - PRINT ( "\n"); - if (found_dev) { - return bridge; - } else { - PRINT ( "Couldn't find upstream device!\n"); - return 0; - } + struct pci_bus *bus = 0; + struct pci_dev *bridge = 0; + struct pci_dev *cur = 0; + int found_dev = 0; + + bus = dev->bus; + if (bus == 0) { + PRINT ( "Device doesn't have an associated bus!\n"); + return 0; + } + + bridge = bus->self; + if (bridge == 0) { + PRINT ( "Can't get the bridge for the bus!\n"); + return 0; + } + + PRINT ( "Upstream device %x/%x, bus:slot.func %02x:%02x.%02x\n", + bridge->vendor, bridge->device, + bridge->bus->number, PCI_SLOT(bridge->devfn), PCI_FUNC(bridge->devfn)); + + PRINT ( "List of downstream devices:"); + list_for_each_entry (cur, &bus->devices, bus_list) { + if (cur != 0) { + PRINT ( " %x/%x", cur->vendor, cur->device); + if (cur == dev) { + found_dev = 1; + } + } + } + PRINT ( "\n"); + if (found_dev) { + return bridge; + } else { + PRINT ( "Couldn't find upstream device!\n"); + return 0; + } } static int scan_bars(struct fpgapci_dev *fpgapci, struct pci_dev *dev) { - int i; - - for (i = 0; i < PCI_NUM_BARS; i++) { - unsigned long bar_start = pci_resource_start(dev, i); - if (bar_start) { - unsigned long bar_end = pci_resource_end(dev, i); - unsigned long bar_flags = pci_resource_flags(dev, i); - PRINT ( "BAR[%d] 0x%08lx-0x%08lx flags 0x%08lx", - i, bar_start, bar_end, bar_flags); - } - } + int i; + + for (i = 0; i < PCI_NUM_BARS; i++) { + unsigned long bar_start = pci_resource_start(dev, i); + if (bar_start) { + unsigned long bar_end = pci_resource_end(dev, i); + unsigned long bar_flags = pci_resource_flags(dev, i); + PRINT ( "BAR[%d] 0x%08lx-0x%08lx flags 0x%08lx", + i, bar_start, bar_end, bar_flags); + } + } - return 0; + return 0; } @@ -1019,64 +1022,64 @@ static int scan_bars(struct fpgapci_dev *fpgapci, struct pci_dev *dev) */ static int map_bars(struct fpgapci_dev *fpgapci, struct pci_dev *dev) { - int i; + int i; - for (i = 0; i < PCI_NUM_BARS; i++){ - phys_addr_t bar_start = pci_resource_start(dev, i); - phys_addr_t bar_end = pci_resource_end(dev, i); - unsigned long bar_length = bar_end - bar_start + 1; - fpgapci->bar_length[i] = bar_length; + for (i = 0; i < PCI_NUM_BARS; i++){ + phys_addr_t bar_start = pci_resource_start(dev, i); + phys_addr_t bar_end = pci_resource_end(dev, i); + unsigned long bar_length = bar_end - bar_start + 1; + fpgapci->bar_length[i] = bar_length; - if (!bar_start || !bar_end) { - fpgapci->bar_length[i] = 0; - continue; - } + if (!bar_start || !bar_end) { + fpgapci->bar_length[i] = 0; + continue; + } - if (bar_length < 1) { - PRINT ( "BAR #%d length is less than 1 byte\n", i); - continue; - } + if (bar_length < 1) { + PRINT ( "BAR #%d length is less than 1 byte\n", i); + continue; + } - PRINT ( "bar_start=%llx, bar_end=%llx, bar_length=%lx, flag=%lx\n", bar_start, - bar_end, bar_length, pci_resource_flags(dev, i)); + PRINT ( "bar_start=%llx, bar_end=%llx, bar_length=%lx, flag=%lx\n", bar_start, + bar_end, bar_length, pci_resource_flags(dev, i)); - /* map the device memory or IO region into kernel virtual - * address space */ - fpgapci->bar[i] = ioremap_nocache (bar_start + FPGALOGIC_I2C_BASE, I2C_PCI_MAX_BUS * FPGALOGIC_CH_OFFSET); + /* map the device memory or IO region into kernel virtual + * address space */ + fpgapci->bar[i] = ioremap_nocache (bar_start + FPGALOGIC_I2C_BASE, I2C_PCI_MAX_BUS * FPGALOGIC_CH_OFFSET); - if (!fpgapci->bar[i]) { - PRINT ( "Could not map BAR #%d.\n", i); - return -1; - } + if (!fpgapci->bar[i]) { + PRINT ( "Could not map BAR #%d.\n", i); + return -1; + } - PRINT ( "BAR[%d] mapped at 0x%p with length %lu.", i, - fpgapci->bar[i], bar_length); + PRINT ( "BAR[%d] mapped at 0x%p with length %lu.", i, + fpgapci->bar[i], bar_length); - if(i == 0) //FPGA register is in the BAR[0] - { + if(i == 0) //FPGA register is in the BAR[0] + { fpga_phys_addr = bar_start; fpga_ctl_addr = ioremap_nocache (bar_start, FPGA_CTL_REG_SIZE); fpga_base_addr = fpgapci->bar[i]; - } + } - PRINT ( "BAR[%d] mapped at 0x%p with length %lu.\n", i, - fpgapci->bar[i], bar_length); - } - return 0; + PRINT ( "BAR[%d] mapped at 0x%p with length %lu.\n", i, + fpgapci->bar[i], bar_length); + } + return 0; } static void free_bars(struct fpgapci_dev *fpgapci, struct pci_dev *dev) { - int i; + int i; - for (i = 0; i < PCI_NUM_BARS; i++) { - if (fpgapci->bar[i]) { - pci_iounmap(dev, fpgapci->bar[i]); - fpgapci->bar[i] = NULL; - } - } + for (i = 0; i < PCI_NUM_BARS; i++) { + if (fpgapci->bar[i]) { + pci_iounmap(dev, fpgapci->bar[i]); + fpgapci->bar[i] = NULL; + } + } } #define FPGA_PCI_NAME "FPGA_PCI" @@ -1089,206 +1092,206 @@ static void free_bars(struct fpgapci_dev *fpgapci, struct pci_dev *dev) * */ static int register_intr_handler(struct pci_dev *dev, int irq_num_id) { - int err = 0; - struct fpgapci_dev *fpgapci = 0; + int err = 0; + struct fpgapci_dev *fpgapci = 0; - fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&dev->dev); - if (fpgapci == 0) { - PRINT ( ": fpgapci_dev is 0\n"); - return err; - } + fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&dev->dev); + if (fpgapci == 0) { + PRINT ( ": fpgapci_dev is 0\n"); + return err; + } if ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_00) { - /* Request interrupt line for unique function - * alternatively function will be called from free_irq as well + /* Request interrupt line for unique function + * alternatively function will be called from free_irq as well * with flag IRQF_SHARED */ - switch(irq_num_id) { - /* Currently we only support test vector 2 for FPGA Logic I2C channel - * controller 1-7 interrupt*/ - case FPGA_MSI_VECTOR_ID_4: - err = request_irq(dev->irq + irq_num_id, fpgaport_1_32_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, dev); - PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_5: - err = request_irq(dev->irq + irq_num_id, fpgaport_33_64_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, dev); - PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_8: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[0]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_9: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[1]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_10: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[2]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_11: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[3]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_12: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[4]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_13: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[5]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_14: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[6]); - fpgapci->irq_assigned++; - break; - - default: - PRINT("No more interrupt handler for number (%d)\n", - dev->irq + irq_num_id); - break; - } + switch(irq_num_id) { + /* Currently we only support test vector 2 for FPGA Logic I2C channel + * controller 1-7 interrupt*/ + case FPGA_MSI_VECTOR_ID_4: + err = request_irq(dev->irq + irq_num_id, fpgaport_1_32_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, dev); + PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_5: + err = request_irq(dev->irq + irq_num_id, fpgaport_33_64_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, dev); + PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_8: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[0]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_9: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[1]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_10: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[2]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_11: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[3]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_12: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[4]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_13: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[5]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_14: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[6]); + fpgapci->irq_assigned++; + break; + + default: + PRINT("No more interrupt handler for number (%d)\n", + dev->irq + irq_num_id); + break; + } } else if (((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_01) || - ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_02) || - ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_03)) { - /* FPGA SPEC 4.3.1.34, First i2c channel mapped to vector 8 */ + ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_02) || + ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_03)) { + /* FPGA SPEC 4.3.1.34, First i2c channel mapped to vector 8 */ switch (irq_num_id) { - case FPGA_MSI_VECTOR_ID_4: - err = request_irq(dev->irq + irq_num_id, fpgaport_1_32_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, dev); - PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_5: - err = request_irq(dev->irq + irq_num_id, fpgaport_33_64_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, dev); - PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_8: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[0]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_9: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[1]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_10: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[2]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_11: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[3]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_12: - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, - FPGA_PCI_NAME, &fpgalogic_i2c[4]); - fpgapci->irq_assigned++; - break; - case FPGA_MSI_VECTOR_ID_13: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_5) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[5]); - fpgapci->irq_assigned++; - } - break; - case FPGA_MSI_VECTOR_ID_14: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_5) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[6]); - fpgapci->irq_assigned++; - } - break; - case FPGA_MSI_VECTOR_ID_15: - /*it is an external interrupt number. Ignore this case */ - break; - case FPGA_MSI_VECTOR_ID_16: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_7) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[7]); - fpgapci->irq_assigned++; - } - break; - case FPGA_MSI_VECTOR_ID_17: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_8) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[8]); - fpgapci->irq_assigned++; - } - break; - case FPGA_MSI_VECTOR_ID_18: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_8) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[9]); - fpgapci->irq_assigned++; - } - break; - case FPGA_MSI_VECTOR_ID_19: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_10) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[10]); - fpgapci->irq_assigned++; - } - break; - case FPGA_MSI_VECTOR_ID_20: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_10) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[11]); - fpgapci->irq_assigned++; - } - break; - case FPGA_MSI_VECTOR_ID_21: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[12]); - fpgapci->irq_assigned++; - } - break; - case FPGA_MSI_VECTOR_ID_22: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[13]); - fpgapci->irq_assigned++; - } - break; - case FPGA_MSI_VECTOR_ID_23: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[14]); - fpgapci->irq_assigned++; - } - break; - case FPGA_MSI_VECTOR_ID_24: - if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { - err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, - IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[15]); - fpgapci->irq_assigned++; - } - break; - - default: - PRINT("No more interrupt handler for number (%d)\n", - dev->irq + irq_num_id); - break; + case FPGA_MSI_VECTOR_ID_4: + err = request_irq(dev->irq + irq_num_id, fpgaport_1_32_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, dev); + PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_5: + err = request_irq(dev->irq + irq_num_id, fpgaport_33_64_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, dev); + PRINT ( "%d: fpgapci_dev: irq: %d, %d\n", __LINE__, dev->irq, irq_num_id); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_8: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[0]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_9: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[1]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_10: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[2]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_11: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[3]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_12: + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, IRQF_EARLY_RESUME, + FPGA_PCI_NAME, &fpgalogic_i2c[4]); + fpgapci->irq_assigned++; + break; + case FPGA_MSI_VECTOR_ID_13: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_5) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[5]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_14: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_5) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[6]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_15: + /*it is an external interrupt number. Ignore this case */ + break; + case FPGA_MSI_VECTOR_ID_16: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_7) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[7]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_17: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_8) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[8]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_18: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_8) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[9]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_19: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_10) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[10]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_20: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_10) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[11]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_21: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[12]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_22: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[13]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_23: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[14]); + fpgapci->irq_assigned++; + } + break; + case FPGA_MSI_VECTOR_ID_24: + if (total_i2c_pci_bus > I2C_PCI_BUS_NUM_12) { + err = request_irq(dev->irq + irq_num_id, fpgai2c_isr, + IRQF_EARLY_RESUME, FPGA_PCI_NAME, &fpgalogic_i2c[15]); + fpgapci->irq_assigned++; + } + break; + + default: + PRINT("No more interrupt handler for number (%d)\n", + dev->irq + irq_num_id); + break; } } - return err; + return err; } /* Mask for MSI Multi message enable bits */ #define MSI_MME 0x70 @@ -1348,33 +1351,33 @@ enum fpga_irq_type { #define CAP_REG 0x34 static void msi_set_enable(struct pci_dev *dev, int enable) { - int pos,maxvec; - u16 control; - int request_private_bits = 4; + int pos,maxvec; + u16 control; + int request_private_bits = 4; - pos = pci_find_capability(dev, PCI_CAP_ID_MSI); + pos = pci_find_capability(dev, PCI_CAP_ID_MSI); - if (pos) { - pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control); - maxvec = 1 << ((control & PCI_MSI_FLAGS_QMASK) >> 1); - PRINT("control = 0x%x maxvec = 0x%x\n", control, maxvec); - control &= ~PCI_MSI_FLAGS_ENABLE; + if (pos) { + pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control); + maxvec = 1 << ((control & PCI_MSI_FLAGS_QMASK) >> 1); + PRINT("control = 0x%x maxvec = 0x%x\n", control, maxvec); + control &= ~PCI_MSI_FLAGS_ENABLE; - /* - * The PCI 2.3 spec mandates that there are at most 32 - * interrupts. If this device asks for more, only give it one. - */ - if (request_private_bits > 5) { - request_private_bits = 0; - } + /* + * The PCI 2.3 spec mandates that there are at most 32 + * interrupts. If this device asks for more, only give it one. + */ + if (request_private_bits > 5) { + request_private_bits = 0; + } - /* Update the number of IRQs the device has available to it */ - control &= ~PCI_MSI_FLAGS_QSIZE; - control |= (request_private_bits << 4); + /* Update the number of IRQs the device has available to it */ + control &= ~PCI_MSI_FLAGS_QSIZE; + control |= (request_private_bits << 4); - pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control); - } + pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control); + } } /** * @brief Enables pcie-device and claims/remaps neccessary bar resources @@ -1383,211 +1386,212 @@ static void msi_set_enable(struct pci_dev *dev, int enable) * */ static int fpgapci_setup_device(struct fpgapci_dev *fpgapci,struct pci_dev *dev) { - int err = 0; + int err = 0; - /* wake up the pci device */ - err = pci_enable_device(dev); - if(err) { - PRINT("failed to enable pci device %d\n", err); - goto error_pci_en; - } + /* wake up the pci device */ + err = pci_enable_device(dev); + if(err) { + PRINT("failed to enable pci device %d\n", err); + goto error_pci_en; + } - /* on platforms with buggy ACPI, pdev->msi_enabled may be set to - * allow pci_enable_device to work. This indicates INTx was not routed - * and only MSI should be used - */ + /* on platforms with buggy ACPI, pdev->msi_enabled may be set to + * allow pci_enable_device to work. This indicates INTx was not routed + * and only MSI should be used + */ - pci_set_master(dev); + pci_set_master(dev); - /* Setup the BAR memory regions */ - err = pci_request_regions(dev, DRIVER_NAME); - if (err) { - PRINT("failed to enable pci device %d\n", err); - goto error_pci_req; - } + /* Setup the BAR memory regions */ + err = pci_request_regions(dev, DRIVER_NAME); + if (err) { + PRINT("failed to enable pci device %d\n", err); + goto error_pci_req; + } - scan_bars(fpgapci, dev); + scan_bars(fpgapci, dev); - if (map_bars(fpgapci, dev)) { - goto fail_map_bars; - } + if (map_bars(fpgapci, dev)) { + goto fail_map_bars; + } i2c_pci_init(); - return 0; - /* ERROR HANDLING */ + return 0; + /* ERROR HANDLING */ fail_map_bars: - pci_release_regions(dev); + pci_release_regions(dev); error_pci_req: - pci_disable_device(dev); + pci_disable_device(dev); error_pci_en: - return -ENODEV; + return -ENODEV; } static int fpgapci_configure_msi(struct fpgapci_dev *fpgapci,struct pci_dev *dev) { - int err = 0, i; - int request_vec; + int err = 0, i; + int request_vec; - msi_set_enable(dev,1); - PRINT("Check MSI capability after msi_set_enable\n"); + msi_set_enable(dev,1); + PRINT("Check MSI capability after msi_set_enable\n"); - /*Above 4.1.12*/ - request_vec = total_i2c_pci_bus; - err = pci_alloc_irq_vectors(dev, request_vec, pci_msi_vec_count(dev), - PCI_IRQ_MSI);//PCI_IRQ_AFFINITY | PCI_IRQ_MSI); + /*Above 4.1.12*/ + request_vec = total_i2c_pci_bus; + err = pci_alloc_irq_vectors(dev, request_vec, pci_msi_vec_count(dev), + PCI_IRQ_MSI);//PCI_IRQ_AFFINITY | PCI_IRQ_MSI); - if (err <= 0) { - PRINT("Cannot set MSI vector (%d)\n", err); - goto error_no_msi; - } else { - PRINT("Got %d MSI vectors starting at %d\n", err, dev->irq); + if (err <= 0) { + PRINT("Cannot set MSI vector (%d)\n", err); + goto error_no_msi; + } else { + PRINT("Got %d MSI vectors starting at %d\n", err, dev->irq); if ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_00) { if (err < MSI_VECTOR_REV_00) { goto error_disable_msi; } } else if (((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_01) || - ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_02) || - ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_03)) { + ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_02) || + ((board_rev_type & MB_BRD_REV_MASK) == MB_BRD_REV_03)) { if (err < MSI_VECTOR_REV_01) { goto error_disable_msi; } } - } - fpgapci->irq_first = dev->irq; - fpgapci->irq_length = err; - fpgapci->irq_assigned = 0; + } + fpgapci->irq_first = dev->irq; + fpgapci->irq_length = err; + fpgapci->irq_assigned = 0; - for(i = 0; i < fpgapci->irq_length; i++) { - err = register_intr_handler(dev, i); - if (err) { - PRINT("Cannot request Interrupt number %d\n", i); - goto error_pci_req_irq; - } - } + for(i = 0; i < fpgapci->irq_length; i++) { + err = register_intr_handler(dev, i); + if (err) { + PRINT("Cannot request Interrupt number %d\n", i); + goto error_pci_req_irq; + } + } - return 0; + return 0; error_pci_req_irq: - for(i = 0; i < fpgapci->irq_assigned; i++) - { - PRINT("free_irq %d i =%d\n",fpgapci->irq_first + i,i); + for(i = 0; i < fpgapci->irq_assigned; i++) + { + PRINT("free_irq %d i =%d\n",fpgapci->irq_first + i,i); if (i < 7) free_irq(fpgapci->irq_first + 8 + i, &fpgalogic_i2c[i]); else free_irq(fpgapci->irq_first + 8 + i + 1, &fpgalogic_i2c[i]); - } + } error_disable_msi: - pci_disable_msi(fpgapci->pci_dev); + pci_disable_msi(fpgapci->pci_dev); error_no_msi: - return -ENOSPC; + return -ENOSPC; } static int fpgapci_probe(struct pci_dev *dev, const struct pci_device_id *id) { - struct fpgapci_dev *fpgapci = 0; - int status = 0; + struct fpgapci_dev *fpgapci = 0; + int status = 0; #ifdef TEST - PRINT ( " vendor = 0x%x, device = 0x%x, class = 0x%x, bus:slot.func = %02x:%02x.%02x\n", - dev->vendor, dev->device, dev->class, - dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); + PRINT ( " vendor = 0x%x, device = 0x%x, class = 0x%x, bus:slot.func = %02x:%02x.%02x\n", + dev->vendor, dev->device, dev->class, + dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); #endif - fpgapci = kzalloc(sizeof(struct fpgapci_dev), GFP_KERNEL); + fpgapci = kzalloc(sizeof(struct fpgapci_dev), GFP_KERNEL); - if (!fpgapci) { - PRINT( "Couldn't allocate memory!\n"); - goto fail_kzalloc; - } + if (!fpgapci) { + PRINT( "Couldn't allocate memory!\n"); + goto fail_kzalloc; + } - fpgapci->pci_dev = dev; - dev_set_drvdata(&dev->dev, (void*)fpgapci); + fpgapci->pci_dev = dev; + dev_set_drvdata(&dev->dev, (void*)fpgapci); - fpgapci->upstream = find_upstream_dev (dev); - status = sysfs_create_group(&dev->dev.kobj, &port_attr_grp); - if (status) { - printk(KERN_INFO "%s:Cannot create sysfs\n", __FUNCTION__); - } + status = sysfs_create_group(&dev->dev.kobj, &port_attr_grp); + if (status) { + printk(KERN_INFO "%s:Cannot create sysfs\n", __FUNCTION__); + } - if(fpgapci_setup_device(fpgapci,dev)) { - goto error_no_device; - } + fpgapci->upstream = find_upstream_dev (dev); - if (use_irq) { - if(fpgapci_configure_msi(fpgapci,dev)) { - goto error_cannot_configure; - } - } + if(fpgapci_setup_device(fpgapci,dev)) { + goto error_no_device; + } + if (use_irq) { + if(fpgapci_configure_msi(fpgapci,dev)) { + goto error_cannot_configure; + } + } - return 0; - /* ERROR HANDLING */ + + return 0; + /* ERROR HANDLING */ error_cannot_configure: - printk("error_cannot_configure\n"); - free_bars (fpgapci, dev); - pci_release_regions(dev); - pci_disable_device(dev); + printk("error_cannot_configure\n"); + free_bars (fpgapci, dev); + pci_release_regions(dev); + pci_disable_device(dev); error_no_device: - i2c_pci_deinit(); - printk("error_no_device\n"); + i2c_pci_deinit(); + printk("error_no_device\n"); fail_kzalloc: - return -1; + return -1; } static void fpgapci_remove(struct pci_dev *dev) { - struct fpgapci_dev *fpgapci = 0; - int i; - PRINT (": dev is %p\n", dev); - - if (dev == 0) { - PRINT ( ": dev is 0\n"); - return; - } - - fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&dev->dev); - if (fpgapci == 0) { - PRINT ( ": fpgapci_dev is 0\n"); - return; - } - i2c_pci_deinit(); - // - if (use_irq) - { - for(i = 0; i < fpgapci->irq_assigned; i++) - { - PRINT("free_irq %d i =%d\n",fpgapci->irq_first + i,i); + struct fpgapci_dev *fpgapci = 0; + int i; + PRINT (": dev is %p\n", dev); + + if (dev == 0) { + PRINT ( ": dev is 0\n"); + return; + } + + fpgapci = (struct fpgapci_dev*) dev_get_drvdata(&dev->dev); + if (fpgapci == 0) { + PRINT ( ": fpgapci_dev is 0\n"); + return; + } + i2c_pci_deinit(); + // + if (use_irq) + { + for(i = 0; i < fpgapci->irq_assigned; i++) + { + PRINT("free_irq %d i =%d\n",fpgapci->irq_first + i,i); if (i < 7) - free_irq(fpgapci->irq_first + 8 + i, &fpgalogic_i2c[i]); + free_irq(fpgapci->irq_first + 8 + i, &fpgalogic_i2c[i]); else free_irq(fpgapci->irq_first + 8 + i + 1, &fpgalogic_i2c[i]); - } - } - pci_disable_msi(fpgapci->pci_dev); - free_bars (fpgapci, dev); - pci_disable_device(dev); - pci_release_regions(dev); + } + } + pci_disable_msi(fpgapci->pci_dev); + free_bars (fpgapci, dev); + pci_disable_device(dev); + pci_release_regions(dev); - kfree (fpgapci); + kfree (fpgapci); } static const struct pci_device_id fpgapci_ids[] = { - {PCI_DEVICE(PCI_VENDOR_ID_XILINX, DEVICE)}, - {0, }, + {PCI_DEVICE(PCI_VENDOR_ID_XILINX, DEVICE)}, + {0, }, }; MODULE_DEVICE_TABLE(pci, fpgapci_ids); static struct pci_driver fpgapci_driver = { - .name = DRIVER_NAME, - .id_table = fpgapci_ids, - .probe = fpgapci_probe, - .remove = fpgapci_remove, - /* resume, suspend are optional */ + .name = DRIVER_NAME, + .id_table = fpgapci_ids, + .probe = fpgapci_probe, + .remove = fpgapci_remove, + /* resume, suspend are optional */ }; /* Initialize the driver module (but not any device) and register @@ -1595,21 +1599,21 @@ static struct pci_driver fpgapci_driver = { static int __init fpgapci_init(void) { - if (pci_register_driver(&fpgapci_driver)) { - PRINT("pci_unregister_driver\n"); - pci_unregister_driver(&fpgapci_driver); - return -ENODEV; - } + if (pci_register_driver(&fpgapci_driver)) { + PRINT("pci_unregister_driver\n"); + pci_unregister_driver(&fpgapci_driver); + return -ENODEV; + } - return 0; + return 0; } static void __exit fpgapci_exit(void) { - PRINT ("fpgapci_exit"); + PRINT ("fpgapci_exit"); - /* unregister this driver from the PCI bus driver */ - pci_unregister_driver(&fpgapci_driver); + /* unregister this driver from the PCI bus driver */ + pci_unregister_driver(&fpgapci_driver); } @@ -1620,3 +1624,4 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("joyce_yu@dell.com"); MODULE_DESCRIPTION ("Driver for FPGA Logic I2C bus"); MODULE_SUPPORTED_DEVICE ("FPGA Logic I2C bus"); + diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/platform_sensors.py b/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/platform_sensors.py index 3091d1c9ed44..039a34e5b69b 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/platform_sensors.py +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/platform_sensors.py @@ -22,11 +22,15 @@ IPMI_SENSOR_DATA = "ipmitool sdr list" IPMI_SENSOR_DUMP = "/tmp/sdr" -FAN_PRESENCE = "FAN{0}_prsnt" PSU_PRESENCE = "PSU{0}_stat" # Use this for older firmware # PSU_PRESENCE="PSU{0}_prsnt" +IPMI_FAN_PRESENCE = "ipmitool sensor get FAN{0}_prsnt" +IPMI_PSU1_DATA_DOCKER = "ipmitool raw 0x04 0x2d 0x31 | awk '{print substr($0,9,1)}'" +IPMI_PSU2_DATA_DOCKER = "ipmitool raw 0x04 0x2d 0x32 | awk '{print substr($0,9,1)}'" +IPMI_RAW_STORAGE_READ = "ipmitool raw 0x0a 0x11 {0} 0 0 0xa0" +IPMI_FRU = "ipmitool fru" ipmi_sdr_list = "" # Dump sensor registers @@ -40,9 +44,18 @@ def ipmi_sensor_dump(): status, ipmi_sdr_list = commands.getstatusoutput(ipmi_cmd) if status: - logging.error('Failed to execute:' + ipmi_sdr_list) + logging.error('Failed to execute: ' + ipmi_sdr_list) sys.exit(0) +# Fetch a Fan Status + +def get_fan_status(fan_id): + ret_status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_FAN_PRESENCE.format(fan_id)) + if ret_status: + logging.error('Failed to execute : %s'%IPMI_FAN_PRESENCE.format(fan_id)) + sys.exit(0) + return(' ' + ipmi_cmd_ret.splitlines()[5].strip(' ').strip('[]')) + # Fetch a BMC register @@ -62,6 +75,35 @@ def get_pmc_register(reg_name): logging.basicConfig(level=logging.DEBUG) return output +#Fetch FRU Data for given fruid +def get_psu_airflow(psu_id): + fru_id = 'PSU' + str(psu_id) + '_fru' + ret_status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_FRU) + if ret_status: + logging.error('Failed to execute ipmitool: '+ IPMI_FRU) + sys.exit(0) + found_fru = False + for line in ipmi_cmd_ret.splitlines(): + if line.startswith('FRU Device Description') and fru_id in line.split(':')[1] : + found_fru = True + if found_fru and line.startswith(' Board Product '): + return ' B2F' if 'PS/IO' in line else ' F2B' + return '' + +# Fetch FRU on given offset +def fetch_raw_fru(dev_id, offset): + ret_status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_RAW_STORAGE_READ.format(dev_id)) + if ret_status: + logging.error('Failed to execute ipmitool :' + IPMI_RAW_STORAGE_READ.format(dev_id)) + sys.exit(0) + return int((ipmi_cmd_ret.splitlines()[offset/16]).split(' ')[(offset%16+1)]) + + + + +def get_fan_airflow(fan_id): + Airflow_Direction = [' F2B', ' B2F'] + return Airflow_Direction[fetch_raw_fru(fan_id+2, 0x46)] # Print the information for temperature sensors @@ -93,7 +135,6 @@ def print_temperature_sensors(): def print_fan_tray(tray): Fan_Status = [' Normal', ' Abnormal'] - Airflow_Direction = ['B2F', 'F2B'] print ' Fan Tray ' + str(tray) + ':' @@ -152,16 +193,62 @@ def print_fan_tray(tray): Fan_Status[fan1_status] print ' Fan2 State: ',\ Fan_Status[fan2_status] + print ' Airflow: ',\ + get_fan_airflow(tray) print('\nFan Trays:') for tray in range(1, S5232F_MAX_FAN_TRAYS + 1): - fan_presence = FAN_PRESENCE.format(tray) - if (get_pmc_register(fan_presence)): + if (get_fan_status(tray) == ' Present'): print_fan_tray(tray) else: - print '\n Fan Tray ' + str(tray + 1) + ': Not present' + print ' Fan Tray {}: NOT PRESENT'.format(str(tray)) + + def get_psu_presence(index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + ret_status = 1 + + if index == 1: + ret_status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_PSU1_DATA_DOCKER) + elif index == 2: + ret_status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_PSU2_DATA_DOCKER) + + if ret_status: + logging.error('Failed to execute ipmitool :' + IPMI_PSU1_DATA_DOCKER) + sys.exit(0) + + psu_status = ipmi_cmd_ret + return (int(psu_status, 16) & 1) + + def get_psu_status(index): + """ + Retrieves the presence status of power supply unit (PSU) defined + by index + :param index: An integer, index of the PSU of which to query status + :return: Boolean, True if PSU is plugged, False if not + """ + status = 0 + ret_status = 1 + ipmi_cmd_ret = 'f' + + if index == 1: + ret_status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_PSU1_DATA_DOCKER) + elif index == 2: + ret_status, ipmi_cmd_ret = commands.getstatusoutput(IPMI_PSU2_DATA_DOCKER) + + if ret_status: + logging.error('Failed to execute ipmitool : ' + IPMI_PSU2_DATA_DOCKER) + sys.exit(0) + + psu_status = ipmi_cmd_ret + + return (not int(psu_status, 16) > 1) # Print the information for PSU1, PSU2 @@ -175,7 +262,6 @@ def print_psu(psu): PSU_FAN_AIR_FLOW_BIT = 0 Psu_Fan_Presence = ['Present', 'Absent'] Psu_Fan_Status = ['Normal', 'Abnormal'] - Psu_Fan_Airflow = ['B2F', 'F2B'] # print ' Input: ', Psu_Input_Type[psu_input_type] # print ' Type: ', Psu_Type[psu_type] @@ -233,15 +319,19 @@ def print_psu(psu): get_pmc_register('PSU2_In_amp') print ' Output Current: ',\ get_pmc_register('PSU2_Out_amp') + print ' Airflow: ',\ + get_psu_airflow(psu) print('\nPSUs:') for psu in range(1, S5232F_MAX_PSUS + 1): - psu_presence = PSU_PRESENCE.format(psu) - if (get_pmc_register(psu_presence)): - print_psu(psu) + #psu_presence = PSU_PRESENCE.format(psu) + if not get_psu_presence(psu): + print ' PSU{}: NOT PRESENT'.format(psu) + elif not get_psu_status(psu) : + print ' PSU{}: NOT OK'.format(psu) else: - print '\n PSU ', psu, 'Not present' + print_psu(psu) print '\n Total Power: ',\ get_pmc_register('PSU_Total_watt') diff --git a/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/s5232f_platform.sh b/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/s5232f_platform.sh index 18e5ca2d5159..6f9282a604f2 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/s5232f_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/s5232f/scripts/s5232f_platform.sh @@ -91,6 +91,48 @@ switch_board_led_default() { resource="/sys/bus/pci/devices/0000:04:00.0/resource0" python /usr/bin/pcisysfs.py --set --offset 0x24 --val 0x194 --res $resource > /dev/null 2>&1 } + +# Readout firmware version of the system and +# store in /var/log/firmware_versions +platform_firmware_versions() { + FIRMWARE_VERSION_FILE=/var/log/firmware_versions + rm -rf ${FIRMWARE_VERSION_FILE} + echo "BIOS: `dmidecode -s system-version `" > $FIRMWARE_VERSION_FILE + ## Get FPGA version + r=`/usr/bin/pcisysfs.py --get --offset 0x00 --res /sys/bus/pci/devices/0000\:04\:00.0/resource0 | sed '1d; s/.*\(....\)$/\1/; s/\(..\{1\}\)/\1./'` + r_min=$(echo $r | sed 's/.*\(..\)$/0x\1/') + r_maj=$(echo $r | sed 's/^\(..\).*/0x\1/') + echo "FPGA: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE + + ## Get BMC Firmware Revision + r=`cat /sys/class/ipmi/ipmi0/device/bmc/firmware_revision` + echo "BMC: $r" >> $FIRMWARE_VERSION_FILE + + #System CPLD 0x31 on i2c bus 601 ( physical FPGA I2C-2) + r_min=`/usr/sbin/i2cget -y 601 0x31 0x0 | sed ' s/.*\(0x..\)$/\1/'` + r_maj=`/usr/sbin/i2cget -y 601 0x31 0x1 | sed ' s/.*\(0x..\)$/\1/'` + echo "System CPLD: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE + + #Slave CPLD 1 0x30 on i2c bus 600 ( physical FPGA I2C-1) + r_min=`/usr/sbin/i2cget -y 600 0x30 0x0 | sed ' s/.*\(0x..\)$/\1/'` + r_maj=`/usr/sbin/i2cget -y 600 0x30 0x1 | sed ' s/.*\(0x..\)$/\1/'` + echo "Slave CPLD 1: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE + + #Slave CPLD 2 0x31 on i2c bus 600 ( physical FPGA I2C-1) + r_min=`/usr/sbin/i2cget -y 600 0x31 0x0 | sed ' s/.*\(0x..\)$/\1/'` + r_maj=`/usr/sbin/i2cget -y 600 0x31 0x1 | sed ' s/.*\(0x..\)$/\1/'` + echo "Slave CPLD 2: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE + + #Slave CPLD 3 0x32 on i2c bus 600 ( physical FPGA I2C-1) + r_min=`/usr/sbin/i2cget -y 600 0x32 0x0 | sed ' s/.*\(0x..\)$/\1/'` + r_maj=`/usr/sbin/i2cget -y 600 0x32 0x1 | sed ' s/.*\(0x..\)$/\1/'` + echo "Slave CPLD 3: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE + + #Slave CPLD 3 0x32 on i2c bus 600 ( physical FPGA I2C-1) + r_min=`/usr/sbin/i2cget -y 600 0x33 0x0 | sed ' s/.*\(0x..\)$/\1/'` + r_maj=`/usr/sbin/i2cget -y 600 0x33 0x1 | sed ' s/.*\(0x..\)$/\1/'` + echo "Slave CPLD 4: $((r_maj)).$((r_min))" >> $FIRMWARE_VERSION_FILE +} init_devnum if [ "$1" == "init" ]; then @@ -106,10 +148,12 @@ if [ "$1" == "init" ]; then switch_board_modsel switch_board_led_default python /usr/bin/qsfp_irq_enable.py + platform_firmware_versions elif [ "$1" == "deinit" ]; then sys_eeprom "delete_device" switch_board_qsfp "delete_device" + switch_board_sfp "delete_device" switch_board_qsfp_mux "delete_device" modprobe -r i2c-mux-pca954x From a97b73e79cd7992ba9ecfe47749e29bd7058bcdf Mon Sep 17 00:00:00 2001 From: rajendra-dendukuri <47423477+rajendra-dendukuri@users.noreply.github.com> Date: Wed, 8 Apr 2020 02:44:50 -0400 Subject: [PATCH 152/178] Fix typo in config-setup service (#4388) --- files/image_config/config-setup/config-setup | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/files/image_config/config-setup/config-setup b/files/image_config/config-setup/config-setup index f19abd266e95..afff97806518 100755 --- a/files/image_config/config-setup/config-setup +++ b/files/image_config/config-setup/config-setup @@ -247,7 +247,7 @@ generate_config() # is created # - If updategraph is enabled and ZTP is disabled, updategraph initializes # configuration -do_config_intialization() +do_config_initialization() { if ! updategraph_is_enabled ; then if ! ztp_is_enabled ; then @@ -350,12 +350,12 @@ boot_config() fi if [ -e /tmp/pending_config_initialization ] || [ -e ${CONFIG_SETUP_INITIALIZATION_FLAG} ]; then - do_config_intialization + do_config_initialization fi # If no startup configuration is found, create a configuration to be used if [ ! -e ${CONFIG_DB_JSON} ]; then - do_config_intialization + do_config_initialization # force ZTP to restart if ztp_is_enabled ; then ztp_status=$(ztp status -c) From 2772cce8fe5492db8c59f0697526e6c7a8f8d519 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Wed, 8 Apr 2020 23:03:47 -0700 Subject: [PATCH 153/178] [device/accton] Fix Python error for as7116-54x (#4391) Fix syntax error --- device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/sfp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/sfp.py b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/sfp.py index 07e0649579ac..be1dbb52a79b 100644 --- a/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/sfp.py +++ b/device/accton/x86_64-accton_as7116_54x-r0/sonic_platform/sfp.py @@ -1111,7 +1111,7 @@ def get_presence(self): presence = int(sfp_presence.read(), 16) except IOError: return False - logger.log_info("debug:port_ %s sfp presence is %s" % (str(self.index)), % (str(presence)) + logger.log_info("debug:port_ %s sfp presence is %s" % (str(self.index), str(presence))) return presence def get_model(self): From 7d27d385eaf7f0be9acf11375d0ceb86d080a0f6 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Wed, 8 Apr 2020 23:03:22 -0700 Subject: [PATCH 154/178] [device/accton] Fix Python error for wedge100bf_32x (#4392) Remove undefined export, "constants" --- .../plugins/pltfm_mgr_rpc/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/pltfm_mgr_rpc/__init__.py b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/pltfm_mgr_rpc/__init__.py index 09cb959f2d46..414c3d6389c5 100644 --- a/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/pltfm_mgr_rpc/__init__.py +++ b/device/barefoot/x86_64-accton_wedge100bf_32x-r0/plugins/pltfm_mgr_rpc/__init__.py @@ -1 +1 @@ -__all__ = ['ttypes', 'constants', 'pltfm_mgr_rpc'] +__all__ = ['ttypes', 'pltfm_mgr_rpc'] From 4f1b9ff6f38aa413546f591f2695561d033fdcb0 Mon Sep 17 00:00:00 2001 From: Abhishek Dosi Date: Fri, 10 Apr 2020 21:33:00 -0700 Subject: [PATCH 155/178] [SubModule Update] sonic-swss Fixed SAI_BUFFER_PROFILE_ATTR_BUFFER_SIZE to uint64_t --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index f61f484d5d4f..3f8c2fe8267d 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit f61f484d5d4fa82d7dd7c7634efcc22ee9bbbb7b +Subproject commit 3f8c2fe8267d2051e098c2a71f977b70d84e84b6 From d09fba379f24b61af26913fc3c9ba34464fc423e Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Sat, 11 Apr 2020 16:42:56 -0700 Subject: [PATCH 156/178] [201911][Juniper QFX5210] Fix Python errors (#4413) --- .../qfx5210/utils/juniper_qfx5210_monitor.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_monitor.py b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_monitor.py index d225400121b8..ec83499c5c7b 100755 --- a/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_monitor.py +++ b/platform/broadcom/sonic-platform-modules-juniper/qfx5210/utils/juniper_qfx5210_monitor.py @@ -468,7 +468,7 @@ def __init__(self, log_file, log_level): masterLED_file = open(MASTER_LED_PATH, 'r+') except IOError as e: print "Error: unable to open file: %s" % str(e) - return False + return masterLED_file.write(str(master_led_value)) masterLED_file.close() @@ -477,10 +477,9 @@ def __init__(self, log_file, log_level): systemLED_file = open(SYSTEM_LED_PATH, 'r+') except IOError as e: print "Error: unable to open file: %s" % str(e) - return False + return systemLED_file.write(str(system_led_value)) systemLED_file.close() - pass def manage_device(self): thermal = QFX5210_ThermalUtil() From 4ee0f1ff08dd6b8ac16c472b3114eef8f31376c0 Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Mon, 13 Apr 2020 19:45:56 +0300 Subject: [PATCH 157/178] update SAI 1.16.2 SDK 4.4.0800 FW *.2007.0872 (#4417) --- platform/mellanox/fw.mk | 6 +++--- platform/mellanox/mlnx-sai.mk | 2 +- platform/mellanox/mlnx-sai/SAI-Implementation | 2 +- platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers | 2 +- platform/mellanox/sdk.mk | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/platform/mellanox/fw.mk b/platform/mellanox/fw.mk index dc8243be1e83..1a95072f7a78 100644 --- a/platform/mellanox/fw.mk +++ b/platform/mellanox/fw.mk @@ -11,17 +11,17 @@ else FW_FROM_URL = n endif -MLNX_SPC_FW_VERSION = 13.2007.0322 +MLNX_SPC_FW_VERSION = 13.2007.0872 MLNX_SPC_FW_FILE = fw-SPC-rel-$(subst .,_,$(MLNX_SPC_FW_VERSION))-EVB.mfa $(MLNX_SPC_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC_FW_FILE) -MLNX_SPC2_FW_VERSION = 29.2007.0322 +MLNX_SPC2_FW_VERSION = 29.2007.0872 MLNX_SPC2_FW_FILE = fw-SPC2-rel-$(subst .,_,$(MLNX_SPC2_FW_VERSION))-EVB.mfa $(MLNX_SPC2_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC2_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC2_FW_FILE) -MLNX_SPC3_FW_VERSION = 30.2007.0322 +MLNX_SPC3_FW_VERSION = 30.2007.0872 MLNX_SPC3_FW_FILE = fw-SPC3-rel-$(subst .,_,$(MLNX_SPC3_FW_VERSION))-EVB.mfa $(MLNX_SPC3_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH) $(MLNX_SPC3_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC3_FW_FILE) diff --git a/platform/mellanox/mlnx-sai.mk b/platform/mellanox/mlnx-sai.mk index 4f9e3b292465..275445bd80e0 100644 --- a/platform/mellanox/mlnx-sai.mk +++ b/platform/mellanox/mlnx-sai.mk @@ -1,6 +1,6 @@ # Mellanox SAI -MLNX_SAI_VERSION = SAIRel1.16.1-master +MLNX_SAI_VERSION = SAIRel1.16.2-master export MLNX_SAI_VERSION diff --git a/platform/mellanox/mlnx-sai/SAI-Implementation b/platform/mellanox/mlnx-sai/SAI-Implementation index ef47a5592190..5eb3e143e3da 160000 --- a/platform/mellanox/mlnx-sai/SAI-Implementation +++ b/platform/mellanox/mlnx-sai/SAI-Implementation @@ -1 +1 @@ -Subproject commit ef47a5592190c08d2f127d3fe8fa5a77ee4087ba +Subproject commit 5eb3e143e3da934b30fd9b66126a6ab626f1b15e diff --git a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers index 07425a0957d1..1d7da850581f 160000 --- a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers +++ b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers @@ -1 +1 @@ -Subproject commit 07425a0957d100405e3781f8bb633c462f37a92c +Subproject commit 1d7da850581ff0dd79990ae1c5bcb174d4272267 diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk index f2af75cccf2b..3b2e9a8f30c8 100644 --- a/platform/mellanox/sdk.mk +++ b/platform/mellanox/sdk.mk @@ -1,5 +1,5 @@ MLNX_SDK_BASE_PATH = $(PLATFORM_PATH)/sdk-src/sx-kernel/Switch-SDK-drivers/bin/ -MLNX_SDK_VERSION = 4.4.0542 +MLNX_SDK_VERSION = 4.4.0880 MLNX_SDK_ISSU_VERSION = 101 MLNX_SDK_DEB_VERSION = $(subst _,.,$(MLNX_SDK_VERSION)) From 0b35fcf3bf6c2f7742d557d4b621733d5e3d2996 Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Mon, 13 Apr 2020 18:13:19 +0300 Subject: [PATCH 158/178] [mellanox]: Add SSD FW update tool (#4351) * [mellanox]: Add SSD FW update tool. Signed-off-by: Nazarii Hnydyn * [mellanox]: Align Platform API. Signed-off-by: Nazarii Hnydyn * [mellanox]: Fix firmware description. Signed-off-by: Nazarii Hnydyn * [mellanox]: Update SSD tool. Signed-off-by: Nazarii Hnydyn --- .../build_templates/sonic_debian_extension.j2 | 3 +- platform/mellanox/fw.mk | 6 +- platform/mellanox/issu-version.mk | 3 +- platform/mellanox/mlnx-ffb.mk | 2 + platform/mellanox/mlnx-onie-fw-update.mk | 9 + ...{onie-fw-update => mlnx-onie-fw-update.sh} | 0 .../sonic_platform/component.py | 8 +- platform/mellanox/mlnx-ssd-fw-update.mk | 9 + platform/mellanox/mlnx-ssd-fw-update.sh | 727 ++++++++++++++++++ platform/mellanox/one-image.mk | 2 +- platform/mellanox/onie-fw-update.mk | 7 - platform/mellanox/rules.mk | 3 +- 12 files changed, 761 insertions(+), 18 deletions(-) create mode 100644 platform/mellanox/mlnx-onie-fw-update.mk rename platform/mellanox/{onie-fw-update => mlnx-onie-fw-update.sh} (100%) create mode 100644 platform/mellanox/mlnx-ssd-fw-update.mk create mode 100755 platform/mellanox/mlnx-ssd-fw-update.sh delete mode 100644 platform/mellanox/onie-fw-update.mk diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 66391c7bac8d..fa6678ca1f8e 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -458,7 +458,8 @@ sudo cp $files_path/$MLNX_SPC2_FW_FILE $FILESYSTEM_ROOT/etc/mlnx/fw-SPC2.mfa sudo cp $files_path/$MLNX_SPC3_FW_FILE $FILESYSTEM_ROOT/etc/mlnx/fw-SPC3.mfa sudo cp $files_path/$ISSU_VERSION_FILE $FILESYSTEM_ROOT/etc/mlnx/issu-version sudo cp $files_path/$MLNX_FFB_SCRIPT $FILESYSTEM_ROOT/usr/bin/mlnx-ffb.sh -sudo cp $files_path/$ONIE_FW_UPDATE $FILESYSTEM_ROOT/usr/bin/onie-fw-update.sh +sudo cp $files_path/$MLNX_ONIE_FW_UPDATE $FILESYSTEM_ROOT/usr/bin/$MLNX_ONIE_FW_UPDATE +sudo cp $files_path/$MLNX_SSD_FW_UPDATE $FILESYSTEM_ROOT/usr/bin/$MLNX_SSD_FW_UPDATE j2 platform/mellanox/mlnx-fw-upgrade.j2 | sudo tee $FILESYSTEM_ROOT/usr/bin/mlnx-fw-upgrade.sh sudo chmod 755 $FILESYSTEM_ROOT/usr/bin/mlnx-fw-upgrade.sh diff --git a/platform/mellanox/fw.mk b/platform/mellanox/fw.mk index 1a95072f7a78..faa3b3f239b6 100644 --- a/platform/mellanox/fw.mk +++ b/platform/mellanox/fw.mk @@ -1,4 +1,4 @@ -# mellanox firmware +# mellanox asic firmware MLNX_FW_BASE_PATH = $(MLNX_SDK_BASE_PATH) @@ -34,6 +34,8 @@ else SONIC_ONLINE_FILES += $(MLNX_FW_FILES) endif +MLNX_FILES += $(MLNX_FW_FILES) + export MLNX_SPC_FW_VERSION export MLNX_SPC_FW_FILE @@ -42,5 +44,3 @@ export MLNX_SPC2_FW_FILE export MLNX_SPC3_FW_VERSION export MLNX_SPC3_FW_FILE - -export MLNX_FW_FILES diff --git a/platform/mellanox/issu-version.mk b/platform/mellanox/issu-version.mk index c7ae4296ab7a..db368ffd8c10 100644 --- a/platform/mellanox/issu-version.mk +++ b/platform/mellanox/issu-version.mk @@ -5,5 +5,6 @@ $(ISSU_VERSION_FILE)_SRC_PATH = $(PLATFORM_PATH)/issu-version $(ISSU_VERSION_FILE)_DEPENDS += $(APPLIBS) SONIC_MAKE_FILES += $(ISSU_VERSION_FILE) -export ISSU_VERSION_FILE +MLNX_FILES += $(ISSU_VERSION_FILE) +export ISSU_VERSION_FILE diff --git a/platform/mellanox/mlnx-ffb.mk b/platform/mellanox/mlnx-ffb.mk index dabb995a3658..82d50b7ae3e3 100755 --- a/platform/mellanox/mlnx-ffb.mk +++ b/platform/mellanox/mlnx-ffb.mk @@ -4,4 +4,6 @@ MLNX_FFB_SCRIPT = mlnx-ffb.sh $(MLNX_FFB_SCRIPT)_PATH = platform/mellanox/ SONIC_COPY_FILES += $(MLNX_FFB_SCRIPT) +MLNX_FILES += $(MLNX_FFB_SCRIPT) + export MLNX_FFB_SCRIPT diff --git a/platform/mellanox/mlnx-onie-fw-update.mk b/platform/mellanox/mlnx-onie-fw-update.mk new file mode 100644 index 000000000000..825c12c30ba4 --- /dev/null +++ b/platform/mellanox/mlnx-onie-fw-update.mk @@ -0,0 +1,9 @@ +# onie update tool + +MLNX_ONIE_FW_UPDATE = mlnx-onie-fw-update.sh +$(MLNX_ONIE_FW_UPDATE)_PATH = platform/mellanox/ +SONIC_COPY_FILES += $(MLNX_ONIE_FW_UPDATE) + +MLNX_FILES += $(MLNX_ONIE_FW_UPDATE) + +export MLNX_ONIE_FW_UPDATE diff --git a/platform/mellanox/onie-fw-update b/platform/mellanox/mlnx-onie-fw-update.sh similarity index 100% rename from platform/mellanox/onie-fw-update rename to platform/mellanox/mlnx-onie-fw-update.sh diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py index 70fd96023b8c..468420eaf0aa 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py @@ -114,10 +114,10 @@ class ComponentBIOS(Component): BIOS_VERSION_PARSE_PATTERN = 'OEM[\s]*Strings\n[\s]*String[\s]*1:[\s]*([0-9a-zA-Z_\.]*)' BIOS_PENDING_UPDATE_PATTERN = '([0-9A-Za-z_]*.rom)[\s]*\|[\s]*bios_update' - ONIE_FW_UPDATE_CMD_ADD = '/usr/bin/onie-fw-update.sh add {}' - ONIE_FW_UPDATE_CMD_REMOVE = '/usr/bin/onie-fw-update.sh remove {}' - ONIE_FW_UPDATE_CMD_UPDATE = '/usr/bin/onie-fw-update.sh update' - ONIE_FW_UPDATE_CMD_SHOW = '/usr/bin/onie-fw-update.sh show-pending' + ONIE_FW_UPDATE_CMD_ADD = '/usr/bin/mlnx-onie-fw-update.sh add {}' + ONIE_FW_UPDATE_CMD_REMOVE = '/usr/bin/mlnx-onie-fw-update.sh remove {}' + ONIE_FW_UPDATE_CMD_UPDATE = '/usr/bin/mlnx-onie-fw-update.sh update' + ONIE_FW_UPDATE_CMD_SHOW = '/usr/bin/mlnx-onie-fw-update.sh show-pending' BIOS_QUERY_VERSION_COMMAND = 'dmidecode -t 11' diff --git a/platform/mellanox/mlnx-ssd-fw-update.mk b/platform/mellanox/mlnx-ssd-fw-update.mk new file mode 100644 index 000000000000..f932e57d2521 --- /dev/null +++ b/platform/mellanox/mlnx-ssd-fw-update.mk @@ -0,0 +1,9 @@ +# ssd update tool + +MLNX_SSD_FW_UPDATE = mlnx-ssd-fw-update.sh +$(MLNX_SSD_FW_UPDATE)_PATH = platform/mellanox/ +SONIC_COPY_FILES += $(MLNX_SSD_FW_UPDATE) + +MLNX_FILES += $(MLNX_SSD_FW_UPDATE) + +export MLNX_SSD_FW_UPDATE diff --git a/platform/mellanox/mlnx-ssd-fw-update.sh b/platform/mellanox/mlnx-ssd-fw-update.sh new file mode 100755 index 000000000000..5163c8e7f8f7 --- /dev/null +++ b/platform/mellanox/mlnx-ssd-fw-update.sh @@ -0,0 +1,727 @@ +#!/bin/bash +######################################################################## +# Copyright (c) 2020 Mellanox Technologies. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the names of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# Alternatively, this software may be distributed under the terms of the +# GNU General Public License ("GPL") version 2 as published by the Free +# Software Foundation. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +#==============================================================================# +#= Global variable # +#= +#===== +VERSION="1.3" +#===== +SWITCH_SSD_DEV="/dev/sda" +UTIL_TITLE="This is MLNX SSD firmware update utility to read and write SSD FW. Version ${VERSION}" +DEPENDECIES=("smartctl" "sha256sum" "tar" "/bin/bash" "gpg" "sed" "realpath" "dirname") +TRUE="0" +FALSE="1" +ERR_MSG="ERR_MSG" +INI_PREFIX="ini_section_" +PUBLIC_CERT_NAME="trusted.gpg" +CHECKSUM_NAME="checksum" +SCRIPT_MODE="RELESE" # RELESE -or- DEBUG +DEBUG_MSG="DEBUG" # remove all instance after script is ready. +#===== +PKG_EXTRACTED=$FALSE +LOGGER_UTIL=$FALSE +SSD_FW_VER="" +SSD_DEVICE_MODEL="" +SSD_SERIAL="" +SSD_SIZE="" +SECTIONS=() +#===== +ARG_IMAGE_FLAG=$FALSE +ARG_IMAGE_VAL="" +ARG_QUERY_FLAG=$FALSE +ARG_YES_FLAG=$FALSE +ARG_POWER_CYCLE_FLAG=$FALSE +ARG_HELP_FLAG=$FALSE +ARG_VERSION_FLAG=$FALSE +ARG_PACKAGE_INFO_FLAG=$FALSE +ARG_UPDATE_FLAG=$FALSE + + + +#==============================================================================# +#= usage function. # +#= +function init_script() { +# check if logger utility supported + if [ -x "$(command -v logger)" ]; then + LOGGER_UTIL=$TRUE + else + LOGGER_UTIL=$FALSE + fi +} + +#==============================================================================# +#= usage function. # +#= +function usage() { + echo + echo -e "$UTIL_TITLE" + echo + echo -e "Usage:" + echo -e "\tmlnx_ssd_fw_update.sh [OPTION]" + echo -e "Commands:" + echo -e "\t-i, --image\t\t Path to SSD FW package" + echo -e "\t-q, --query\t\t Print SSD information (SSD model, serial number, version and size)" + echo -e "\t\t\t\t Combined with image, comparison is made if update is required" + echo -e "\t-p, --package-info\t Get package info" + echo -e "\t-u, --update\t\t Upgrade firmware" + echo -e "\t-y --yes\t\t Assume \"yes\" to all questions" + echo -e "\t-V, --version\t\t Print utility version" + echo -e "\t-h, --help\t\t Show this usage" + echo -e "\t --power-cycle\t Execute power cycle at completion, even if not required" + echo + echo -e "Example:" + echo -e "\tmlnx_ssd_fw_update.sh -q" + echo -e "\tmlnx_ssd_fw_update.sh -q -i mlnx_ssd_fw_package.pkg" + echo -e "\tmlnx_ssd_fw_update.sh -p -i mlnx_ssd_fw_package.pkg" + echo -e "\tmlnx_ssd_fw_update.sh -u -i mlnx_ssd_fw_package.pkg" + echo +} + +#==============================================================================# +#= Log function. # +#= +function LOG_MSG() { + if [ $# -gt 0 ]; then + LOG_STR=$1 + if [[ $# -eq 1 ]]; then + [[ "$LOGGER_UTIL" == "$TRUE" && "$LOG_STR" != "" ]] && logger -t mlnx_ssd_fw_update.sh -p user.notice $(echo "$LOG_STR" | sed 's/\\t//g') + echo -e "$LOG_STR" + elif [[ $# -eq 2 && "$2" == "$ERR_MSG" ]]; then + [[ "$LOGGER_UTIL" == "$TRUE" && "$LOG_STR" != "" ]] && logger -t mlnx_ssd_fw_update.sh -p user.err $(echo "$LOG_STR" | sed 's/\\t//g') + echo -e "$LOG_STR" + elif [[ $# -eq 2 && "$2" == "$SCRIPT_MODE" ]]; then + echo -e "DBG: $LOG_STR" + fi + fi +} + +#==============================================================================# +#= Log function. # +#= +function LOG_MSG_AND_EXIT() { + LOG_MSG "$@" "$ERR_MSG" + erase_extract_package "$extraction_path" + LOG_MSG "Exiting..." + exit 1 +} + +#==============================================================================# +#= This function check if given argument is valid and return boolean result. # +#= +function check_usage() { + local argument_count=$# + + LOG_MSG "Number of argument:$argument_count" ${DEBUG_MSG} + + if [ $# -eq 0 ]; then + LOG_MSG "Error: false usage given." + usage + exit 1 + fi + + while [[ $# -gt 0 ]] + do + key="$1" + + case $key in + -i|--image) + ARG_IMAGE_FLAG=$TRUE + ARG_IMAGE_VAL="$2" + shift # past argument + shift # past value + ;; + -q|--query) + ARG_QUERY_FLAG=$TRUE + shift # past argument + ;; + -y|--yes) + ARG_YES_FLAG=$TRUE + shift # past argument + ;; + -h|--help) + ARG_HELP_FLAG=$TRUE + shift # past argument + ;; + -V|--version) + ARG_VERSION_FLAG=$TRUE + shift # past argument + ;; + -u|--update) + ARG_UPDATE_FLAG=$TRUE + shift # past argument + ;; + -p|--package-info) + ARG_PACKAGE_INFO_FLAG=$TRUE + shift # past argument + ;; + --power-cycle) + ARG_POWER_CYCLE_FLAG=$TRUE + shift # past argument + ;; + *) + LOG_MSG "Error: false usage given." + usage + exit 1 + ;; + esac + done + + if [[ ("$ARG_IMAGE_FLAG" == "$TRUE" && ( $argument_count -lt 3 )) || + ("$ARG_IMAGE_FLAG" == "$TRUE" && ( $argument_count -gt 5 )) || + ("$ARG_PACKAGE_INFO_FLAG" == "$TRUE" && ( $argument_count -ne 3 )) || + ("$ARG_QUERY_FLAG" == "$TRUE" && ( $argument_count -lt 1 )) || + ("$ARG_QUERY_FLAG" == "$TRUE" && ( $argument_count -gt 3 )) || + ("$ARG_HELP_FLAG" == "$TRUE" && ( $argument_count -gt 1 )) || + ("$ARG_VERSION_FLAG" == "$TRUE" && ( $argument_count -gt 1 )) || + ("$ARG_IMAGE_FLAG" == "$TRUE" && "$ARG_IMAGE_VAL" == "") || + ("$ARG_UPDATE_FLAG" == "$TRUE" && "$ARG_IMAGE_FLAG" == "$FALSE") || + ("$ARG_PACKAGE_INFO_FLAG" == "$TRUE" && "$ARG_IMAGE_FLAG" == "$FALSE") || + ("$ARG_POWER_CYCLE_FLAG" == "$TRUE" && "$ARG_UPDATE_FLAG" == "$FALSE") || + ("$ARG_UPDATE_FLAG" == "$TRUE" && "$ARG_PACKAGE_INFO_FLAG" == "$TRUE") ]]; then + + LOG_MSG "Error: false usage given." + usage + exit 1 + fi + +### Debug message remove when script is done. + LOG_MSG "ARG_IMAGE_FLAG = ${ARG_IMAGE_FLAG}" ${DEBUG_MSG} + LOG_MSG "ARG_IMAGE_VAL = ${ARG_IMAGE_VAL}" ${DEBUG_MSG} + LOG_MSG "ARG_QUERY_FLAG = ${ARG_QUERY_FLAG}" ${DEBUG_MSG} + LOG_MSG "ARG_YES_FLAG = ${ARG_YES_FLAG}" ${DEBUG_MSG} + LOG_MSG "ARG_HELP_FLAG = ${ARG_HELP_FLAG}" ${DEBUG_MSG} + LOG_MSG "ARG_VERSION_FLAG = ${ARG_VERSION_FLAG}" ${DEBUG_MSG} + LOG_MSG "ARG_PACKAGE_INFO_FLAG = ${ARG_PACKAGE_INFO_FLAG}" ${DEBUG_MSG} + LOG_MSG "ARG_POWER_CYCLE_FLAG = ${ARG_POWER_CYCLE_FLAG}" ${DEBUG_MSG} + +} + +#==============================================================================# +# This function return SSD fw version using hdparm utility # +# +function get_ssd_fw_version() { + [ $1 ] || { LOG_MSG_AND_EXIT "Wrong usage - ${FUNCNAME[0]}()"; } + + local device_fw_version + device_fw_version=$(smartctl -i $SWITCH_SSD_DEV | grep -Po "Firmware Version: +\K[^,]+") + LOG_MSG "device_fw_version: $device_fw_version" ${DEBUG_MSG} + eval $1='$device_fw_version' +} + +#==============================================================================# +# This function return SSD device model using hdparm utility # +# +function get_ssd_device_model() { + [ $1 ] || { LOG_MSG_AND_EXIT "Wrong usage - ${FUNCNAME[0]}()"; } + + local device_model_name + device_model_name=$(smartctl -i $SWITCH_SSD_DEV | grep -Po "Device Model: +\K[^,]+") + LOG_MSG "device_model_name: $device_model_name" ${DEBUG_MSG} + eval $1='$device_model_name' +} + +#==============================================================================# +# This function return SSD size using hdparm utility # +# +function get_ssd_size() { + [ $1 ] || { LOG_MSG_AND_EXIT "Wrong usage - ${FUNCNAME[0]}()"; } + + local device_size + device_size=$(smartctl -i $SWITCH_SSD_DEV | grep -Po "User Capacity:.+bytes \[\K[^ ]+") + LOG_MSG "device_size: $device_size" ${DEBUG_MSG} + eval $1='$device_size' +} + +#==============================================================================# +# This function return SSD serial using hdparm utility # +# +function get_ssd_serial() { + [ $1 ] || { LOG_MSG_AND_EXIT "Wrong usage - ${FUNCNAME[0]}()"; } + + local device_serial + device_serial=$(smartctl -i $SWITCH_SSD_DEV | grep -Po "Serial Number: +\K[^,]+") + LOG_MSG "device_serial: $device_serial" ${DEBUG_MSG} + eval $1='$device_serial' +} + +#==============================================================================# +#= This function check if given argument is valid and return boolean result. # +#= +function get_ssd_info() { + LOG_MSG "func: ${FUNCNAME[0]}()" ${DEBUG_MSG} + get_ssd_fw_version SSD_FW_VER + get_ssd_device_model SSD_DEVICE_MODEL + get_ssd_serial SSD_SERIAL + get_ssd_size SSD_SIZE +} + +#==============================================================================# +#= This function check if given argument is valid and return boolean result. # +#= +function check_tool_dependencies() { + LOG_MSG "func: ${FUNCNAME[0]}()" ${DEBUG_MSG} + for i in "${!DEPENDECIES[@]}" + do + if [ ! -x "$(command -v ${DEPENDECIES[$i]})" ]; then + LOG_MSG_AND_EXIT "Error: This tool require the following utils to be installed ${DEPENDECIES[$i]}" + fi + done +} + +#==============================================================================# +#= This function parse package ini file and declare it attributes # +#= +function ini_parser { + LOG_MSG "func: ${FUNCNAME[0]}()" ${DEBUG_MSG} + + local filename="$1" + LOG_MSG "filename:$filename" ${DEBUG_MSG} + + shopt -p extglob &> /dev/null + CHANGE_EXTGLOB=$? + if [ $CHANGE_EXTGLOB = 1 ] + then + shopt -s extglob + fi + ini="$(<$filename)" # read the file + ini=${ini//$'\r'/} # remove linefeed i.e dos2unix + ini="${ini//[/\\[}" + ini="${ini//]/\\]}" + IFS=$'\n' && ini=( ${ini} ) # convert to line-array + ini=( ${ini[*]//\)/\\\)} ) # append / before any parenthesis + ini=( ${ini[*]//\(/\\\(} ) # append / before any parenthesis + ini=( ${ini[*]/#*([[:space:]]);*/} ) + ini=( ${ini[*]/#*([[:space:]])\#*/} ) + ini=( ${ini[*]/#+([[:space:]])/} ) # remove init whitespace + ini=( ${ini[*]/%+([[:space:]])/} ) # remove ending whitespace + ini=( ${ini[*]/*([[:space:]])=*([[:space:]])/=} ) # remove whitespace around = + ini=( ${ini[*]/#\\[/\}$'\n'"$INI_PREFIX"} ) # set section prefix + ini=( ${ini[*]/%\\]/ \(} ) # convert text2function (1) + ini=( ${ini[*]/=/=\( } ) # convert item to array + ini=( ${ini[*]/%/ \)} ) # close array parenthesis + ini=( ${ini[*]/%\\ \)/ \\} ) # the multiline trick + ini=( ${ini[*]/%\( \)/\(\) \{} ) # convert text2function (2) + ini=( ${ini[*]/%\} \)/\}} ) # remove extra parenthesis + ini=( ${ini[*]/%\{/\{$'\n''ini_unset ${FUNCNAME/#'$INI_PREFIX'}'$'\n'} ) # clean previous definition of section + ini[0]="" # remove first element + ini[${#ini[*]} + 1]='}' # add the last brace + eval "$(echo "${ini[*]}")" # eval the result + [ $? -ne 0 ] && LOG_MSG_AND_EXIT "Error: failed to parse package content." + SECTIONS="$(echo ${ini[*]} | grep -Po "$INI_PREFIX+\K[\w]+")" + if [ $CHANGE_EXTGLOB = 1 ] + then + shopt -u extglob + fi +} + +#==============================================================================# +#= This function unset parse ini section and variables # +#= +function ini_unset { + LOG_MSG "func: ${FUNCNAME[0]}()" ${DEBUG_MSG} + SECTION=$1 + OLDIFS="$IFS" + IFS=' '$'\n' + if [ -z "$SECTION" ] + then + fun="$(declare -F)" + else + fun="$(declare -F $INI_PREFIX$SECTION)" + if [ -z "$fun" ] + then + echo "section $SECTION not found" 1>&2 + return + fi + fi + fun="${fun//declare -f/}" + for f in $fun; do + [ "${f#$INI_PREFIX}" == "${f}" ] && continue + item="$(declare -f ${f})" + item="${item##*\{}" # remove function definition + item="${item##*FUNCNAME*$INI_PREFIX\};}" # remove clear section + item="${item/\}}" # remove function close + item="${item%)*}" # remove everything after parenthesis + item="${item});" # add close parenthesis + vars="" + while [ "$item" != "" ] + do + newvar="${item%%=*}" # get item name + vars="$vars $newvar" # add name to collection + item="${item#*;}" # remove readed line + done + for var in $vars; do + unset $var + done + done + IFS="$OLDIFS" +} + +#==============================================================================# +#= This function check package signing and returns back true or false # +#= +function check_package_signing() { + LOG_MSG "func: ${FUNCNAME[0]}()" ${DEBUG_MSG} + + [ $1 ] || { LOG_MSG_AND_EXIT "Wrong usage - ${FUNCNAME[0]}()"; } + + local package_path=$1 + local checksum_unsigned_file="$package_path/$CHECKSUM_NAME" + local checksum_signed_file="$package_path/$CHECKSUM_NAME.sig" + local public_cert_file="$package_path/$PUBLIC_CERT_NAME" + +### Check if unsigned checksum file exists + [ ! -f "$checksum_unsigned_file" ] && LOG_MSG_AND_EXIT "Error: fail to find unsigned checksum file to verify package signing." + +### Check if signed checksum file exists + [ ! -f "$checksum_signed_file" ] && LOG_MSG_AND_EXIT "Error: fail to find sign checksum file to verify package signing." + +### Check if public key exists + [ ! -f "$public_cert_file" ] && LOG_MSG_AND_EXIT "Error: fail to find public certificate to verify package signing." + + + LOG_MSG "public_cert_file: ${public_cert_file}" ${DEBUG_MSG} + LOG_MSG "checksum_signed_file: ${checksum_signed_file}" ${DEBUG_MSG} + LOG_MSG "checksum_unsigned_file: ${checksum_unsigned_file}" ${DEBUG_MSG} + + gpg --keyring "$public_cert_file" --verify "$checksum_signed_file" "$checksum_unsigned_file" > /dev/null 2>&1 + [ $? -ne 0 ] && LOG_MSG_AND_EXIT "Error: fault package signing." + + LOG_MSG "cd into: ${package_path}" ${DEBUG_MSG} + cd $package_path > /dev/null 2>&1 + sha256sum -c $CHECKSUM_NAME > /dev/null 2>&1 + [ $? -ne 0 ] && LOG_MSG_AND_EXIT "Error: fault package SHA signing, file has been compromised" + LOG_MSG "backing back:" ${DEBUG_MSG} + cd - > /dev/null 2>&1 + LOG_MSG "exiting:" ${DEBUG_MSG} + +} + +#==============================================================================# +#= This function prints supported SSD from package ini # +#= +function string_supported_model() { + + local section=$1 + + if [[ ! -z "${Vendor[*]}" ]] && [[ ! -z "${SSD_FW_Model[*]}" ]] && [[ ! -z "${SSD_FW_Version[*]}" ]] \ + && [[ ! -z "${SSD_Size[*]}" ]] && [[ ! -z ${Shutdown_Policy[*]} ]]; then + printf 'o %-10s | %-30s | %-12s | %-6sGB | %-7s |\n' \ + "$( IFS=$'\n'; echo "${Vendor[@]}" )" "$( IFS=$'\n'; echo "${SSD_FW_Model[@]}" )" \ + "${SSD_FW_Version[@]}" "${SSD_Size[@]}" "${Shutdown_Policy[@],,}" + fi + +} + +#==============================================================================# +#= This function extract SSD FW package into /tmp # +#= +function extract_package() { + LOG_MSG "func: ${FUNCNAME[0]}()" ${DEBUG_MSG} + + local filename=$1 + LOG_MSG "filename:$filename" ${DEBUG_MSG} +### Check if file exists + [ ! -f $filename ] && LOG_MSG_AND_EXIT "Error: given file ($filename) not found." +### Check if tmp available + [ ! -d "/tmp" ] && LOG_MSG_AND_EXIT "Error: directory /tmp DOES NOT exists." + + local base_filename="${filename##*/}" + local folder_name="/tmp/""${base_filename%%.*}" + +### Check if full path available + if [ -d $folder_name ]; then + LOG_MSG "Path:$folder_name already exists, removing folder." ${DEBUG_MSG} + rm -rf ${folder_name} + [ $? -ne 0 ] && LOG_MSG_AND_EXIT "Error: folder:$folder_name is already in use and can't be overwrite, please remove it and retry." + fi + + mkdir ${folder_name} && tar xf ${filename} -C ${folder_name} --strip-components 1 --warning=no-timestamp > /dev/null 2>&1 + #tar -xf $filename --directory /tmp/ --warning=no-timestamp > /dev/null 2>&1 +### Check if untar succeed. + [ $? -ne 0 ] && LOG_MSG_AND_EXIT "Error: fail to extract given package ($filename)." + +### return the path file extraction is + # local base_filename="${filename##*/}" + # local folder_name="/tmp/""${base_filename%%.*}" + eval $2="$folder_name" + + PKG_EXTRACTED=$TRUE + + check_package_signing $folder_name + + LOG_MSG "successfully untar file." ${DEBUG_MSG} +} + +#==============================================================================# +#= This function extract SSD FW package into /tmp # +#= +function erase_extract_package() { + LOG_MSG "func: ${FUNCNAME[0]}()" ${DEBUG_MSG} + + [[ "$PKG_EXTRACTED" == "$FALSE" ]] && return + + local folder_name=$1 + + LOG_MSG "folder_name: $folder_name" ${DEBUG_MSG} + +### Check if folder exists + if [ ! -d "$folder_name" ]; then + LOG_MSG "Error: directory $folder_name DOES NOT exists." "$ERR_MSG" + LOG_MSG "Exiting..." + exit 1 + fi + rm -rf $folder_name +### Check if untar succeed. + if [ $? -ne 0 ]; then + LOG_MSG "Error: fail to delete $folder_name folder." "$ERR_MSG" + LOG_MSG "Exiting..." + exit 1 + fi + + PKG_EXTRACTED=$FALSE + LOG_MSG "successfully removed folder:$folder_name" ${DEBUG_MSG} +} + + +#==============================================================================# +#= This function returns back ini section array. +#= +function call_ini_section() { + LOG_MSG "func: ${FUNCNAME[0]}()" ${DEBUG_MSG} + + local ini_section=$1 + LOG_MSG "ini_section:$ini_section" ${DEBUG_MSG} + + [[ -z "$ini_section" ]] && LOG_MSG_AND_EXIT "Error: given INI section is null." + [[ -z "$(declare -F "$INI_PREFIX$ini_section")" ]] && LOG_MSG_AND_EXIT "Error: $ini_section section is missing in INI file." + + eval "$(echo "$INI_PREFIX$ini_section")" # call given section function. +} + +#==============================================================================# +#= This function prints ssd info +#= +function print_ssd_info() { + LOG_MSG "func: ${FUNCNAME[0]}()" ${DEBUG_MSG} + + local argument_count=$# + + if [ $argument_count -eq 2 ]; then + local newer_fw_version=$1 + local power_policy=$2 + LOG_MSG "Device Model\t\t : $SSD_DEVICE_MODEL" + LOG_MSG "Serial Number\t\t : $SSD_SERIAL" + LOG_MSG "User Capacity\t\t : $SSD_SIZE GB" + LOG_MSG "Current Firmware Version : $SSD_FW_VER" + LOG_MSG "Available Firmware Version : $Newer_FW_Version" + LOG_MSG "Power Cycle Required\t : $power_policy" + LOG_MSG "Upgrade Required\t : yes" + elif [ $argument_count -eq 1 ]; then + local _upgrade_require=$1 + LOG_MSG "Device Model\t : $SSD_DEVICE_MODEL" + LOG_MSG "Serial Number\t : $SSD_SERIAL" + LOG_MSG "User Capacity\t : $SSD_SIZE GB" + LOG_MSG "Firmware Version : $SSD_FW_VER" + LOG_MSG "Upgrade Required : $_upgrade_require" + else + LOG_MSG "Device Model\t : $SSD_DEVICE_MODEL" + LOG_MSG "Serial Number\t : $SSD_SERIAL" + LOG_MSG "User Capacity\t : $SSD_SIZE GB" + LOG_MSG "Firmware Version : $SSD_FW_VER" + fi +} + +# Main +# ------------------------------------------------------------------------------ +init_script +check_usage "$@" + +# show help +if [ $ARG_HELP_FLAG == $TRUE ]; then + usage + exit 0 +# show version +elif [ $ARG_VERSION_FLAG == $TRUE ]; then + echo $UTIL_TITLE + exit 0 +# show SSD info +elif [ $ARG_QUERY_FLAG == $TRUE ]; then + match_found=$FALSE + check_tool_dependencies + get_ssd_info + + if [ $ARG_IMAGE_FLAG == $TRUE ]; then + extract_package $ARG_IMAGE_VAL extraction_path + ini_parser "$extraction_path/list.ini" + + for section in $SECTIONS; do + if [[ $section != "main" ]]; then + call_ini_section $section + if [[ "$SSD_DEVICE_MODEL" == "$( IFS=$'\n'; echo "${SSD_FW_Model[@]}" )" ]] && \ + [[ "$SSD_FW_VER" == "${SSD_FW_Version[@]}" ]] && \ + [[ "$SSD_SIZE" == "${SSD_Size[@]}" ]]; then + + match_found=$TRUE + break + fi + ini_unset $section + fi + done + + erase_extract_package "$extraction_path" + if [[ "$match_found" == "$FALSE" ]]; then + #LOG_MSG "SSD FW upgrade not require, based on given package latest version is in used." + print_ssd_info "no" + echo -e "" + exit 0 + fi + fi + + if [[ "$match_found" == "$TRUE" ]]; then + print_ssd_info $Newer_FW_Version ${Shutdown_Policy[0],,} + erase_extract_package "$extraction_path" + else + print_ssd_info + fi + + echo -e "" + + exit 0 +# show package version +elif [ $ARG_PACKAGE_INFO_FLAG == $TRUE ]; then + check_tool_dependencies + extract_package $ARG_IMAGE_VAL extraction_path + # 2. check signing + ini_parser "$extraction_path/list.ini" + + call_ini_section "main" + LOG_MSG "Package Name: $ARG_IMAGE_VAL" + [[ ! -z ${description[@]} ]] && LOG_MSG "Description: ${description[@]}" + [[ ! -z ${version[@]} ]] && LOG_MSG "Version: ${version[@]}" + [[ ! -z ${release_date[@]} ]] && LOG_MSG "Release Date: ${release_date[@]}" + LOG_MSG "Supported SSDs:" + LOG_MSG " Vendor | Model | FW ver | Size | Pwr Cyc Req |" + LOG_MSG "=============|================================|==============|==========|=============|" + for section in $SECTIONS; do + if [[ "$section" != "main" ]]; then + call_ini_section $section + supported_model=$(string_supported_model $section) + LOG_MSG "$supported_model" + ini_unset $section + fi + done + echo -e "" + erase_extract_package "$extraction_path" + exit 0 +# operate SSD fw update +elif [ $ARG_UPDATE_FLAG == $TRUE ]; then + check_tool_dependencies + get_ssd_info + extract_package $ARG_IMAGE_VAL extraction_path + # 2. check signing + UPDATE_DONE=$FALSE + ini_parser "$extraction_path/list.ini" + for section in $SECTIONS; do + if [[ $section != "main" ]]; then + call_ini_section $section + if [[ "$SSD_DEVICE_MODEL" == "$( IFS=$'\n'; echo "${SSD_FW_Model[@]}" )" ]] && \ + [[ "$SSD_FW_VER" == "${SSD_FW_Version[@]}" ]] && \ + [[ "$SSD_SIZE" == "${SSD_Size[@]}" ]]; then + UPDATE_DONE=$TRUE + + power_policy=${Shutdown_Policy[0],,} + LOG_MSG "Power policy:$power_policy" ${DEBUG_MSG} + print_ssd_info $Newer_FW_Version ${Shutdown_Policy[0],,} + echo -e "" + #[[ "yes" == "$power_policy" ]] && LOG_MSG "PLEASE NOTE: System will power-cycle automatically once SSD FW Update complete!" + [[ "yes" == "$power_policy" || "$ARG_POWER_CYCLE_FLAG" == "$TRUE" ]] && LOG_MSG "Please note: Once SSD FW Update process ends, system will power-cycle automaticly and it will take up to 1 minute to access it back." + + # Prompt approval for FW update if ignore in case "yes" flag is on. + if [[ "$ARG_YES_FLAG" == "$FALSE" ]]; then + read -p "Do you want to continue? [Y/N]" -n 1 -r + echo # (optional) move to a new line + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + LOG_MSG_AND_EXIT "Aborting..." + exit 0 + fi + fi + + # Check FWUpgrade scripts exists & if so call it. + ssd_script_name=$Update_Script + ssd_script_path="${extraction_path}/${section}/${ssd_script_name}" + LOG_MSG "ssd_script_path: $ssd_script_path" ${DEBUG_MSG} + if [ ! -f $ssd_script_path ]; then + LOG_MSG_AND_EXIT "Error: fail to call upgrade script ($ssd_script_path)!" + fi + ( + cd "${extraction_path}/${section}" > /dev/null 2>&1 || exit + /bin/bash "$ssd_script_path" "${extraction_path}/${section}" + #cd - > /dev/null 2>&1 || exit + ) + if [ $? -ne 0 ]; then + LOG_MSG_AND_EXIT "Error: SSD FW update failed." + else + LOG_MSG "SSD FW update completed successfully." + + if [ $ARG_POWER_CYCLE_FLAG == $TRUE ]; then + LOG_MSG "Execute power cycle..." + sleep 1 + sync + power_cycle_script="${extraction_path}/common/mlnx_shutdown.sh" + [ ! -f $power_cycle_script ]&& LOG_MSG_AND_EXIT "Error: failed to initiate power cycle." + ($power_cycle_script "-s") + [ $? -ne 0 ] && LOG_MSG_AND_EXIT "Error: failed to power cycle the system automatically." + erase_extract_package "$extraction_path" + + fi + + fi + + break # Exit the for loop + fi + ini_unset $section + fi + done + if [ $UPDATE_DONE == $FALSE ]; then + LOG_MSG "SSD FW upgrade not require, based on given package latest version is in used." + print_ssd_info "no" + fi + + echo -e "" + erase_extract_package "$extraction_path" + exit 0 +fi + +exit 0 diff --git a/platform/mellanox/one-image.mk b/platform/mellanox/one-image.mk index e4723c3bd1b0..0f69b7335bf1 100644 --- a/platform/mellanox/one-image.mk +++ b/platform/mellanox/one-image.mk @@ -11,5 +11,5 @@ $(SONIC_ONE_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.g else $(SONIC_ONE_IMAGE)_DOCKERS = $(SONIC_INSTALL_DOCKER_IMAGES) endif -$(SONIC_ONE_IMAGE)_FILES += $(MLNX_FW_FILES) $(MLNX_FFB_SCRIPT) $(ISSU_VERSION_FILE) $(ONIE_FW_UPDATE) +$(SONIC_ONE_IMAGE)_FILES += $(MLNX_FILES) SONIC_INSTALLERS += $(SONIC_ONE_IMAGE) diff --git a/platform/mellanox/onie-fw-update.mk b/platform/mellanox/onie-fw-update.mk deleted file mode 100644 index 160f1c98f7b1..000000000000 --- a/platform/mellanox/onie-fw-update.mk +++ /dev/null @@ -1,7 +0,0 @@ -# bios update tool - -ONIE_FW_UPDATE= onie-fw-update -$(ONIE_FW_UPDATE)_PATH = platform/mellanox/ -SONIC_COPY_FILES += $(ONIE_FW_UPDATE) - -export ONIE_FW_UPDATE diff --git a/platform/mellanox/rules.mk b/platform/mellanox/rules.mk index efd0af2c8f4a..bdb4e955c2d4 100644 --- a/platform/mellanox/rules.mk +++ b/platform/mellanox/rules.mk @@ -12,7 +12,8 @@ include $(PLATFORM_PATH)/libsaithrift-dev.mk include $(PLATFORM_PATH)/docker-ptf-mlnx.mk include $(PLATFORM_PATH)/mlnx-ffb.mk include $(PLATFORM_PATH)/issu-version.mk -include $(PLATFORM_PATH)/onie-fw-update.mk +include $(PLATFORM_PATH)/mlnx-onie-fw-update.mk +include $(PLATFORM_PATH)/mlnx-ssd-fw-update.mk SONIC_ALL += $(SONIC_ONE_IMAGE) \ $(DOCKER_FPM) From 68448856a723679b5a4df2592284883af361f59e Mon Sep 17 00:00:00 2001 From: noaOrMlnx <58519608+noaOrMlnx@users.noreply.github.com> Date: Mon, 30 Mar 2020 19:24:16 +0300 Subject: [PATCH 159/178] Bug fix: #4011 #4012 - "show run acl", "show run interfaces" - traceback when no ACL_RULE/INTERFACE is present. (#4226) * Fix bugs - "show run acl/interfaces" returns traceback when no ACL_RULE/INTERFACE is present in configuration - Change logic in main to take data only if the var_json appears in DB. - Add unit testing for bug fix & fix comments Signed-off-by: Noa Or --- src/sonic-config-engine/sonic-cfggen | 2 +- src/sonic-config-engine/tests/test_cfggen.py | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index 34f5a36f0fe3..6000aefb4245 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -295,7 +295,7 @@ def main(): template = jinja2.Template('{{' + args.var + '}}') print(template.render(data)) - if args.var_json != None: + if args.var_json != None and args.var_json in data: if args.key != None: print(json.dumps(FormatConverter.to_serialized(data[args.var_json], args.key), indent=4, cls=minigraph_encoder)) else: diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index 2ae28946a905..7f5eb155092f 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -331,3 +331,13 @@ def test_minigraph_sub_port_interfaces(self, check_stderr=True): output = subprocess.check_output("sed -i \'s/%s/%s/g\' %s" % (BACKEND_TOR_ROUTER, TOR_ROUTER, self.sample_graph_simple), shell=True) self.test_jinja_expression(self.sample_graph_simple, TOR_ROUTER) + + def test_show_run_acl(self): + argument = '-a \'{"key1":"value"}\' --var-json ACL_RULE' + output = self.run_script(argument) + self.assertEqual(output, '') + + def test_show_run_interfaces(self): + argument = '-a \'{"key1":"value"}\' --var-json INTERFACE' + output = self.run_script(argument) + self.assertEqual(output, '') From 0099305475759c3cf70561495ae3483aa42a2b07 Mon Sep 17 00:00:00 2001 From: SuvarnaMeenakshi <50386592+SuvarnaMeenakshi@users.noreply.github.com> Date: Tue, 31 Mar 2020 10:06:19 -0700 Subject: [PATCH 160/178] Multi-ASIC implementation (#3888) Changes made to support multi-asic platform. Added multi-instance support for swss, syncd, database, bgp, teamd and lldp. --- .../msft_multi_asic_vs/0/lanemap.ini | 32 ++++++ .../msft_multi_asic_vs/0/sai.profile | 7 +- .../msft_multi_asic_vs/1/lanemap.ini | 32 ++++++ .../msft_multi_asic_vs/1/sai.profile | 7 +- .../msft_multi_asic_vs/2/lanemap.ini | 32 ++++++ .../msft_multi_asic_vs/2/sai.profile | 7 +- .../msft_multi_asic_vs/3/lanemap.ini | 32 ++++++ .../msft_multi_asic_vs/3/sai.profile | 7 +- .../msft_multi_asic_vs/4/lanemap.ini | 32 ++++++ .../msft_multi_asic_vs/4/sai.profile | 7 +- .../msft_multi_asic_vs/5/lanemap.ini | 32 ++++++ .../msft_multi_asic_vs/5/sai.profile | 7 +- .../msft_multi_asic_vs/topology.sh | 13 +-- dockers/docker-fpm-frr/bgpd.conf.default.j2 | 20 ++++ files/build_templates/database.service.j2 | 1 + files/build_templates/docker_image_ctl.j2 | 69 +++++++----- files/build_templates/lldp.service.j2 | 18 ---- .../per_namespace/bgp.service.j2 | 21 ++++ .../per_namespace/database.service.j2 | 22 ++++ .../per_namespace/lldp.service.j2 | 22 ++++ .../per_namespace/swss.service.j2 | 31 ++++++ .../per_namespace/syncd.service.j2 | 33 ++++++ .../per_namespace/teamd.service.j2 | 19 ++++ .../single_instance/bgp.service.j2 | 18 ---- .../single_instance/database.service.j2 | 18 ---- .../single_instance/swss.service.j2 | 25 ----- .../single_instance/syncd.service.j2 | 30 ------ .../single_instance/teamd.service.j2 | 18 ---- .../build_templates/sonic_debian_extension.j2 | 4 + files/image_config/topology/topology.sh | 18 ++-- files/scripts/sonic-netns-exec | 12 +++ files/scripts/swss.sh | 100 ++++++++++++------ files/scripts/syncd.sh | 55 ++++++---- platform/vs/sonic_multiasic.xml | 2 +- rules/docker-fpm-frr.mk | 1 - slave.mk | 28 +++-- 36 files changed, 586 insertions(+), 246 deletions(-) create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/lanemap.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/lanemap.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/lanemap.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/lanemap.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/lanemap.ini create mode 100644 device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/lanemap.ini create mode 120000 files/build_templates/database.service.j2 delete mode 100644 files/build_templates/lldp.service.j2 create mode 100644 files/build_templates/per_namespace/bgp.service.j2 create mode 100644 files/build_templates/per_namespace/database.service.j2 create mode 100644 files/build_templates/per_namespace/lldp.service.j2 create mode 100644 files/build_templates/per_namespace/swss.service.j2 create mode 100644 files/build_templates/per_namespace/syncd.service.j2 create mode 100644 files/build_templates/per_namespace/teamd.service.j2 delete mode 100644 files/build_templates/single_instance/bgp.service.j2 delete mode 100644 files/build_templates/single_instance/database.service.j2 delete mode 100644 files/build_templates/single_instance/swss.service.j2 delete mode 100644 files/build_templates/single_instance/syncd.service.j2 delete mode 100644 files/build_templates/single_instance/teamd.service.j2 create mode 100755 files/scripts/sonic-netns-exec diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/lanemap.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/lanemap.ini new file mode 100644 index 000000000000..36278a01778c --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/lanemap.ini @@ -0,0 +1,32 @@ +eth1:25,26,27,28 +eth2:29,30,31,32 +eth3:33,34,35,36 +eth4:37,38,39,40 +eth5:45,46,47,48 +eth6:41,42,43,44 +eth7:1,2,3,4 +eth8:5,6,7,8 +eth9:13,14,15,16 +eth10:9,10,11,12 +eth11:17,18,19,20 +eth12:21,22,23,24 +eth13:53,54,55,56 +eth14:49,50,51,52 +eth15:57,58,59,60 +eth16:61,62,63,64 +eth17:69,70,71,72 +eth18:65,66,67,68 +eth19:73,74,75,76 +eth20:77,78,79,80 +eth21:109,110,111,112 +eth22:105,106,107,108 +eth23:113,114,115,116 +eth24:117,118,119,120 +eth25:125,126,127,128 +eth26:121,122,123,124 +eth27:81,82,83,84 +eth28:85,86,87,88 +eth29:93,94,95,96 +eth30:89,90,91,92 +eth31:101,102,103,104 +eth32:97,98,99,100 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/sai.profile index 52e2e289af60..bfc466f27e54 100644 --- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/sai.profile +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/sai.profile @@ -1,2 +1,5 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm -SAI_NUM_ECMP_MEMBERS=32 +SAI_WARM_BOOT_READ_FILE=/var/cache/sai_warmboot.bin +SAI_WARM_BOOT_WRITE_FILE=/var/cache/sai_warmboot.bin +SAI_VS_SWITCH_TYPE=SAI_VS_SWITCH_TYPE_BCM56850 +SAI_VS_HOSTIF_USE_TAP_DEVICE=true +SAI_VS_INTERFACE_LANE_MAP_FILE=/usr/share/sonic/hwsku/lanemap.ini diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/lanemap.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/lanemap.ini new file mode 100644 index 000000000000..36278a01778c --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/lanemap.ini @@ -0,0 +1,32 @@ +eth1:25,26,27,28 +eth2:29,30,31,32 +eth3:33,34,35,36 +eth4:37,38,39,40 +eth5:45,46,47,48 +eth6:41,42,43,44 +eth7:1,2,3,4 +eth8:5,6,7,8 +eth9:13,14,15,16 +eth10:9,10,11,12 +eth11:17,18,19,20 +eth12:21,22,23,24 +eth13:53,54,55,56 +eth14:49,50,51,52 +eth15:57,58,59,60 +eth16:61,62,63,64 +eth17:69,70,71,72 +eth18:65,66,67,68 +eth19:73,74,75,76 +eth20:77,78,79,80 +eth21:109,110,111,112 +eth22:105,106,107,108 +eth23:113,114,115,116 +eth24:117,118,119,120 +eth25:125,126,127,128 +eth26:121,122,123,124 +eth27:81,82,83,84 +eth28:85,86,87,88 +eth29:93,94,95,96 +eth30:89,90,91,92 +eth31:101,102,103,104 +eth32:97,98,99,100 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/sai.profile index 52e2e289af60..bfc466f27e54 100644 --- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/sai.profile +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/sai.profile @@ -1,2 +1,5 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm -SAI_NUM_ECMP_MEMBERS=32 +SAI_WARM_BOOT_READ_FILE=/var/cache/sai_warmboot.bin +SAI_WARM_BOOT_WRITE_FILE=/var/cache/sai_warmboot.bin +SAI_VS_SWITCH_TYPE=SAI_VS_SWITCH_TYPE_BCM56850 +SAI_VS_HOSTIF_USE_TAP_DEVICE=true +SAI_VS_INTERFACE_LANE_MAP_FILE=/usr/share/sonic/hwsku/lanemap.ini diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/lanemap.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/lanemap.ini new file mode 100644 index 000000000000..36278a01778c --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/lanemap.ini @@ -0,0 +1,32 @@ +eth1:25,26,27,28 +eth2:29,30,31,32 +eth3:33,34,35,36 +eth4:37,38,39,40 +eth5:45,46,47,48 +eth6:41,42,43,44 +eth7:1,2,3,4 +eth8:5,6,7,8 +eth9:13,14,15,16 +eth10:9,10,11,12 +eth11:17,18,19,20 +eth12:21,22,23,24 +eth13:53,54,55,56 +eth14:49,50,51,52 +eth15:57,58,59,60 +eth16:61,62,63,64 +eth17:69,70,71,72 +eth18:65,66,67,68 +eth19:73,74,75,76 +eth20:77,78,79,80 +eth21:109,110,111,112 +eth22:105,106,107,108 +eth23:113,114,115,116 +eth24:117,118,119,120 +eth25:125,126,127,128 +eth26:121,122,123,124 +eth27:81,82,83,84 +eth28:85,86,87,88 +eth29:93,94,95,96 +eth30:89,90,91,92 +eth31:101,102,103,104 +eth32:97,98,99,100 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/sai.profile index 52e2e289af60..bfc466f27e54 100644 --- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/sai.profile +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/sai.profile @@ -1,2 +1,5 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm -SAI_NUM_ECMP_MEMBERS=32 +SAI_WARM_BOOT_READ_FILE=/var/cache/sai_warmboot.bin +SAI_WARM_BOOT_WRITE_FILE=/var/cache/sai_warmboot.bin +SAI_VS_SWITCH_TYPE=SAI_VS_SWITCH_TYPE_BCM56850 +SAI_VS_HOSTIF_USE_TAP_DEVICE=true +SAI_VS_INTERFACE_LANE_MAP_FILE=/usr/share/sonic/hwsku/lanemap.ini diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/lanemap.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/lanemap.ini new file mode 100644 index 000000000000..36278a01778c --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/lanemap.ini @@ -0,0 +1,32 @@ +eth1:25,26,27,28 +eth2:29,30,31,32 +eth3:33,34,35,36 +eth4:37,38,39,40 +eth5:45,46,47,48 +eth6:41,42,43,44 +eth7:1,2,3,4 +eth8:5,6,7,8 +eth9:13,14,15,16 +eth10:9,10,11,12 +eth11:17,18,19,20 +eth12:21,22,23,24 +eth13:53,54,55,56 +eth14:49,50,51,52 +eth15:57,58,59,60 +eth16:61,62,63,64 +eth17:69,70,71,72 +eth18:65,66,67,68 +eth19:73,74,75,76 +eth20:77,78,79,80 +eth21:109,110,111,112 +eth22:105,106,107,108 +eth23:113,114,115,116 +eth24:117,118,119,120 +eth25:125,126,127,128 +eth26:121,122,123,124 +eth27:81,82,83,84 +eth28:85,86,87,88 +eth29:93,94,95,96 +eth30:89,90,91,92 +eth31:101,102,103,104 +eth32:97,98,99,100 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/sai.profile index 52e2e289af60..bfc466f27e54 100644 --- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/sai.profile +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/sai.profile @@ -1,2 +1,5 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm -SAI_NUM_ECMP_MEMBERS=32 +SAI_WARM_BOOT_READ_FILE=/var/cache/sai_warmboot.bin +SAI_WARM_BOOT_WRITE_FILE=/var/cache/sai_warmboot.bin +SAI_VS_SWITCH_TYPE=SAI_VS_SWITCH_TYPE_BCM56850 +SAI_VS_HOSTIF_USE_TAP_DEVICE=true +SAI_VS_INTERFACE_LANE_MAP_FILE=/usr/share/sonic/hwsku/lanemap.ini diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/lanemap.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/lanemap.ini new file mode 100644 index 000000000000..36278a01778c --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/lanemap.ini @@ -0,0 +1,32 @@ +eth1:25,26,27,28 +eth2:29,30,31,32 +eth3:33,34,35,36 +eth4:37,38,39,40 +eth5:45,46,47,48 +eth6:41,42,43,44 +eth7:1,2,3,4 +eth8:5,6,7,8 +eth9:13,14,15,16 +eth10:9,10,11,12 +eth11:17,18,19,20 +eth12:21,22,23,24 +eth13:53,54,55,56 +eth14:49,50,51,52 +eth15:57,58,59,60 +eth16:61,62,63,64 +eth17:69,70,71,72 +eth18:65,66,67,68 +eth19:73,74,75,76 +eth20:77,78,79,80 +eth21:109,110,111,112 +eth22:105,106,107,108 +eth23:113,114,115,116 +eth24:117,118,119,120 +eth25:125,126,127,128 +eth26:121,122,123,124 +eth27:81,82,83,84 +eth28:85,86,87,88 +eth29:93,94,95,96 +eth30:89,90,91,92 +eth31:101,102,103,104 +eth32:97,98,99,100 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/sai.profile index 52e2e289af60..bfc466f27e54 100644 --- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/sai.profile +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/sai.profile @@ -1,2 +1,5 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm -SAI_NUM_ECMP_MEMBERS=32 +SAI_WARM_BOOT_READ_FILE=/var/cache/sai_warmboot.bin +SAI_WARM_BOOT_WRITE_FILE=/var/cache/sai_warmboot.bin +SAI_VS_SWITCH_TYPE=SAI_VS_SWITCH_TYPE_BCM56850 +SAI_VS_HOSTIF_USE_TAP_DEVICE=true +SAI_VS_INTERFACE_LANE_MAP_FILE=/usr/share/sonic/hwsku/lanemap.ini diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/lanemap.ini b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/lanemap.ini new file mode 100644 index 000000000000..36278a01778c --- /dev/null +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/lanemap.ini @@ -0,0 +1,32 @@ +eth1:25,26,27,28 +eth2:29,30,31,32 +eth3:33,34,35,36 +eth4:37,38,39,40 +eth5:45,46,47,48 +eth6:41,42,43,44 +eth7:1,2,3,4 +eth8:5,6,7,8 +eth9:13,14,15,16 +eth10:9,10,11,12 +eth11:17,18,19,20 +eth12:21,22,23,24 +eth13:53,54,55,56 +eth14:49,50,51,52 +eth15:57,58,59,60 +eth16:61,62,63,64 +eth17:69,70,71,72 +eth18:65,66,67,68 +eth19:73,74,75,76 +eth20:77,78,79,80 +eth21:109,110,111,112 +eth22:105,106,107,108 +eth23:113,114,115,116 +eth24:117,118,119,120 +eth25:125,126,127,128 +eth26:121,122,123,124 +eth27:81,82,83,84 +eth28:85,86,87,88 +eth29:93,94,95,96 +eth30:89,90,91,92 +eth31:101,102,103,104 +eth32:97,98,99,100 diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/sai.profile b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/sai.profile index 52e2e289af60..bfc466f27e54 100644 --- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/sai.profile +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/sai.profile @@ -1,2 +1,5 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td2-s6000-32x40G.config.bcm -SAI_NUM_ECMP_MEMBERS=32 +SAI_WARM_BOOT_READ_FILE=/var/cache/sai_warmboot.bin +SAI_WARM_BOOT_WRITE_FILE=/var/cache/sai_warmboot.bin +SAI_VS_SWITCH_TYPE=SAI_VS_SWITCH_TYPE_BCM56850 +SAI_VS_HOSTIF_USE_TAP_DEVICE=true +SAI_VS_INTERFACE_LANE_MAP_FILE=/usr/share/sonic/hwsku/lanemap.ini diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/topology.sh b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/topology.sh index 378f794190d4..cf70f3063189 100755 --- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/topology.sh +++ b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/topology.sh @@ -14,9 +14,10 @@ start () { # eth48 - eth63: asic5 for ASIC in `seq $FIRST_FRONTEND_ASIC $LAST_FRONTEND_ASIC`; do for NUM in `seq 1 16`; do - ORIG="eth$((16 * $ASIC + $NUM - 1))" + ORIG="eth$((16 * $ASIC + $NUM))" TEMP="ethTemp999" - NEW="eth$(($NUM + 16))" + NEW="eth$(($NUM))" + echo "$ASIC : $NEW old $ORIG" ip link set dev $ORIG down ip link set dev $ORIG name $TEMP # rename to prevent conflicts before renaming in new namespace ip link set dev $TEMP netns asic$ASIC @@ -29,8 +30,9 @@ start () { for BACKEND in `seq $FIRST_BACKEND_ASIC $LAST_BACKEND_ASIC`; do for FRONTEND in `seq $FIRST_FRONTEND_ASIC $LAST_FRONTEND_ASIC`; do for LINK in `seq 1 8`; do - BACK_NAME="eth$((8 * $FRONTEND + $LINK))" - FRONT_NAME="eth$((8 * $(($LAST_BACKEND_ASIC - $BACKEND)) + $LINK))" + FRONT_NAME="eth$((8 * $(($BACKEND - $FIRST_BACKEND_ASIC)) + $LINK + 16))" + BACK_NAME="eth$((8 * $FRONTEND + $LINK))" + echo "$FRONTEND:$FRONT_NAME - $BACKEND:$BACK_NAME" TEMP_BACK="ethBack999" TEMP_FRONT="ethFront999" @@ -52,7 +54,7 @@ stop() { for ASIC in `seq $FIRST_FRONTEND_ASIC $LAST_FRONTEND_ASIC`; do for NUM in `seq 1 16`; do TEMP="eth999" - OLD="eth$(($NUM + 16))" + OLD="eth$((16 * $ASIC + $NUM))" NAME="eth$((16 * $ASIC + $NUM - 1))" sudo ip netns exec asic$ASIC ip link set dev $OLD down sudo ip netns exec asic$ASIC ip link set dev $OLD name $TEMP @@ -78,4 +80,3 @@ case "$1" in echo "Usage: $0 {start|stop}" ;; esac - diff --git a/dockers/docker-fpm-frr/bgpd.conf.default.j2 b/dockers/docker-fpm-frr/bgpd.conf.default.j2 index e12782b035aa..2bf80b80a787 100644 --- a/dockers/docker-fpm-frr/bgpd.conf.default.j2 +++ b/dockers/docker-fpm-frr/bgpd.conf.default.j2 @@ -23,6 +23,20 @@ route-map TO_BGP_PEER_V4 permit 100 ! route-map TO_BGP_PEER_V6 permit 100 ! +{% if DEVICE_METADATA['localhost']['type'] == 'InternalFrontend' %} +route-map HIDE_INTERNAL permit 10 + set community local-AS +! +{% endif %} +{% if DEVICE_METADATA['localhost']['type'] == 'InternalBackend' %} +route-map OVERRIDE_ORIGINATOR_ID permit 10 +{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} +{% if prefix | ipv4 and name == 'Loopback0' %} + set originator-id {{ prefix | ip }} +{% endif %} +{% endfor %} +! +{% endif %} {% if BGP_MONITORS is defined and BGP_MONITORS|length > 0 %} route-map FROM_BGPMON deny 10 ! @@ -37,6 +51,9 @@ route-map set-next-hop-global-v6 permit 10 set ipv6 next-hop prefer-global ! router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} +{% if DEVICE_METADATA['localhost']['type'] == 'InternalFrontend' %} + redistribute connected route-map HIDE_INTERNAL +{% endif %} bgp log-neighbor-changes bgp bestpath as-path multipath-relax no bgp default ipv4-unicast @@ -151,6 +168,9 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} neighbor {{ neighbor_addr }} peer-group BGPMON neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} neighbor {{ neighbor_addr }} activate +{% if DEVICE_METADATA['localhost']['type'] == 'InternalBackend' %} + neighbor {{ neighbor_addr }} route-map OVERRIDE_ORIGINATOR_ID in +{% endif %} address-family ipv6 neighbor {{ neighbor_addr }} activate exit-address-family diff --git a/files/build_templates/database.service.j2 b/files/build_templates/database.service.j2 new file mode 120000 index 000000000000..63340abef881 --- /dev/null +++ b/files/build_templates/database.service.j2 @@ -0,0 +1 @@ +per_namespace/database.service.j2 \ No newline at end of file diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 5de892555a1b..297c9dd1c2bd 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -14,15 +14,16 @@ link_namespace() { mkdir -p /var/run/netns PID="$(docker inspect -f {{"'{{.State.Pid}}'"}} "{{docker_container_name}}$DEV")" - if `ip netns | grep --quiet -w "{{docker_container_name}}$DEV"`; then # namespace exists - if [ $(readlink -f /var/run/netns/$NET_NS$DEV) = $(readlink -f /proc/$PID/ns/net) ]; then # namespace is correctly linked + PIDS=`ip netns pids "$NET_NS" 2>/dev/null` + if [ "$?" -eq "0" ]; then # namespace exists + if `echo $PIDS | grep --quiet -w $PID`; then # namespace is correctly linked return 0 else # if it's incorrectly linked remove it - ip netns delete "{{docker_container_name}}$DEV" + ip netns delete $NET_NS fi fi - ln -s /proc/$PID/ns/net /var/run/netns/$NET_NS$DEV + ln -s /proc/$PID/ns/net /var/run/netns/$NET_NS } {%- endif %} @@ -56,14 +57,14 @@ function preStartAction() WARM_DIR=/host/warmboot if [[ ("$BOOT_TYPE" == "warm" || "$BOOT_TYPE" == "fastfast") && -f $WARM_DIR/dump.rdb ]]; then # Load redis content from /host/warmboot/dump.rdb - docker cp $WARM_DIR/dump.rdb database:/var/lib/redis/dump.rdb + docker cp $WARM_DIR/dump.rdb database$DEV:/var/lib/redis/dump.rdb else # Create an emtpy file and overwrite any RDB if already there echo -n > /tmp/dump.rdb - docker cp /tmp/dump.rdb database:/var/lib/redis/ + docker cp /tmp/dump.rdb database$DEV:/var/lib/redis/ fi {%- elif docker_container_name == "snmp" %} - sonic-db-cli STATE_DB HSET 'DEVICE_METADATA|localhost' chassis_serial_number $(decode-syseeprom -s) + sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB HSET 'DEVICE_METADATA|localhost' chassis_serial_number $(decode-syseeprom -s) {%- else %} : # nothing {%- endif %} @@ -76,25 +77,25 @@ function postStartAction() link_namespace $DEV fi # Wait until redis starts - /usr/bin/docker exec database ping_pong_db_insts + /usr/bin/docker exec database$DEV ping_pong_db_insts if [[ ("$BOOT_TYPE" == "warm" || "$BOOT_TYPE" == "fastfast") && -f $WARM_DIR/dump.rdb ]]; then rm -f $WARM_DIR/dump.rdb else # If there is a config_db.json dump file, load it. - if [ -r /etc/sonic/config_db.json ]; then + if [ -r /etc/sonic/config_db$DEV.json ]; then if [ -r /etc/sonic/init_cfg.json ]; then - sonic-cfggen -j /etc/sonic/init_cfg.json -j /etc/sonic/config_db.json --write-to-db + sonic-netns-exec "$NET_NS" sonic-cfggen -j /etc/sonic/init_cfg.json -j /etc/sonic/config_db$DEV.json --write-to-db else - sonic-cfggen -j /etc/sonic/config_db.json --write-to-db + sonic-netns-exec "$NET_NS" sonic-cfggen -j /etc/sonic/config_db$DEV.json --write-to-db fi fi if [[ "$BOOT_TYPE" == "fast" ]]; then # set the key to expire in 3 minutes - sonic-db-cli STATE_DB SET "FAST_REBOOT|system" "1" "EX" "180" + /usr/bin/sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB SET "FAST_REBOOT|system" "1" "EX" "180" fi - sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" + /usr/bin/sonic-netns-exec "$NET_NS" sonic-db-cli CONFIG_DB SET "CONFIG_DB_INITIALIZED" "1" fi if [[ -x /usr/bin/db_migrator.py ]]; then @@ -102,14 +103,14 @@ function postStartAction() /usr/bin/db_migrator.py -o migrate fi {%- elif docker_container_name == "swss" %} - docker exec swss rm -f /ready # remove cruft + docker exec swss$DEV rm -f /ready # remove cruft if [[ "$BOOT_TYPE" == "fast" ]] && [[ -d /host/fast-reboot ]]; then - test -e /host/fast-reboot/fdb.json && docker cp /host/fast-reboot/fdb.json swss:/ - test -e /host/fast-reboot/arp.json && docker cp /host/fast-reboot/arp.json swss:/ - test -e /host/fast-reboot/default_routes.json && docker cp /host/fast-reboot/default_routes.json swss:/ + test -e /host/fast-reboot/fdb.json && docker cp /host/fast-reboot/fdb.json swss$DEV:/ + test -e /host/fast-reboot/arp.json && docker cp /host/fast-reboot/arp.json swss$DEV:/ + test -e /host/fast-reboot/default_routes.json && docker cp /host/fast-reboot/default_routes.json swss$DEV:/ rm -fr /host/fast-reboot fi - docker exec swss touch /ready # signal swssconfig.sh to go + docker exec swss$DEV touch /ready # signal swssconfig.sh to go {%- elif docker_container_name == "pmon" %} DEVPATH="/usr/share/sonic/device" @@ -131,14 +132,14 @@ start() { BOOT_TYPE=`getBootType` # Obtain our platform as we will mount directories with these names in each docker - PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` + PLATFORM=`sonic-netns-exec "$NET_NS" sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` {%- if docker_container_name == "database" %} # Don't mount HWSKU in {{docker_container_name}} container. HWSKU="" {%- else %} # Obtain our HWSKU as we will mount directories with these names in each docker - HWSKU=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hwsku"]'` + HWSKU=`sonic-netns-exec "$NET_NS" sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hwsku"]'` {%- endif %} DOCKERCHECK=`docker inspect --type container {{docker_container_name}}$DEV 2>/dev/null` @@ -185,7 +186,14 @@ start() { NET="container:database$DEV" {%- endif %} fi - +{%- if docker_container_name == "bgp" %} + if [ "$DEV" ]; then + if [ ! -d "/etc/sonic/frr/$DEV" ]; then + mkdir /etc/sonic/frr/$DEV + cp -r /etc/sonic/frr/*.conf /etc/sonic/frr/$DEV + fi + fi +{%- endif %} {%- if sonic_asic_platform == "mellanox" %} # TODO: Mellanox will remove the --tmpfs exception after SDK socket path changed in new SDK version {%- endif %} @@ -215,10 +223,13 @@ start() { --tmpfs /tmp \ {%- endif %} {%- endif %} - -v /var/run/redis:/var/run/redis:rw \ +{%- if docker_container_name == "bgp" %} + -v /etc/sonic/frr/$DEV:/etc/frr:rw \ +{%- endif %} + -v /var/run/redis$DEV:/var/run/redis:rw \ -v /usr/share/sonic/device/$PLATFORM:/usr/share/sonic/platform:ro \ {%- if docker_container_name != "database" %} - -v /usr/share/sonic/device/$PLATFORM/$HWSKU:/usr/share/sonic/hwsku:ro \ + -v /usr/share/sonic/device/$PLATFORM/$HWSKU/$DEV:/usr/share/sonic/hwsku:ro \ {%- endif %} {%- if sonic_asic_platform != "mellanox" %} --tmpfs /tmp \ @@ -230,7 +241,7 @@ start() { } preStartAction - docker start {{docker_container_name}} + docker start {{docker_container_name}}$DEV postStartAction } @@ -241,13 +252,19 @@ wait() { stop() { docker stop {{docker_container_name}}$DEV {%- if docker_container_name == "database" %} - ip netns delete "$NET_NS$DEV" + if [ "$DEV" ]; then + ip netns delete "$NET_NS" + fi {%- endif %} } OP=$1 DEV=$2 # namespace/device number to operate on -NET_NS="asic" #name of the network namespace +if [ "$DEV" ]; then + NET_NS="asic$DEV" #name of the network namespace +else + NET_NS="" +fi case "$1" in start|wait|stop) diff --git a/files/build_templates/lldp.service.j2 b/files/build_templates/lldp.service.j2 deleted file mode 100644 index 2599fc5c5bdc..000000000000 --- a/files/build_templates/lldp.service.j2 +++ /dev/null @@ -1,18 +0,0 @@ -[Unit] -Description=LLDP container -Requires=updategraph.service -After=updategraph.service swss.service syncd.service -Before=ntp-config.service -StartLimitIntervalSec=1200 -StartLimitBurst=3 - -[Service] -User={{ sonicadmin_user }} -ExecStartPre=/usr/bin/{{docker_container_name}}.sh start -ExecStart=/usr/bin/{{docker_container_name}}.sh wait -ExecStop=/usr/bin/{{docker_container_name}}.sh stop -Restart=always -RestartSec=30 - -[Install] -WantedBy=multi-user.target diff --git a/files/build_templates/per_namespace/bgp.service.j2 b/files/build_templates/per_namespace/bgp.service.j2 new file mode 100644 index 000000000000..79e9afc4ebc1 --- /dev/null +++ b/files/build_templates/per_namespace/bgp.service.j2 @@ -0,0 +1,21 @@ +[Unit] +Description=BGP container +Requires=database{% if multi_instance == 'true' %}@%i{% endif %}.service +After=database{% if multi_instance == 'true' %}@%i{% endif %}.service +Requires=updategraph.service +After=updategraph.service +Before=ntp-config.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 + +[Service] +User={{ sonicadmin_user }} +ExecStartPre=/usr/bin/{{docker_container_name}}.sh start{% if multi_instance == 'true' %} %i{% endif %} +ExecStart=/usr/bin/{{docker_container_name}}.sh wait{% if multi_instance == 'true' %} %i{% endif %} +ExecStop=/usr/bin/{{docker_container_name}}.sh stop{% if multi_instance == 'true' %} %i{% endif %} + +Restart=always +RestartSec=30 + +[Install] +WantedBy=multi-user.target diff --git a/files/build_templates/per_namespace/database.service.j2 b/files/build_templates/per_namespace/database.service.j2 new file mode 100644 index 000000000000..396fdc6678c2 --- /dev/null +++ b/files/build_templates/per_namespace/database.service.j2 @@ -0,0 +1,22 @@ +[Unit] +Description=Database container +{% if multi_instance == 'true' %} +Requires=database.service +After=database.service +{% endif %} +Requires=docker.service +After=docker.service +After=rc-local.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 + +[Service] +User=root +ExecStartPre=/usr/bin/{{docker_container_name}}.sh start{% if multi_instance == 'true' %} %i{% endif %} +ExecStart=/usr/bin/{{docker_container_name}}.sh wait{% if multi_instance == 'true' %} %i{% endif %} +ExecStop=/usr/bin/{{docker_container_name}}.sh stop{% if multi_instance == 'true' %} %i{% endif %} +Restart=always +RestartSec=30 + +[Install] +WantedBy=multi-user.target diff --git a/files/build_templates/per_namespace/lldp.service.j2 b/files/build_templates/per_namespace/lldp.service.j2 new file mode 100644 index 000000000000..b48675b03202 --- /dev/null +++ b/files/build_templates/per_namespace/lldp.service.j2 @@ -0,0 +1,22 @@ +[Unit] +Description=LLDP container +Requires=database{% if multi_instance == 'true' %}@%i{% endif %}.service +After=database{% if multi_instance == 'true' %}@%i{% endif %}.service +After=swss{% if multi_instance == 'true' %}@%i{% endif %}.service +After=syncd{% if multi_instance == 'true' %}@%i{% endif %}.service +Requires=updategraph.service +After=updategraph.service +Before=ntp-config.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 + +[Service] +User={{ sonicadmin_user }} +ExecStartPre=/usr/bin/{{docker_container_name}}.sh start{% if multi_instance == 'true' %} %i{% endif %} +ExecStart=/usr/bin/{{docker_container_name}}.sh wait{% if multi_instance == 'true' %} %i{% endif %} +ExecStop=/usr/bin/{{docker_container_name}}.sh stop{% if multi_instance == 'true' %} %i{% endif %} +Restart=always +RestartSec=30 + +[Install] +WantedBy=multi-user.target diff --git a/files/build_templates/per_namespace/swss.service.j2 b/files/build_templates/per_namespace/swss.service.j2 new file mode 100644 index 000000000000..53d6b4497df7 --- /dev/null +++ b/files/build_templates/per_namespace/swss.service.j2 @@ -0,0 +1,31 @@ +[Unit] +Description=switch state service +Requires=database{% if multi_instance == 'true' %}@%i{% endif %}.service +After=database{% if multi_instance == 'true' %}@%i{% endif %}.service +{% if multi_instance == 'true' and sonic_asic_platform == 'vs' %} +Requires=topology.service +After=topology.service +{% endif %} +{% if sonic_asic_platform == 'broadcom' %} +Requires=opennsl-modules.service +{% elif sonic_asic_platform == 'nephos' %} +Requires=nps-modules-4.9.0-11-2-amd64.service +{% endif %} +Requires=updategraph.service +After=updategraph.service +After=interfaces-config.service +Before=ntp-config.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 + +[Service] +User=root +Environment=sonic_asic_platform={{ sonic_asic_platform }} +ExecStartPre=/usr/local/bin/swss.sh start{% if multi_instance == 'true' %} %i{% endif %} +ExecStart=/usr/local/bin/swss.sh wait{% if multi_instance == 'true' %} %i{% endif %} +ExecStop=/usr/local/bin/swss.sh stop{% if multi_instance == 'true' %} %i{% endif %} +Restart=always +RestartSec=30 + +[Install] +WantedBy=multi-user.target diff --git a/files/build_templates/per_namespace/syncd.service.j2 b/files/build_templates/per_namespace/syncd.service.j2 new file mode 100644 index 000000000000..b2922e0d12b6 --- /dev/null +++ b/files/build_templates/per_namespace/syncd.service.j2 @@ -0,0 +1,33 @@ +[Unit] +Description=syncd service +Requires=database{% if multi_instance == 'true' %}@%i{% endif %}.service +After=database{% if multi_instance == 'true' %}@%i{% endif %}.service +After=swss{% if multi_instance == 'true' %}@%i{% endif %}.service +{% if multi_instance == 'true' and sonic_asic_platform == 'vs' %} +Requires=topology.service +After=topology.service +{% endif %} +{% if sonic_asic_platform == 'broadcom' %} +Requires=opennsl-modules.service +After=opennsl-modules.service +{% elif sonic_asic_platform == 'nephos' %} +Requires=nps-modules-4.9.0-11-2-amd64.service +After=nps-modules-4.9.0-11-2-amd64.service +{% endif %} +Requires=updategraph.service +After=updategraph.service +After=interfaces-config.service +Before=ntp-config.service + +[Service] +User=root +Environment=sonic_asic_platform={{ sonic_asic_platform }} +ExecStartPre=/usr/local/bin/syncd.sh start{% if multi_instance == 'true' %} %i{% endif %} +ExecStart=/usr/local/bin/syncd.sh wait{% if multi_instance == 'true' %} %i{% endif %} +ExecStop=/usr/local/bin/syncd.sh stop{% if multi_instance == 'true' %} %i{% endif %} +{% if sonic_asic_platform == 'mellanox' %} +TimeoutStartSec=150 +{% endif %} + +[Install] +WantedBy=multi-user.target diff --git a/files/build_templates/per_namespace/teamd.service.j2 b/files/build_templates/per_namespace/teamd.service.j2 new file mode 100644 index 000000000000..092f9d2ebde2 --- /dev/null +++ b/files/build_templates/per_namespace/teamd.service.j2 @@ -0,0 +1,19 @@ +[Unit] +Description=TEAMD container +After=swss{% if multi_instance == 'true' %}@%i{% endif %}.service +Requires=updategraph.service +After=updategraph.service +Before=ntp-config.service +StartLimitIntervalSec=1200 +StartLimitBurst=3 + +[Service] +User={{ sonicadmin_user }} +ExecStartPre=/usr/bin/{{docker_container_name}}.sh start{% if multi_instance == 'true' %} %i{% endif %} +ExecStart=/usr/bin/{{docker_container_name}}.sh wait{% if multi_instance == 'true' %} %i{% endif %} +ExecStop=/usr/bin/{{docker_container_name}}.sh stop{% if multi_instance == 'true' %} %i{% endif %} +Restart=always +RestartSec=30 + +[Install] +WantedBy=multi-user.target diff --git a/files/build_templates/single_instance/bgp.service.j2 b/files/build_templates/single_instance/bgp.service.j2 deleted file mode 100644 index fdf9d9c78c04..000000000000 --- a/files/build_templates/single_instance/bgp.service.j2 +++ /dev/null @@ -1,18 +0,0 @@ -[Unit] -Description=BGP container -Requires=updategraph.service -After=updategraph.service -Before=ntp-config.service -StartLimitIntervalSec=1200 -StartLimitBurst=3 - -[Service] -User={{ sonicadmin_user }} -ExecStartPre=/usr/bin/{{docker_container_name}}.sh start -ExecStart=/usr/bin/{{docker_container_name}}.sh wait -ExecStop=/usr/bin/{{docker_container_name}}.sh stop -Restart=always -RestartSec=30 - -[Install] -WantedBy=multi-user.target diff --git a/files/build_templates/single_instance/database.service.j2 b/files/build_templates/single_instance/database.service.j2 deleted file mode 100644 index fd0063195e31..000000000000 --- a/files/build_templates/single_instance/database.service.j2 +++ /dev/null @@ -1,18 +0,0 @@ -[Unit] -Description=Database container -Requires=docker.service -After=docker.service -After=rc-local.service -StartLimitIntervalSec=1200 -StartLimitBurst=3 - -[Service] -User=root -ExecStartPre=/usr/bin/{{docker_container_name}}.sh start -ExecStart=/usr/bin/{{docker_container_name}}.sh wait -ExecStop=/usr/bin/{{docker_container_name}}.sh stop -Restart=always -RestartSec=30 - -[Install] -WantedBy=multi-user.target diff --git a/files/build_templates/single_instance/swss.service.j2 b/files/build_templates/single_instance/swss.service.j2 deleted file mode 100644 index 44206b08ebce..000000000000 --- a/files/build_templates/single_instance/swss.service.j2 +++ /dev/null @@ -1,25 +0,0 @@ -[Unit] -Description=switch state service -Requires=database.service updategraph.service -{% if sonic_asic_platform == 'broadcom' %} -Requires=opennsl-modules.service -{% elif sonic_asic_platform == 'nephos' %} -Requires=nps-modules-4.9.0-11-2-amd64.service -{% endif %} -After=database.service updategraph.service -After=interfaces-config.service -Before=ntp-config.service -StartLimitIntervalSec=1200 -StartLimitBurst=3 - -[Service] -User=root -Environment=sonic_asic_platform={{ sonic_asic_platform }} -ExecStartPre=/usr/local/bin/swss.sh start -ExecStart=/usr/local/bin/swss.sh wait -ExecStop=/usr/local/bin/swss.sh stop -Restart=always -RestartSec=30 - -[Install] -WantedBy=multi-user.target diff --git a/files/build_templates/single_instance/syncd.service.j2 b/files/build_templates/single_instance/syncd.service.j2 deleted file mode 100644 index 7a7d27114b07..000000000000 --- a/files/build_templates/single_instance/syncd.service.j2 +++ /dev/null @@ -1,30 +0,0 @@ -[Unit] -Description=syncd service -Requires=database.service updategraph.service -{% if sonic_asic_platform == 'broadcom' %} -Requires=opennsl-modules.service -{% elif sonic_asic_platform == 'nephos' %} -Requires=nps-modules-4.9.0-11-2-amd64.service -{% endif %} -After=database.service updategraph.service -After=interfaces-config.service -{% if sonic_asic_platform == 'broadcom' %} -After=opennsl-modules.service -{% elif sonic_asic_platform == 'nephos' %} -After=nps-modules-4.9.0-11-2-amd64.service -{% endif %} -After=swss.service -Before=ntp-config.service - -[Service] -User=root -Environment=sonic_asic_platform={{ sonic_asic_platform }} -ExecStartPre=/usr/local/bin/syncd.sh start -ExecStart=/usr/local/bin/syncd.sh wait -ExecStop=/usr/local/bin/syncd.sh stop -{% if sonic_asic_platform == 'mellanox' %} -TimeoutStartSec=150 -{% endif %} - -[Install] -WantedBy=multi-user.target diff --git a/files/build_templates/single_instance/teamd.service.j2 b/files/build_templates/single_instance/teamd.service.j2 deleted file mode 100644 index be0521a4fbec..000000000000 --- a/files/build_templates/single_instance/teamd.service.j2 +++ /dev/null @@ -1,18 +0,0 @@ -[Unit] -Description=TEAMD container -Requires=updategraph.service -After=updategraph.service swss.service -Before=ntp-config.service -StartLimitIntervalSec=1200 -StartLimitBurst=3 - -[Service] -User={{ sonicadmin_user }} -ExecStartPre=/usr/bin/{{docker_container_name}}.sh start -ExecStart=/usr/bin/{{docker_container_name}}.sh wait -ExecStop=/usr/bin/{{docker_container_name}}.sh stop -Restart=always -RestartSec=30 - -[Install] -WantedBy=multi-user.target diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index fa6678ca1f8e..4b5234bc96a1 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -284,6 +284,7 @@ j2 files/build_templates/init_cfg.json.j2 | sudo tee $FILESYSTEM_ROOT/etc/sonic/ # Copy config-setup script and service file j2 files/build_templates/config-setup.service.j2 | sudo tee $FILESYSTEM_ROOT/etc/systemd/system/config-setup.service sudo cp $IMAGE_CONFIGS/config-setup/config-setup $FILESYSTEM_ROOT/usr/bin/config-setup +echo "config-setup.service" | sudo tee -a $GENERATED_SERVICE_FILE sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable config-setup.service # Copy SNMP configuration files @@ -430,6 +431,9 @@ sudo LANG=C chroot $FILESYSTEM_ROOT umount -lf /sys sudo LANG=C cp $SCRIPTS_DIR/swss.sh $FILESYSTEM_ROOT/usr/local/bin/swss.sh sudo LANG=C cp $SCRIPTS_DIR/syncd.sh $FILESYSTEM_ROOT/usr/local/bin/syncd.sh +# Copy sonic-netns-exec script +sudo LANG=C cp $SCRIPTS_DIR/sonic-netns-exec $FILESYSTEM_ROOT/usr/bin/sonic-netns-exec + # Copy systemd timer configuration # It implements delayed start of services sudo cp $BUILD_TEMPLATES/snmp.timer $FILESYSTEM_ROOT/etc/systemd/system/ diff --git a/files/image_config/topology/topology.sh b/files/image_config/topology/topology.sh index 7013920ec016..dde7da247484 100755 --- a/files/image_config/topology/topology.sh +++ b/files/image_config/topology/topology.sh @@ -6,18 +6,16 @@ # start() { - DB_FIRST_INSTANCE="/var/run/redis0/redis.sock" - TOPOLOGY_SCRIPT="topology.sh" - PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform -s $DB_FIRST_INSTANCE` - HWSKU=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hwsku"]' -s $DB_FIRST_INSTANCE` - /usr/share/sonic/device/$PLATFORM/$HWSKU/$TOPOLOGY_SCRIPT start + TOPOLOGY_SCRIPT="topology.sh" + PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` + HWSKU=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hwsku"]'` + /usr/share/sonic/device/$PLATFORM/$HWSKU/$TOPOLOGY_SCRIPT start } stop() { - DB_FIRST_INSTANCE="/var/run/redis0/redis.sock" - TOPOLOGY_SCRIPT="topology.sh" - PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform -s $DB_FIRST_INSTANCE` - HWSKU=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hwsku"]' -s $DB_FIRST_INSTANCE` - /usr/share/sonic/device/$PLATFORM/$HWSKU/$TOPOLOGY_SCRIPT stop + TOPOLOGY_SCRIPT="topology.sh" + PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` + HWSKU=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hwsku"]'` + usr/share/sonic/device/$PLATFORM/$HWSKU/$TOPOLOGY_SCRIPT stop } case "$1" in diff --git a/files/scripts/sonic-netns-exec b/files/scripts/sonic-netns-exec new file mode 100755 index 000000000000..166a2c7e4a2f --- /dev/null +++ b/files/scripts/sonic-netns-exec @@ -0,0 +1,12 @@ +#!/bin/bash +# Wrapper to execute any command in a specific +# network namespace. +# Usage: +# sonic-netns-exec +NS="$1" +shift +if [ "$NS" != "" ]; then + ip netns exec $NS $@ +else + $@ +fi diff --git a/files/scripts/swss.sh b/files/scripts/swss.sh index a14d03e40f50..360e331f3636 100755 --- a/files/scripts/swss.sh +++ b/files/scripts/swss.sh @@ -1,10 +1,7 @@ #!/bin/bash -SERVICE="swss" -PEER="syncd" -DEPENDENT="teamd radv dhcp_relay" -DEBUGLOG="/tmp/swss-syncd-debug.log" -LOCKFILE="/tmp/swss-syncd-lock" +DEPENDENT="radv dhcp_relay" +MULTI_INST_DEPENDENT="teamd" function debug() { @@ -14,25 +11,25 @@ function debug() function lock_service_state_change() { - debug "Locking ${LOCKFILE} from ${SERVICE} service" + debug "Locking ${LOCKFILE} from ${SERVICE}$DEV service" exec {LOCKFD}>${LOCKFILE} /usr/bin/flock -x ${LOCKFD} trap "/usr/bin/flock -u ${LOCKFD}" 0 2 3 15 - debug "Locked ${LOCKFILE} (${LOCKFD}) from ${SERVICE} service" + debug "Locked ${LOCKFILE} (${LOCKFD}) from ${SERVICE}$DEV service" } function unlock_service_state_change() { - debug "Unlocking ${LOCKFILE} (${LOCKFD}) from ${SERVICE} service" + debug "Unlocking ${LOCKFILE} (${LOCKFD}) from ${SERVICE}$DEV service" /usr/bin/flock -u ${LOCKFD} } function check_warm_boot() { - SYSTEM_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` - SERVICE_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` + SYSTEM_WARM_START=`sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` + SERVICE_WARM_START=`sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` if [[ x"$SYSTEM_WARM_START" == x"true" ]] || [[ x"$SERVICE_WARM_START" == x"true" ]]; then WARM_BOOT="true" else @@ -43,7 +40,7 @@ function check_warm_boot() function validate_restore_count() { if [[ x"$WARM_BOOT" == x"true" ]]; then - RESTORE_COUNT=`sonic-db-cli STATE_DB hget "WARM_RESTART_TABLE|orchagent" restore_count` + RESTORE_COUNT=`sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB hget "WARM_RESTART_TABLE|orchagent" restore_count` # We have to make sure db data has not been flushed. if [[ -z "$RESTORE_COUNT" ]]; then WARM_BOOT="false" @@ -54,10 +51,10 @@ function validate_restore_count() function wait_for_database_service() { # Wait for redis server start before database clean - /usr/bin/docker exec database ping_pong_db_insts + /usr/bin/docker exec database$DEV ping_pong_db_insts # Wait for configDB initialization - until [[ $(sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; + until [[ $(sonic-netns-exec "$NET_NS" sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; do sleep 1; done } @@ -67,7 +64,7 @@ function wait_for_database_service() # $2 the string of a list of table prefixes function clean_up_tables() { - sonic-db-cli $1 EVAL " + sonic-netns-exec "$NET_NS" sonic-db-cli $1 EVAL " local tables = {$2} for i = 1, table.getn(tables) do local matches = redis.call('KEYS', tables[i]) @@ -81,25 +78,48 @@ start_peer_and_dependent_services() { check_warm_boot if [[ x"$WARM_BOOT" != x"true" ]]; then - /bin/systemctl start ${PEER} + if [[ ! -z $DEV ]]; then + /bin/systemctl start ${PEER}@$DEV + else + /bin/systemctl start ${PEER} + fi for dep in ${DEPENDENT}; do /bin/systemctl start ${dep} done + for dep in ${MULTI_INST_DEPENDENT}; do + if [[ ! -z $DEV ]]; then + /bin/systemctl start ${dep}@$DEV + else + /bin/systemctl start ${dep} + fi + done fi } stop_peer_and_dependent_services() { # if warm start enabled or peer lock exists, don't stop peer service docker if [[ x"$WARM_BOOT" != x"true" ]]; then - /bin/systemctl stop ${PEER} + if [[ ! -z $DEV ]]; then + /bin/systemctl stop ${PEER}@$DEV + else + /bin/systemctl stop ${PEER} + fi for dep in ${DEPENDENT}; do /bin/systemctl stop ${dep} done + for dep in ${MULTI_INST_DEPENDENT}; do + if [[ ! -z $DEV ]]; then + /bin/systemctl stop ${dep}@$DEV + else + /bin/systemctl stop ${dep} + fi + done + fi } start() { - debug "Starting ${SERVICE} service..." + debug "Starting ${SERVICE}$DEV service..." lock_service_state_change @@ -107,21 +127,21 @@ start() { check_warm_boot validate_restore_count - debug "Warm boot flag: ${SERVICE} ${WARM_BOOT}." + debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}." # Don't flush DB during warm boot if [[ x"$WARM_BOOT" != x"true" ]]; then debug "Flushing APP, ASIC, COUNTER, CONFIG, and partial STATE databases ..." - sonic-db-cli APPL_DB FLUSHDB - sonic-db-cli ASIC_DB FLUSHDB - sonic-db-cli COUNTERS_DB FLUSHDB - sonic-db-cli FLEX_COUNTER_DB FLUSHDB + sonic-netns-exec "$NET_NS" sonic-db-cli APPL_DB FLUSHDB + sonic-netns-exec "$NET_NS" sonic-db-cli ASIC_DB FLUSHDB + sonic-netns-exec "$NET_NS" sonic-db-cli COUNTERS_DB FLUSHDB + sonic-netns-exec "$NET_NS" sonic-db-cli FLEX_COUNTER_DB FLUSHDB clean_up_tables STATE_DB "'PORT_TABLE*', 'MGMT_PORT_TABLE*', 'VLAN_TABLE*', 'VLAN_MEMBER_TABLE*', 'LAG_TABLE*', 'LAG_MEMBER_TABLE*', 'INTERFACE_TABLE*', 'MIRROR_SESSION*', 'VRF_TABLE*', 'FDB_TABLE*'" fi # start service docker - /usr/bin/${SERVICE}.sh start - debug "Started ${SERVICE} service..." + /usr/bin/${SERVICE}.sh start $DEV + debug "Started ${SERVICE}$DEV service..." # Unlock has to happen before reaching out to peer service unlock_service_state_change @@ -134,7 +154,11 @@ wait() { # NOTE: This assumes Docker containers share the same names as their # corresponding services for SECS in {1..60}; do - RUNNING=$(docker inspect -f '{{.State.Running}}' ${PEER}) + if [[ ! -z $DEV ]]; then + RUNNING=$(docker inspect -f '{{.State.Running}}' ${PEER}$DEV) + else + RUNNING=$(docker inspect -f '{{.State.Running}}' ${PEER}) + fi if [[ x"$RUNNING" == x"true" ]]; then break else @@ -144,20 +168,24 @@ wait() { # NOTE: This assumes Docker containers share the same names as their # corresponding services - /usr/bin/docker-wait-any ${SERVICE} ${PEER} + if [[ ! -z $DEV ]]; then + /usr/bin/docker-wait-any ${SERVICE}$DEV ${PEER}$DEV + else + /usr/bin/docker-wait-any ${SERVICE} ${PEER} + fi } stop() { - debug "Stopping ${SERVICE} service..." + debug "Stopping ${SERVICE}$DEV service..." [[ -f ${LOCKFILE} ]] || /usr/bin/touch ${LOCKFILE} lock_service_state_change check_warm_boot - debug "Warm boot flag: ${SERVICE} ${WARM_BOOT}." + debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}." - /usr/bin/${SERVICE}.sh stop - debug "Stopped ${SERVICE} service..." + /usr/bin/${SERVICE}.sh stop $DEV + debug "Stopped ${SERVICE}$DEV service..." # Flush FAST_REBOOT table when swss needs to stop. The only # time when this would take effect is when fast-reboot @@ -172,6 +200,18 @@ stop() { stop_peer_and_dependent_services } +DEV=$2 + +SERVICE="swss" +PEER="syncd" +DEBUGLOG="/tmp/swss-syncd-debug$DEV.log" +LOCKFILE="/tmp/swss-syncd-lock$DEV" +if [ "$DEV" ]; then + NET_NS="asic$DEV" #name of the network namespace +else + NET_NS="" +fi + case "$1" in start|wait|stop) $1 diff --git a/files/scripts/syncd.sh b/files/scripts/syncd.sh index 4b47e7ad4c45..9847cfec9406 100755 --- a/files/scripts/syncd.sh +++ b/files/scripts/syncd.sh @@ -1,9 +1,5 @@ #!/bin/bash -SERVICE="syncd" -PEER="swss" -DEBUGLOG="/tmp/swss-syncd-debug.log" -LOCKFILE="/tmp/swss-syncd-lock" function debug() { @@ -13,25 +9,25 @@ function debug() function lock_service_state_change() { - debug "Locking ${LOCKFILE} from ${SERVICE} service" + debug "Locking ${LOCKFILE} from ${SERVICE}$DEV service" exec {LOCKFD}>${LOCKFILE} /usr/bin/flock -x ${LOCKFD} trap "/usr/bin/flock -u ${LOCKFD}" 0 2 3 15 - debug "Locked ${LOCKFILE} (${LOCKFD}) from ${SERVICE} service" + debug "Locked ${LOCKFILE} (${LOCKFD}) from ${SERVICE}$DEV service" } function unlock_service_state_change() { - debug "Unlocking ${LOCKFILE} (${LOCKFD}) from ${SERVICE} service" + debug "Unlocking ${LOCKFILE} (${LOCKFD}) from ${SERVICE}$DEV service" /usr/bin/flock -u ${LOCKFD} } function check_warm_boot() { - SYSTEM_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` - SERVICE_WARM_START=`sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` + SYSTEM_WARM_START=`sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|system" enable` + SERVICE_WARM_START=`sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` # SYSTEM_WARM_START could be empty, always make WARM_BOOT meaningful. if [[ x"$SYSTEM_WARM_START" == x"true" ]] || [[ x"$SERVICE_WARM_START" == x"true" ]]; then WARM_BOOT="true" @@ -43,10 +39,10 @@ function check_warm_boot() function wait_for_database_service() { # Wait for redis server start before database clean - /usr/bin/docker exec database ping_pong_db_insts + /usr/bin/docker exec database$DEV ping_pong_db_insts # Wait for configDB initialization - until [[ $(sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; + until [[ $(sonic-netns-exec "$NET_NS" sonic-db-cli CONFIG_DB GET "CONFIG_DB_INITIALIZED") ]]; do sleep 1; done } @@ -63,7 +59,7 @@ function getBootType() ;; *SONIC_BOOT_TYPE=fast*|*fast-reboot*) # check that the key exists - if [[ $(sonic-db-cli STATE_DB GET "FAST_REBOOT|system") == "1" ]]; then + if [[ $(sonic-netns-exec "$NET_NS" sonic-db-cli STATE_DB GET "FAST_REBOOT|system") == "1" ]]; then TYPE='fast' else TYPE='cold' @@ -76,7 +72,7 @@ function getBootType() } start() { - debug "Starting ${SERVICE} service..." + debug "Starting ${SERVICE}$DEV service..." lock_service_state_change @@ -85,7 +81,7 @@ start() { wait_for_database_service check_warm_boot - debug "Warm boot flag: ${SERVICE} ${WARM_BOOT}." + debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}." if [[ x"$WARM_BOOT" == x"true" ]]; then # Leave a mark for syncd scripts running inside docker. @@ -127,7 +123,7 @@ start() { fi # start service docker - /usr/bin/${SERVICE}.sh start + /usr/bin/${SERVICE}.sh start $DEV debug "Started ${SERVICE} service..." unlock_service_state_change @@ -139,15 +135,15 @@ wait() { /bin/systemctl start pmon debug "Started pmon service" fi - /usr/bin/${SERVICE}.sh wait + /usr/bin/${SERVICE}.sh wait $DEV } stop() { - debug "Stopping ${SERVICE} service..." + debug "Stopping ${SERVICE}$DEV service..." lock_service_state_change check_warm_boot - debug "Warm boot flag: ${SERVICE} ${WARM_BOOT}." + debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}." if [[ x"$WARM_BOOT" == x"true" ]]; then TYPE=warm @@ -163,19 +159,19 @@ stop() { if [[ x$sonic_asic_platform != x"mellanox" ]] || [[ x$TYPE != x"cold" ]]; then debug "${TYPE} shutdown syncd process ..." - /usr/bin/docker exec -i syncd /usr/bin/syncd_request_shutdown --${TYPE} + /usr/bin/docker exec -i syncd$DEV /usr/bin/syncd_request_shutdown --${TYPE} # wait until syncd quits gracefully - while docker top syncd | grep -q /usr/bin/syncd; do + while docker top syncd$DEV | grep -q /usr/bin/syncd; do sleep 0.1 done - /usr/bin/docker exec -i syncd /bin/sync + /usr/bin/docker exec -i syncd$DEV /bin/sync debug "Finished ${TYPE} shutdown syncd process ..." fi - /usr/bin/${SERVICE}.sh stop - debug "Stopped ${SERVICE} service..." + /usr/bin/${SERVICE}.sh stop $DEV + debug "Stopped ${SERVICE}$DEV service..." # platform specific tasks @@ -192,6 +188,19 @@ stop() { unlock_service_state_change } +OP=$1 +DEV=$2 + +SERVICE="syncd" +PEER="swss" +DEBUGLOG="/tmp/swss-syncd-debug$DEV.log" +LOCKFILE="/tmp/swss-syncd-lock$DEV" +if [ "$DEV" ]; then + NET_NS="asic$DEV" #name of the network namespace +else + NET_NS="" +fi + case "$1" in start|wait|stop) $1 diff --git a/platform/vs/sonic_multiasic.xml b/platform/vs/sonic_multiasic.xml index b406bfd40475..b571b5122a52 100644 --- a/platform/vs/sonic_multiasic.xml +++ b/platform/vs/sonic_multiasic.xml @@ -1,7 +1,7 @@ sonic 8 - 2 + 8 /machine diff --git a/rules/docker-fpm-frr.mk b/rules/docker-fpm-frr.mk index 517aff3ea9fc..45a755a9289f 100644 --- a/rules/docker-fpm-frr.mk +++ b/rules/docker-fpm-frr.mk @@ -24,7 +24,6 @@ SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_FPM_FRR_DBG) $(DOCKER_FPM_FRR)_CONTAINER_NAME = bgp $(DOCKER_FPM_FRR)_RUN_OPT += --privileged -t $(DOCKER_FPM_FRR)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro -$(DOCKER_FPM_FRR)_RUN_OPT += -v /etc/sonic/frr:/etc/frr:rw $(DOCKER_FPM_FRR)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) diff --git a/slave.mk b/slave.mk index 16bc790f0b81..21c1176feef1 100644 --- a/slave.mk +++ b/slave.mk @@ -667,6 +667,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export platform_common_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_PLATFORM_COMMON_PY2))" export redis_dump_load_py2_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(REDIS_DUMP_LOAD_PY2))" export install_debug_image="$(INSTALL_DEBUG_TOOLS)" + export multi_instance="false" $(foreach docker, $($*_DOCKERS),\ export docker_image="$(docker)" @@ -677,18 +678,21 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ if [ -f files/build_templates/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 ]; then j2 files/build_templates/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service - fi - - if [ -f files/build_templates/multi_instance/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME)@.service.j2 ]; then - j2 files/build_templates/multi_instance/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME)@.service.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME)@.service - # performs the same check as the elif above, except with make commands so eval behaves properly - $(if $(shell ls files/build_templates/multi_instance/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME)@.service.j2 2>/dev/null),\ - $(eval $(docker:-dbg.gz=.gz)_TEMPLATE = yes) - ) + # Set the flag GLOBAL for all the global system-wide dockers. + $(if $(shell ls files/build_templates/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 2>/dev/null),\ + $(eval $(docker:-dbg.gz=.gz)_GLOBAL = yes) + ) fi - if [ -f files/build_templates/single_instance/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 ]; then - j2 files/build_templates/single_instance/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service + # Any service template, inside instance directory, will be used to generate .service and @.service file. + if [ -f files/build_templates/per_namespace/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 ]; then + export multi_instance="true" + j2 files/build_templates/per_namespace/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME)@.service + $(if $(shell ls files/build_templates/per_namespace/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 2>/dev/null),\ + $(eval $(docker:-dbg.gz=.gz)_TEMPLATE = yes) + ) + export multi_instance="false" + j2 files/build_templates/per_namespace/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service fi j2 files/build_templates/docker_image_ctl.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).sh chmod +x $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).sh @@ -699,8 +703,12 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ # Marks template services with an "@" according to systemd convention # If the $($docker)_TEMPLATE) variable is set, the service will be treated as a template + # If the $($docker)_GLOBAL) and $($docker)_TEMPLATE) variables are set the service will be added both as a global and template service. $(foreach docker, $($*_DOCKERS),\ $(if $($(docker:-dbg.gz=.gz)_TEMPLATE),\ + $(if $($(docker:-dbg.gz=.gz)_GLOBAL),\ + $(eval SERVICES += "$(addsuffix .service, $($(docker:-dbg.gz=.gz)_CONTAINER_NAME))")\ + )\ $(eval SERVICES += "$(addsuffix @.service, $($(docker:-dbg.gz=.gz)_CONTAINER_NAME))"),\ $(eval SERVICES += "$(addsuffix .service, $($(docker:-dbg.gz=.gz)_CONTAINER_NAME))") ) From 9dd1fa016c0cd7eb4319eb5a1fcf61f6d74859d5 Mon Sep 17 00:00:00 2001 From: Myron Sosyak <49795530+msosyak@users.noreply.github.com> Date: Tue, 14 Apr 2020 19:43:35 +0300 Subject: [PATCH 161/178] Update Barefoot kdrv (#4355) --- .../barefoot/bfn-modules/modules/bf_ioctl.h | 67 +- .../barefoot/bfn-modules/modules/bf_kdrv.c | 1186 +++++++++-------- .../barefoot/bfn-modules/modules/bf_kdrv.h | 146 ++ 3 files changed, 832 insertions(+), 567 deletions(-) create mode 100644 platform/barefoot/bfn-modules/modules/bf_kdrv.h diff --git a/platform/barefoot/bfn-modules/modules/bf_ioctl.h b/platform/barefoot/bfn-modules/modules/bf_ioctl.h index e14716f50fa3..0644feb7c8c1 100644 --- a/platform/barefoot/bfn-modules/modules/bf_ioctl.h +++ b/platform/barefoot/bfn-modules/modules/bf_ioctl.h @@ -1,25 +1,28 @@ /******************************************************************************* - * BAREFOOT NETWORKS CONFIDENTIAL & PROPRIETARY - * - * Copyright (c) 2018-2018 Barefoot Networks, Inc. - * - * NOTICE: All information contained herein is, and remains the property of - * Barefoot Networks, Inc. and its suppliers, if any. The intellectual and - * technical concepts contained herein are proprietary to Barefoot Networks, - * Inc. - * and its suppliers and may be covered by U.S. and Foreign Patents, patents in - * process, and are protected by trade secret or copyright law. - * Dissemination of this information or reproduction of this material is - * strictly forbidden unless prior written permission is obtained from - * Barefoot Networks, Inc. - * - * No warranty, explicit or implicit is provided, unless granted under a - * written agreement with Barefoot Networks, Inc. - * - * $Id: $ - * - ******************************************************************************/ + Barefoot Networks Switch ASIC Linux driver + Copyright(c) 2015 - 2019 Barefoot Networks, Inc. + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + This program is distributed in the hope it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + + The full GNU General Public License is included in this distribution in + the file called "COPYING". + + Contact Information: + info@barefootnetworks.com + Barefoot Networks, 4750 Patrick Henry Drive, Santa Clara CA 95054 + +*******************************************************************************/ #ifndef _BF_IOCTL_H_ #define _BF_IOCTL_H_ @@ -35,15 +38,35 @@ typedef uint64_t phys_addr_t; #endif /* __KERNEL__ */ #define BF_IOC_MAGIC 'b' +#define BF_TBUS_MSIX_INDICES_MAX 3 -typedef struct bf_dma_bus_map_s +typedef struct bf_dma_bus_map_s { phys_addr_t phy_addr; void *dma_addr; size_t size; } bf_dma_bus_map_t; +typedef struct bf_tbus_msix_indices_s +{ + int cnt; + int indices[BF_TBUS_MSIX_INDICES_MAX]; +} bf_tbus_msix_indices_t; + +enum bf_intr_mode { + BF_INTR_MODE_NONE = 0, + BF_INTR_MODE_LEGACY, + BF_INTR_MODE_MSI, + BF_INTR_MODE_MSIX, +}; + +typedef struct bf_intr_mode_s { + enum bf_intr_mode intr_mode; +} bf_intr_mode_t; + #define BF_IOCMAPDMAADDR _IOWR(BF_IOC_MAGIC, 0, bf_dma_bus_map_t) -#define BF_IOCUNMAPDMAADDR _IOW(BF_IOC_MAGIC, 0, bf_dma_bus_map_t) +#define BF_IOCUNMAPDMAADDR _IOW(BF_IOC_MAGIC, 1, bf_dma_bus_map_t) +#define BF_TBUS_MSIX_INDEX _IOW(BF_IOC_MAGIC, 2, bf_tbus_msix_indices_t) +#define BF_GET_INTR_MODE _IOR(BF_IOC_MAGIC, 3, bf_intr_mode_t) #endif /* _BF_IOCTL_H_ */ diff --git a/platform/barefoot/bfn-modules/modules/bf_kdrv.c b/platform/barefoot/bfn-modules/modules/bf_kdrv.c index a9e8e65f968b..d4c786c56b75 100644 --- a/platform/barefoot/bfn-modules/modules/bf_kdrv.c +++ b/platform/barefoot/bfn-modules/modules/bf_kdrv.c @@ -1,49 +1,31 @@ /******************************************************************************* - * BAREFOOT NETWORKS CONFIDENTIAL & PROPRIETARY - * - * Copyright (c) 2015-2016 Barefoot Networks, Inc. + Barefoot Networks Switch ASIC Linux driver + Copyright(c) 2015 - 2019 Barefoot Networks, Inc. - * All Rights Reserved. - * - * NOTICE: All information contained herein is, and remains the property of - * Barefoot Networks, Inc. and its suppliers, if any. The intellectual and - * technical concepts contained herein are proprietary to Barefoot Networks, - * Inc. - * and its suppliers and may be covered by U.S. and Foreign Patents, patents in - * process, and are protected by trade secret or copyright law. - * Dissemination of this information or reproduction of this material is - * strictly forbidden unless prior written permission is obtained from - * Barefoot Networks, Inc. - * - * No warranty, explicit or implicit is provided, unless granted under a - * written agreement with Barefoot Networks, Inc. - * - * $Id: $ - * - ******************************************************************************/ -/** - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2015 Barefoot Networks. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * 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... - * - **/ + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + This program is distributed in the hope it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + The full GNU General Public License is included in this distribution in + the file called "COPYING". + + Contact Information: + info@barefootnetworks.com + Barefoot Networks, 4750 Patrick Henry Drive, Santa Clara CA 95054 + +*******************************************************************************/ /* bf_drv kernel module * - * This is kernel mode driver for Tofino chip. + * This is kernel mode driver for Tofino chip. * Provides user space mmap service and user space "wait for interrupt" * and "enable interrupt" services. */ @@ -52,21 +34,18 @@ #include #include #include -#include #include -#include -#include #include #include #include #include "bf_ioctl.h" +#include "bf_kdrv.h" #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) #include #else - #include + #include #endif - #include #include #include @@ -75,104 +54,26 @@ //#error unsupported linux kernel version #endif -/* TBD: Need to build with CONFIG_PCI_MSI */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0) -extern int pci_enable_msi_block(struct pci_dev *dev, unsigned int nvec); -extern int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec); -#else -extern int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec); -extern int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, int minvec, int maxvec); -#endif - -#define PCI_VENDOR_ID_BF 0x1d1c -#define TOFINO_DEV_ID_A0 0x01 -#define TOFINO_DEV_ID_B0 0x10 -#define TOFINO2_DEV_ID_A0 0x0100 - -#ifndef PCI_MSIX_ENTRY_SIZE -#define PCI_MSIX_ENTRY_SIZE 16 -#define PCI_MSIX_ENTRY_LOWER_ADDR 0 -#define PCI_MSIX_ENTRY_UPPER_ADDR 4 -#define PCI_MSIX_ENTRY_DATA 8 -#define PCI_MSIX_ENTRY_VECTOR_CTRL 12 -#define PCI_MSIX_ENTRY_CTRL_MASKBIT 1 +#ifdef BF_INCLUDE_KPKT +/* kernel pkt driver entry/exit APIs */ +extern int bf_kpkt_init(struct pci_dev *pdev, + u8 *bar0_vaddr, + void **adapter_ptr, + int dev_id, + int pci_use_highmem, + unsigned long head_room, + int kpkt_dr_int_en, + unsigned long rx_desc_countp); +extern void bf_kpkt_remove(void *adapter_ptr); +extern void bf_kpkt_irqhandler(int irq, void *adapter_ptr); +extern void bf_kpkt_set_pci_error(void *adapter_ptr, u8 pci_error); #endif -#define BF_CLASS_NAME "bf" -#define BF_MAX_DEVICE_CNT 256 -#define BF_INTR_MODE_NONE_NAME "none" -#define BF_INTR_MODE_LEGACY_NAME "legacy" -#define BF_INTR_MODE_MSI_NAME "msi" -#define BF_INTR_MODE_MSIX_NAME "msix" -#define BF_MAX_BAR_MAPS 6 -#define BF_MSIX_ENTRY_CNT 128 /* TBD make it 512 */ -#define BF_MSI_ENTRY_CNT 2 - -/* interrupt mode */ -enum bf_intr_mode { - BF_INTR_MODE_NONE = 0, - BF_INTR_MODE_LEGACY, - BF_INTR_MODE_MSI, - BF_INTR_MODE_MSIX -}; - -/* device memory */ -struct bf_dev_mem { - const char *name; - phys_addr_t addr; - resource_size_t size; - void __iomem *internal_addr; -}; - -struct bf_listener { - struct bf_pci_dev *bfdev; - s32 event_count[BF_MSIX_ENTRY_CNT]; - int minor; - struct bf_listener *next; -}; - -/* device information */ -struct bf_dev_info { - struct module *owner; - struct device *dev; - int minor; - atomic_t event[BF_MSIX_ENTRY_CNT]; - wait_queue_head_t wait; - const char *version; - struct bf_dev_mem mem[BF_MAX_BAR_MAPS]; - struct msix_entry *msix_entries; - long irq; /* first irq vector */ - int num_irq; /* number of irq vectors */ - unsigned long irq_flags;/* sharable ?? */ - int pci_error_state; /* was there a pci bus error */ -}; - -/* cookie to be passed to IRQ handler, useful especially with MSIX */ -struct bf_int_vector { - struct bf_pci_dev *bf_dev; - int int_vec_offset; -}; - - -/** - * A structure describing the private information for a BF pcie device. - */ -struct bf_pci_dev { - struct bf_dev_info info; - struct pci_dev *pdev; - enum bf_intr_mode mode; - u8 instance; - char name[16]; - struct bf_int_vector bf_int_vec[BF_MSIX_ENTRY_CNT]; - struct bf_listener *listener_head; /* head of a singly linked list of - listeners */ -}; - /* Keep any global information here that must survive even after the * bf_pci_dev is free-ed up. */ struct bf_global { - struct bf_pci_dev *bfdev ; + struct bf_pci_dev *bfdev; struct cdev *bf_cdev; struct fasync_struct *async_queue; }; @@ -181,14 +82,19 @@ static int bf_major; static int bf_minor[BF_MAX_DEVICE_CNT] = {0}; static struct class *bf_class = NULL; static char *intr_mode = NULL; +static int kpkt_mode = 0; +static int kpkt_hd_room = 32; +static int kpkt_rx_count = 256; +static int kpkt_dr_int_en = 1; + static enum bf_intr_mode bf_intr_mode_default = BF_INTR_MODE_MSI; static spinlock_t bf_nonisr_lock; + /* dev->minor should index into this array */ static struct bf_global bf_global[BF_MAX_DEVICE_CNT]; static void bf_add_listener(struct bf_pci_dev *bfdev, - struct bf_listener *listener) -{ + struct bf_listener *listener) { struct bf_listener **cur_listener = &bfdev->listener_head; if (!listener) { @@ -197,7 +103,7 @@ static void bf_add_listener(struct bf_pci_dev *bfdev, spin_lock(&bf_nonisr_lock); while (*cur_listener) { - cur_listener = &((*cur_listener)->next); + cur_listener = &((*cur_listener)->next); } *cur_listener = listener; listener->next = NULL; @@ -206,12 +112,12 @@ static void bf_add_listener(struct bf_pci_dev *bfdev, } static void bf_remove_listener(struct bf_pci_dev *bfdev, - struct bf_listener *listener) -{ + struct bf_listener *listener) { struct bf_listener **cur_listener = &bfdev->listener_head; - /* in case of certain error conditions, this function might be called after bf_pci_remove() - */ + /* in case of certain error conditions, this function might be called after + * bf_pci_remove() + */ if (!bfdev || !listener) { return; } @@ -235,12 +141,11 @@ static void bf_remove_listener(struct bf_pci_dev *bfdev, /* a pool of minor numbers is maintained */ /* return the first available minor number */ -static int bf_get_next_minor_no(int *minor) -{ +static int bf_get_next_minor_no(int *minor) { int i; spin_lock(&bf_nonisr_lock); - for(i = 0; i < BF_MAX_DEVICE_CNT; i++) { + for (i = 0; i < BF_MAX_DEVICE_CNT; i++) { if (bf_minor[i] == 0) { *minor = i; bf_minor[i] = 1; /* mark it as taken */ @@ -254,13 +159,12 @@ static int bf_get_next_minor_no(int *minor) } /* return a minor number back to the pool for recycling */ -static int bf_return_minor_no(int minor) -{ +static int bf_return_minor_no(int minor) { int err; spin_lock(&bf_nonisr_lock); if (bf_minor[minor] == 0) { /* was already returned */ - err = -1; /* don't change anything, but return error */ + err = -1; /* don't change anything, but return error */ } else { bf_minor[minor] = 0; /* mark it as available */ err = 0; @@ -269,31 +173,29 @@ static int bf_return_minor_no(int minor) return err; } -static inline struct bf_pci_dev *bf_get_pci_dev(struct bf_dev_info *info) -{ - return container_of(info, struct bf_pci_dev, info); +static inline struct bf_pci_dev *bf_get_pci_dev(struct bf_dev_info *info) { + return container_of(info, struct bf_pci_dev, info); } /* * It masks the msix on/off of generating MSI-X messages. */ -static void -bf_msix_mask_irq(struct msi_desc *desc, int32_t state) -{ - u32 mask_bits = desc->masked; - unsigned offset = desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + - PCI_MSIX_ENTRY_VECTOR_CTRL; - - if (state != 0) - mask_bits &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT; - else - mask_bits |= PCI_MSIX_ENTRY_CTRL_MASKBIT; - - if (mask_bits != desc->masked) { - writel(mask_bits, desc->mask_base + offset); - readl(desc->mask_base); - desc->masked = mask_bits; - } +static void bf_msix_mask_irq(struct msi_desc *desc, int32_t state) { + u32 mask_bits = desc->masked; + unsigned offset = desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + + PCI_MSIX_ENTRY_VECTOR_CTRL; + + if (state != 0) { + mask_bits &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT; + } else { + mask_bits |= PCI_MSIX_ENTRY_CTRL_MASKBIT; + } + + if (mask_bits != desc->masked) { + writel(mask_bits, desc->mask_base + offset); + readl(desc->mask_base); + desc->masked = mask_bits; + } } /** @@ -308,179 +210,217 @@ bf_msix_mask_irq(struct msi_desc *desc, int32_t state) * - On success, 0. * - On failure, a negative value. */ -static int -bf_pci_irqcontrol(struct bf_pci_dev *bfdev, s32 irq_state) -{ - struct pci_dev *pdev = bfdev->pdev; - - pci_cfg_access_lock(pdev); - if (bfdev->mode == BF_INTR_MODE_LEGACY) - pci_intx(pdev, !!irq_state); - - else if (bfdev->mode == BF_INTR_MODE_MSIX) { - struct msi_desc *desc; -#if LINUX_VERSION_CODE < KERNEL_VERSION(4,2,0) - list_for_each_entry(desc, &pdev->msi_list, list) - bf_msix_mask_irq(desc, irq_state); +static int bf_pci_irqcontrol(struct bf_pci_dev *bfdev, s32 irq_state) { + struct pci_dev *pdev = bfdev->pdev; + + pci_cfg_access_lock(pdev); + if (bfdev->mode == BF_INTR_MODE_LEGACY) { + pci_intx(pdev, !!irq_state); + } else if (bfdev->mode == BF_INTR_MODE_MSIX) { + struct msi_desc *desc; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0) + list_for_each_entry(desc, &pdev->msi_list, list) + bf_msix_mask_irq(desc, irq_state); #else - for_each_pci_msi_entry(desc, pdev) - bf_msix_mask_irq(desc, irq_state); + for_each_pci_msi_entry(desc, pdev) bf_msix_mask_irq(desc, irq_state); #endif - } - pci_cfg_access_unlock(pdev); + } + pci_cfg_access_unlock(pdev); - return 0; + return 0; } +#ifdef BF_INCLUDE_KPKT +/* there are three TBUS MSIX vectors */ +static int bf_irq_is_tbus_msix(struct bf_pci_dev *bfdev, int irq) { + struct bf_dev_info *info = &bfdev->info; + + if (!info->tbus_msix_map_enable) { + return 0; + } + if (irq == info->msix_entries[info->tbus_msix_ind[0]].vector || + irq == info->msix_entries[info->tbus_msix_ind[1]].vector) { + return 1; + } else if (irq == info->msix_entries[info->tbus_msix_ind[2]].vector) { + /* log error */ + printk(KERN_ALERT "bf_tbus error msix\n"); + return 1; + } + return 0; +} +#endif + /** * interrupt handler which will check if the interrupt is from the right * device. If so, disable it here and will be enabled later. */ -static irqreturn_t bf_pci_irqhandler(int irq, struct bf_pci_dev *bfdev) -{ - /* Legacy mode need to mask in hardware */ - if (bfdev->mode == BF_INTR_MODE_LEGACY && - !pci_check_and_mask_intx(bfdev->pdev)) - return IRQ_NONE; - - /* NOTE : if bfdev->info.pci_error_state == 1, then do not access the - * device and return IRQ_NOTHANDLED. - */ - /* Message signal mode, no share IRQ and automasked */ - return IRQ_HANDLED; +static irqreturn_t bf_pci_irqhandler(int irq, struct bf_pci_dev *bfdev) { + /* Legacy mode need to mask in hardware */ + if (bfdev->mode == BF_INTR_MODE_LEGACY && + !pci_check_and_mask_intx(bfdev->pdev)) { + return IRQ_NONE; + } + + /* NOTE : if bfdev->info.pci_error_state == 1, then do not access the + * device and return IRQ_NOTHANDLED. + */ +#ifdef BF_INCLUDE_KPKT + /* handle pkt DR interrpt (MSI vect-1) if it has to be in kernel */ + if (kpkt_dr_int_en && bfdev->info.irq != 0) { + if (bfdev->mode == BF_INTR_MODE_LEGACY) { + bf_kpkt_irqhandler(irq, bfdev->adapter_ptr); + } else if (bfdev->mode == BF_INTR_MODE_MSI) { + /* do not process packet unless the MSI interrupt is from tbus */ + /* all BF interrupts arrive on one single MSI if "1" MSI is configured */ + if (bfdev->info.num_irq == 1 || (irq == (bfdev->info.irq + BF_MSI_INT_TBUS))) { + bf_kpkt_irqhandler(irq, bfdev->adapter_ptr); + } + } else if (bfdev->mode == BF_INTR_MODE_MSIX) { + if (bfdev->info.tof_type == BF_TOFINO_2 && bf_irq_is_tbus_msix(bfdev,irq)) { + bf_kpkt_irqhandler(irq, bfdev->adapter_ptr); + } + } + } +#endif + /* Message signal mode, no share IRQ and automasked */ + return IRQ_HANDLED; } /* Remap pci resources described by bar #pci_bar */ -static int -bf_pci_setup_iomem(struct pci_dev *dev, struct bf_dev_info *info, - int n, int pci_bar, const char *name) -{ - unsigned long addr, len; - void *internal_addr; - - if (sizeof(info->mem) / sizeof(info->mem[0]) <= n) - return -EINVAL; - - addr = pci_resource_start(dev, pci_bar); - len = pci_resource_len(dev, pci_bar); - if (addr == 0 || len == 0) - return -1; - internal_addr = pci_ioremap_bar(dev, pci_bar); - if (internal_addr == NULL) - return -1; - info->mem[n].name = name; - info->mem[n].addr = addr; - info->mem[n].internal_addr = internal_addr; - info->mem[n].size = len; - return 0; +static int bf_pci_setup_iomem(struct pci_dev *dev, + struct bf_dev_info *info, + int n, + int pci_bar, + const char *name) { + unsigned long addr, len; + void *internal_addr; + + if (sizeof(info->mem) / sizeof(info->mem[0]) <= n) { + return -EINVAL; + } + + addr = pci_resource_start(dev, pci_bar); + len = pci_resource_len(dev, pci_bar); + if (addr == 0 || len == 0) { + return -1; + } + internal_addr = pci_ioremap_bar(dev, pci_bar); + if (internal_addr == NULL) { + return -1; + } + info->mem[n].name = name; + info->mem[n].addr = addr; + info->mem[n].internal_addr = internal_addr; + info->mem[n].size = len; + return 0; } /* Unmap previously ioremap'd resources */ -static void -bf_pci_release_iomem(struct bf_dev_info *info) -{ - int i; +static void bf_pci_release_iomem(struct bf_dev_info *info) { + int i; - for (i = 0; i < BF_MAX_BAR_MAPS; i++) { - if (info->mem[i].internal_addr) - iounmap(info->mem[i].internal_addr); - } + for (i = 0; i < BF_MAX_BAR_MAPS; i++) { + if (info->mem[i].internal_addr) { + iounmap(info->mem[i].internal_addr); + } + } } -static int -bf_setup_bars(struct pci_dev *dev, struct bf_dev_info *info) -{ - int i, iom, ret; - unsigned long flags; - static const char *bar_names[BF_MAX_BAR_MAPS] = { - "BAR0", "BAR1", "BAR2", "BAR3", "BAR4", "BAR5", - }; - - iom = 0; - - for (i = 0; i < BF_MAX_BAR_MAPS; i++) { - if (pci_resource_len(dev, i) != 0 && - pci_resource_start(dev, i) != 0) { - flags = pci_resource_flags(dev, i); - if (flags & IORESOURCE_MEM) { - ret = bf_pci_setup_iomem(dev, info, iom, i, bar_names[i]); - if (ret != 0) - return ret; - iom++; - } - } - } - return (iom != 0) ? ret : -ENOENT; +static int bf_setup_bars(struct pci_dev *dev, struct bf_dev_info *info) { + int i, iom, ret; + unsigned long flags; + static const char *bar_names[BF_MAX_BAR_MAPS] = { + "BAR0", "BAR1", "BAR2", "BAR3", "BAR4", "BAR5", + }; + + iom = 0; + + for (i = 0; i < BF_MAX_BAR_MAPS; i++) { + if (pci_resource_len(dev, i) != 0 && pci_resource_start(dev, i) != 0) { + flags = pci_resource_flags(dev, i); + if (flags & IORESOURCE_MEM) { + ret = bf_pci_setup_iomem(dev, info, iom, i, bar_names[i]); + if (ret != 0) { + return ret; + } + iom++; + } + } + } + return (iom != 0) ? ret : -ENOENT; } -static irqreturn_t bf_interrupt(int irq, void *bfdev_id) -{ +static irqreturn_t bf_interrupt(int irq, void *bfdev_id) { struct bf_pci_dev *bfdev = ((struct bf_int_vector *)bfdev_id)->bf_dev; int vect_off = ((struct bf_int_vector *)bfdev_id)->int_vec_offset; irqreturn_t ret = bf_pci_irqhandler(irq, bfdev); - if (ret == IRQ_HANDLED) + if (ret == IRQ_HANDLED) { atomic_inc(&(bfdev->info.event[vect_off])); - + } return ret; } -static unsigned int bf_poll(struct file *filep, poll_table *wait) -{ +static unsigned int bf_poll(struct file *filep, poll_table *wait) { struct bf_listener *listener = (struct bf_listener *)filep->private_data; struct bf_pci_dev *bfdev = listener->bfdev; int i; - + if (!bfdev) { return -ENODEV; } - if (!bfdev->info.irq) + if (!bfdev->info.irq) { return -EIO; - + } + poll_wait(filep, &bfdev->info.wait, wait); - for (i = 0; i < BF_MSIX_ENTRY_CNT; i++) - if (listener->event_count[i] != atomic_read(&bfdev->info.event[i])) + for (i = 0; i < BF_MSIX_ENTRY_CNT; i++) { + if (listener->event_count[i] != atomic_read(&bfdev->info.event[i])) { return POLLIN | POLLRDNORM; + } + } return 0; } -static int bf_find_mem_index(struct vm_area_struct *vma) -{ +static int bf_find_mem_index(struct vm_area_struct *vma) { struct bf_pci_dev *bfdev = vma->vm_private_data; if (vma->vm_pgoff < BF_MAX_BAR_MAPS) { - if (bfdev->info.mem[vma->vm_pgoff].size == 0) + if (bfdev->info.mem[vma->vm_pgoff].size == 0) { return -1; + } return (int)vma->vm_pgoff; } return -1; } - + static const struct vm_operations_struct bf_physical_vm_ops = { #ifdef CONFIG_HAVE_IOREMAP_PROT - .access = generic_access_phys, + .access = generic_access_phys, #endif }; -static int bf_mmap_physical(struct vm_area_struct *vma) -{ +static int bf_mmap_physical(struct vm_area_struct *vma) { struct bf_pci_dev *bfdev = vma->vm_private_data; int bar = bf_find_mem_index(vma); struct bf_dev_mem *mem; - if (bar < 0) + if (bar < 0) { return -EINVAL; + } mem = bfdev->info.mem + bar; - - if (mem->addr & ~PAGE_MASK) + + if (mem->addr & ~PAGE_MASK) { return -ENODEV; - if (vma->vm_end - vma->vm_start > mem->size) + } + if (vma->vm_end - vma->vm_start > mem->size) { return -EINVAL; - + } + vma->vm_ops = &bf_physical_vm_ops; - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + /* * We cannot use the vm_iomap_memory() helper here, * because vma->vm_pgoff is the map index we looked @@ -490,40 +430,45 @@ static int bf_mmap_physical(struct vm_area_struct *vma) * So we just do the physical mmap without a page * offset. */ - return remap_pfn_range(vma, vma->vm_start, mem->addr >> PAGE_SHIFT, - vma->vm_end - vma->vm_start, vma->vm_page_prot); + return remap_pfn_range(vma, + vma->vm_start, + mem->addr >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, + vma->vm_page_prot); } -static int bf_mmap(struct file *filep, struct vm_area_struct *vma) -{ +static int bf_mmap(struct file *filep, struct vm_area_struct *vma) { struct bf_listener *listener = filep->private_data; struct bf_pci_dev *bfdev = listener->bfdev; int bar; unsigned long requested_pages, actual_pages; - + if (!bfdev) { return -ENODEV; } - if (vma->vm_end < vma->vm_start) + if (vma->vm_end < vma->vm_start) { return -EINVAL; - + } + vma->vm_private_data = bfdev; - + bar = bf_find_mem_index(vma); - if (bar < 0) + if (bar < 0) { return -EINVAL; - + } + requested_pages = vma_pages(vma); - actual_pages = ((bfdev->info.mem[bar].addr & ~PAGE_MASK) - + bfdev->info.mem[bar].size + PAGE_SIZE -1) >> PAGE_SHIFT; - if (requested_pages > actual_pages) + actual_pages = ((bfdev->info.mem[bar].addr & ~PAGE_MASK) + + bfdev->info.mem[bar].size + PAGE_SIZE - 1) >> + PAGE_SHIFT; + if (requested_pages > actual_pages) { return -EINVAL; - + } + return bf_mmap_physical(vma); } -static int bf_fasync(int fd, struct file *filep, int mode) -{ +static int bf_fasync(int fd, struct file *filep, int mode) { int minor; if (!filep->private_data) { @@ -539,8 +484,7 @@ static int bf_fasync(int fd, struct file *filep, int mode) return (fasync_helper(fd, filep, mode, &bf_global[minor].async_queue)); } -static int bf_open(struct inode *inode, struct file *filep) -{ +static int bf_open(struct inode *inode, struct file *filep) { struct bf_pci_dev *bfdev; struct bf_listener *listener; int i; @@ -550,19 +494,19 @@ static int bf_open(struct inode *inode, struct file *filep) if (listener) { listener->bfdev = bfdev; listener->minor = bfdev->info.minor; - listener->next = NULL; + listener->next = NULL; bf_add_listener(bfdev, listener); - for (i = 0; i < BF_MSIX_ENTRY_CNT; i++) + for (i = 0; i < BF_MSIX_ENTRY_CNT; i++) { listener->event_count[i] = atomic_read(&bfdev->info.event[i]); + } filep->private_data = listener; return 0; } else { - return(-ENOMEM); + return (-ENOMEM); } } -static int bf_release(struct inode *inode, struct file *filep) -{ +static int bf_release(struct inode *inode, struct file *filep) { struct bf_listener *listener = filep->private_data; bf_fasync(-1, filep, 0); /* empty any process id in the notification list */ @@ -574,42 +518,47 @@ static int bf_release(struct inode *inode, struct file *filep) } /* user space support: make read() system call after poll() of select() */ -static ssize_t bf_read(struct file *filep, char __user *buf, - size_t count, loff_t *ppos) -{ +static ssize_t bf_read(struct file *filep, + char __user *buf, + size_t count, + loff_t *ppos) { struct bf_listener *listener = filep->private_data; struct bf_pci_dev *bfdev = listener->bfdev; int retval, event_count[BF_MSIX_ENTRY_CNT]; - int i, mismatch_found = 0; /* OR of per vector mismatch */ + int i, mismatch_found = 0; /* OR of per vector mismatch */ unsigned char cnt_match[BF_MSIX_ENTRY_CNT]; /* per vector mismatch */ if (!bfdev) { return -ENODEV; } /* irq must be setup for read() to work */ - if (!bfdev->info.irq) + if (!bfdev->info.irq) { return -EIO; + } /* ensure that there is enough space on user buffer for the given interrupt * mode */ if (bfdev->mode == BF_INTR_MODE_MSIX) { - if (count < sizeof(s32)*BF_MSIX_ENTRY_CNT) + if (count < sizeof(s32) * BF_MSIX_ENTRY_CNT) { return -EINVAL; - count = sizeof(s32)*BF_MSIX_ENTRY_CNT; + } + count = sizeof(s32) * BF_MSIX_ENTRY_CNT; } else if (bfdev->mode == BF_INTR_MODE_MSI) { - if (count < sizeof(s32)*BF_MSI_ENTRY_CNT) + if (count < sizeof(s32) * BF_MSI_ENTRY_CNT) { return -EINVAL; - count = sizeof(s32)*BF_MSI_ENTRY_CNT; + } + count = sizeof(s32) * BF_MSI_ENTRY_CNT; } else { - if (count < sizeof(s32)) + if (count < sizeof(s32)) { return -EINVAL; + } count = sizeof(s32); } do { set_current_state(TASK_INTERRUPTIBLE); - for (i = 0; i < (count/sizeof(s32)); i++) { + for (i = 0; i < (count / sizeof(s32)); i++) { event_count[i] = atomic_read(&(bfdev->info.event[i])); if (event_count[i] != listener->event_count[i]) { mismatch_found |= 1; @@ -621,10 +570,10 @@ static ssize_t bf_read(struct file *filep, char __user *buf, } if (mismatch_found) { __set_current_state(TASK_RUNNING); - if (copy_to_user(buf, &event_count, count)) + if (copy_to_user(buf, &event_count, count)) { retval = -EFAULT; - else { /* adjust the listener->event_count; */ - for (i = 0 ; i < (count/sizeof(s32)); i++) { + } else { /* adjust the listener->event_count; */ + for (i = 0; i < (count / sizeof(s32)); i++) { if (cnt_match[i]) { listener->event_count[i] = event_count[i]; } @@ -651,25 +600,29 @@ static ssize_t bf_read(struct file *filep, char __user *buf, return retval; } -/* user space is supposed to call this after it is done with interrupt +/* user space is supposed to call this after it is done with interrupt * processing */ -static ssize_t bf_write(struct file *filep, const char __user *buf, - size_t count, loff_t *ppos) -{ +static ssize_t bf_write(struct file *filep, + const char __user *buf, + size_t count, + loff_t *ppos) { struct bf_listener *listener = filep->private_data; struct bf_pci_dev *bfdev = listener->bfdev; ssize_t ret; s32 int_en; - if (!bfdev || !bfdev->info.irq) + if (!bfdev || !bfdev->info.irq) { return -EIO; - - if (count != sizeof(s32)) + } + + if (count != sizeof(s32)) { return -EINVAL; + } - if (copy_from_user(&int_en, buf, count)) + if (copy_from_user(&int_en, buf, count)) { return -EFAULT; + } /* clear pci_error_state */ bfdev->info.pci_error_state = 0; @@ -692,7 +645,11 @@ static long bf_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) } switch(cmd) { case BF_IOCMAPDMAADDR: +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0) + if (access_ok(addr, sizeof(bf_dma_bus_map_t))) { +#else if (access_ok(VERIFY_WRITE, addr, sizeof(bf_dma_bus_map_t))) { +#endif if (copy_from_user(&dma_map, addr, sizeof(bf_dma_bus_map_t))) { return EFAULT; } @@ -703,7 +660,7 @@ static long bf_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) if (dma_mapping_error(&bfdev->pdev->dev, dma_hndl)) { return EFAULT; } - dma_map.dma_addr = (void *)dma_hndl; + dma_map.dma_addr = (void *)(uintptr_t)dma_hndl; if (copy_to_user(addr, &dma_map, sizeof(bf_dma_bus_map_t))) { return EFAULT; } @@ -712,18 +669,55 @@ static long bf_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) } break; case BF_IOCUNMAPDMAADDR: +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0) + if (access_ok(addr, sizeof(bf_dma_bus_map_t))) { +#else if (access_ok(VERIFY_READ, addr, sizeof(bf_dma_bus_map_t))) { +#endif if (copy_from_user(&dma_map, addr, sizeof(bf_dma_bus_map_t))) { return EFAULT; } if (!dma_map.dma_addr || !dma_map.size) { return EFAULT; } - dma_unmap_single(&bfdev->pdev->dev, (dma_addr_t)dma_map.dma_addr, dma_map.size, DMA_BIDIRECTIONAL); + dma_unmap_single(&bfdev->pdev->dev, (dma_addr_t)(uintptr_t)(dma_map.dma_addr), dma_map.size, DMA_BIDIRECTIONAL); } else { return EFAULT; } break; + case BF_TBUS_MSIX_INDEX: + /* not supported for Tofino-1 */ + if (bfdev->info.tof_type == BF_TOFINO_1) { + return EINVAL; + } else { + int i; + bf_tbus_msix_indices_t msix_ind; + if (copy_from_user(&msix_ind, addr, sizeof(bf_tbus_msix_indices_t))) { + return EFAULT; + } + if (msix_ind.cnt > BF_TBUS_MSIX_INDICES_MAX) { + return EINVAL; + } + for (i = 0; i < msix_ind.cnt; i++) { + if (msix_ind.indices[i] >= BF_MSIX_ENTRY_CNT) { + return EINVAL; + } + } + for (i = 0; i < msix_ind.cnt; i++) { + bfdev->info.tbus_msix_ind[i] = msix_ind.indices[i]; + } + bfdev->info.tbus_msix_map_enable = 1; + } + break; + case BF_GET_INTR_MODE: + { + bf_intr_mode_t i_mode; + i_mode.intr_mode = bfdev->mode; + if (copy_to_user(addr, &i_mode, sizeof(bf_intr_mode_t))) { + return EFAULT; + } + } + break; default: return EINVAL; } @@ -731,27 +725,27 @@ static long bf_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) } static const struct file_operations bf_fops = { - .owner = THIS_MODULE, - .open = bf_open, - .release = bf_release, - .unlocked_ioctl = bf_ioctl, - .read = bf_read, - .write = bf_write, - .mmap = bf_mmap, - .poll = bf_poll, - .fasync = bf_fasync, + .owner = THIS_MODULE, + .open = bf_open, + .release = bf_release, + .unlocked_ioctl = bf_ioctl, + .read = bf_read, + .write = bf_write, + .mmap = bf_mmap, + .poll = bf_poll, + .fasync = bf_fasync, }; -static int bf_major_init(struct bf_pci_dev *bfdev, int minor) -{ +static int bf_major_init(struct bf_pci_dev *bfdev, int minor) { struct cdev *cdev; static const char name[] = "bf"; dev_t bf_dev = 0; int result; result = alloc_chrdev_region(&bf_dev, 0, BF_MAX_DEVICE_CNT, name); - if (result) + if (result) { return result; + } result = -ENOMEM; cdev = cdev_alloc(); @@ -763,8 +757,9 @@ static int bf_major_init(struct bf_pci_dev *bfdev, int minor) kobject_set_name(&cdev->kobj, "%s", name); result = cdev_add(cdev, bf_dev, BF_MAX_DEVICE_CNT); - if (result) + if (result) { goto fail_dev_add; + } bf_major = MAJOR(bf_dev); bf_global[minor].bf_cdev = cdev; @@ -775,19 +770,16 @@ static int bf_major_init(struct bf_pci_dev *bfdev, int minor) return result; } -static void bf_major_cleanup(struct bf_pci_dev *bfdev, int minor) -{ +static void bf_major_cleanup(struct bf_pci_dev *bfdev, int minor) { unregister_chrdev_region(MKDEV(bf_major, 0), BF_MAX_DEVICE_CNT); cdev_del(bf_global[minor].bf_cdev); } -static int bf_init_cdev(struct bf_pci_dev *bfdev, int minor) -{ +static int bf_init_cdev(struct bf_pci_dev *bfdev, int minor) { int ret; ret = bf_major_init(bfdev, minor); - if (ret) - return ret; - + if (ret) return ret; + bf_class = class_create(THIS_MODULE, BF_CLASS_NAME); if (!bf_class) { printk(KERN_ERR "create_class failed for bf_dev\n"); @@ -801,28 +793,26 @@ static int bf_init_cdev(struct bf_pci_dev *bfdev, int minor) return ret; } -static void bf_remove_cdev(struct bf_pci_dev *bfdev) -{ +static void bf_remove_cdev(struct bf_pci_dev *bfdev) { class_destroy(bf_class); bf_major_cleanup(bfdev, bfdev->info.minor); } - /** * bf_register_device - register a new userspace mem device * @parent: parent device - * @bfdev: bf pci device + * @bfdev: bf pci device * * returns zero on success or a negative error code. */ -int bf_register_device(struct device *parent, struct bf_pci_dev *bfdev) -{ +int bf_register_device(struct device *parent, struct bf_pci_dev *bfdev) { struct bf_dev_info *info = &bfdev->info; int i, j, ret = 0; int minor; - if (!parent || !info || !info->version) + if (!parent || !info || !info->version) { return -EINVAL; + } init_waitqueue_head(&info->wait); @@ -840,9 +830,8 @@ int bf_register_device(struct device *parent, struct bf_pci_dev *bfdev) return ret; } - info->dev = device_create(bf_class, parent, - MKDEV(bf_major, minor), bfdev, - "bf%d", minor); + info->dev = device_create( + bf_class, parent, MKDEV(bf_major, minor), bfdev, "bf%d", minor); if (!info->dev) { printk(KERN_ERR "BF: device creation failed\n"); return -ENODEV; @@ -861,19 +850,24 @@ int bf_register_device(struct device *parent, struct bf_pci_dev *bfdev) * freed until they are released. */ if (bfdev->mode == BF_INTR_MODE_LEGACY) { - ret = request_irq(info->irq, bf_interrupt, - info->irq_flags, bfdev->name, + ret = request_irq(info->irq, + bf_interrupt, + info->irq_flags, + bfdev->name, (void *)&(bfdev->bf_int_vec[0])); if (ret) { printk(KERN_ERR "bf failed to request legacy irq %ld error %d\n", - info->irq, ret); + info->irq, + ret); return ret; } printk(KERN_NOTICE "BF allocating legacy int vector %ld\n", info->irq); } else if (bfdev->mode == BF_INTR_MODE_MSIX) { for (i = 0; i < info->num_irq; i++) { - ret = request_irq(info->msix_entries[i].vector, bf_interrupt, - info->irq_flags, bfdev->name, + ret = request_irq(info->msix_entries[i].vector, + bf_interrupt, + info->irq_flags, + bfdev->name, (void *)&(bfdev->bf_int_vec[i])); if (ret) { /* undo all other previous bindings */ @@ -883,14 +877,17 @@ int bf_register_device(struct device *parent, struct bf_pci_dev *bfdev) (void *)&(bfdev->bf_int_vec[j])); } return ret; - } + } } printk(KERN_NOTICE "BF allocating %d MSIx vectors from %ld\n", - info->num_irq, info->irq); + info->num_irq, + info->irq); } else if (bfdev->mode == BF_INTR_MODE_MSI) { for (i = 0; i < info->num_irq; i++) { - ret = request_irq(info->irq + i, bf_interrupt, - info->irq_flags, bfdev->name, + ret = request_irq(info->irq + i, + bf_interrupt, + info->irq_flags, + bfdev->name, (void *)&(bfdev->bf_int_vec[i])); if (ret) { /* undo all other previous bindings */ @@ -899,10 +896,11 @@ int bf_register_device(struct device *parent, struct bf_pci_dev *bfdev) free_irq(info->irq + j, (void *)&(bfdev->bf_int_vec[j])); } return ret; - } + } } printk(KERN_NOTICE "BF allocating %d MSI vectors from %ld\n", - info->num_irq, info->irq); + info->num_irq, + info->irq); } } return 0; @@ -910,12 +908,11 @@ int bf_register_device(struct device *parent, struct bf_pci_dev *bfdev) /** * bf_unregister_device - register a new userspace mem device - * @bfdev: bf pci device + * @bfdev: bf pci device * * returns none */ -void bf_unregister_device(struct bf_pci_dev *bfdev) -{ +void bf_unregister_device(struct bf_pci_dev *bfdev) { struct bf_dev_info *info = &bfdev->info; int i; @@ -938,8 +935,7 @@ void bf_unregister_device(struct bf_pci_dev *bfdev) return; } -static inline struct device *pci_dev_to_dev(struct pci_dev *pdev) -{ +static inline struct device *pci_dev_to_dev(struct pci_dev *pdev) { return &pdev->dev; } @@ -957,7 +953,7 @@ static void bf_disable_int_dma(struct bf_pci_dev *bfdev) { /* mask interrupt at shadow level */ bf_addr = (u32 *)((u8 *)bf_base_addr + 0xc0); for (i = 0; i < 16; i++) { - *bf_addr = 0xffffffff; + *bf_addr = 0xffffffffUL; bf_addr++; } /* mask DMA */ @@ -967,18 +963,17 @@ static void bf_disable_int_dma(struct bf_pci_dev *bfdev) { *bf_addr = val; } -static int -bf_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) -{ +static int bf_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct bf_pci_dev *bfdev; - int err; + int err, pci_use_highmem; int i, num_irq; memset(bf_global, 0, sizeof(bf_global)); bfdev = kzalloc(sizeof(struct bf_pci_dev), GFP_KERNEL); - if (!bfdev) + if (!bfdev) { return -ENOMEM; + } /* init the cookies to be passed to ISRs */ for (i = 0; i < BF_MSIX_ENTRY_CNT; i++) { @@ -992,12 +987,32 @@ bf_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) /* clear pci_error_state */ bfdev->info.pci_error_state = 0; + /* mark pci device_id type */ + bfdev->info.pci_dev_id = pdev->device; + switch (pdev->device) { + case TOFINO2_DEV_ID_A0: + case TOFINO2_DEV_ID_A00: + case TOFINO2_DEV_ID_B0: + bfdev->info.tof_type = BF_TOFINO_2; + break; + default: + bfdev->info.tof_type = BF_TOFINO_1; + break; + } + /* intialize TBUS MSIX indices */ + for (i = 0; i < BF_TBUS_MSIX_INDICES_MAX; i++) { + if (bfdev->info.tof_type == BF_TOFINO_1) { + bfdev->info.tbus_msix_ind[i] = BF_TBUS_MSIX_BASE_INDEX_TOF1 + i; + } else if (bfdev->info.tof_type == BF_TOFINO_2) { + bfdev->info.tbus_msix_ind[i] = BF_TBUS_MSIX_INDEX_INVALID; + } + } /* * enable device */ err = pci_enable_device(pdev); if (err != 0) { - dev_err(&pdev->dev, "Cannot enable PCI device\n"); + printk(KERN_ERR "bf cannot enable PCI device\n"); goto fail_free; } @@ -1007,27 +1022,29 @@ bf_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) */ err = pci_request_regions(pdev, "bf_umem"); if (err != 0) { - dev_err(&pdev->dev, "Cannot request regions\n"); + printk(KERN_ERR "bf Cannot request regions\n"); goto fail_pci_disable; } /* remap IO memory */ err = bf_setup_bars(pdev, &bfdev->info); - if (err != 0) + if (err != 0) { + printk(KERN_ERR "bf Cannot setup BARs\n"); goto fail_release_iomem; + } if (!dma_set_mask(pci_dev_to_dev(pdev), DMA_BIT_MASK(64)) && !dma_set_coherent_mask(pci_dev_to_dev(pdev), DMA_BIT_MASK(64))) { + pci_use_highmem = 1; } else { err = dma_set_mask(pci_dev_to_dev(pdev), DMA_BIT_MASK(32)); if (err) { - err = dma_set_coherent_mask(pci_dev_to_dev(pdev), - DMA_BIT_MASK(32)); + err = dma_set_coherent_mask(pci_dev_to_dev(pdev), DMA_BIT_MASK(32)); if (err) { - dev_err(pci_dev_to_dev(pdev), "No usable DMA " - "configuration, aborting\n"); - goto fail_release_iomem; + printk(KERN_ERR "bf no usable DMA configuration, aborting\n"); + goto fail_release_iomem; } } + pci_use_highmem = 0; } /* enable pci error reporting */ @@ -1054,126 +1071,142 @@ bf_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) switch (bf_intr_mode_default) { #ifdef CONFIG_PCI_MSI - case BF_INTR_MODE_MSIX: - /* Only 1 msi-x vector needed */ - bfdev->info.msix_entries = kcalloc(BF_MSIX_ENTRY_CNT, - sizeof(struct msix_entry), GFP_KERNEL); - if (!bfdev->info.msix_entries) { - err = -ENOMEM; - goto fail_clear_pci_master; - } - for (i = 0; i < BF_MSIX_ENTRY_CNT; i++) { - bfdev->info.msix_entries[i].entry= i; - } + case BF_INTR_MODE_MSIX: + /* Only 1 msi-x vector needed */ + bfdev->info.msix_entries = + kcalloc(BF_MSIX_ENTRY_CNT, sizeof(struct msix_entry), GFP_KERNEL); + if (!bfdev->info.msix_entries) { + err = -ENOMEM; + goto fail_clear_pci_master; + } + for (i = 0; i < BF_MSIX_ENTRY_CNT; i++) { + bfdev->info.msix_entries[i].entry = i; + } #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0) - num_irq = pci_enable_msix(pdev, bfdev->info.msix_entries, - BF_MSIX_ENTRY_CNT); - if (num_irq == 0) { - dev_dbg(&pdev->dev, "using MSI-X"); - bfdev->info.num_irq = BF_MSIX_ENTRY_CNT; - bfdev->info.irq = bfdev->info.msix_entries[0].vector; - bfdev->mode = BF_INTR_MODE_MSIX; - printk(KERN_DEBUG "bf using %d MSIX irq from %ld\n", num_irq, - bfdev->info.irq); - break; - } + num_irq = pci_enable_msix(pdev, bfdev->info.msix_entries, + BF_MSIX_ENTRY_CNT); + if (num_irq == 0) { + bfdev->info.num_irq = BF_MSIX_ENTRY_CNT; + bfdev->info.irq = bfdev->info.msix_entries[0].vector; + bfdev->mode = BF_INTR_MODE_MSIX; + printk(KERN_DEBUG "bf using %d MSIX irq from %ld\n", num_irq, + bfdev->info.irq); + break; + } #else - num_irq = pci_enable_msix_range(pdev, bfdev->info.msix_entries, - BF_MSIX_ENTRY_CNT, BF_MSIX_ENTRY_CNT); - if (num_irq == BF_MSIX_ENTRY_CNT) { - dev_dbg(&pdev->dev, "using MSI-X"); - bfdev->info.num_irq = num_irq; - bfdev->info.irq = bfdev->info.msix_entries[0].vector; - bfdev->mode = BF_INTR_MODE_MSIX; - printk(KERN_DEBUG "bf using %d MSIX irq from %ld\n", num_irq, - bfdev->info.irq); - break; - } else { - if (num_irq) - pci_disable_msix(pdev); - kfree(bfdev->info.msix_entries); - bfdev->info.msix_entries = NULL; - printk(KERN_ERR "bf error allocating MSIX vectors. Trying MSI...\n"); - /* and, fall back to MSI */ - } + num_irq = pci_enable_msix_range( + pdev, bfdev->info.msix_entries, BF_MSIX_ENTRY_CNT, BF_MSIX_ENTRY_CNT); + if (num_irq == BF_MSIX_ENTRY_CNT) { + bfdev->info.num_irq = num_irq; + bfdev->info.irq = bfdev->info.msix_entries[0].vector; + bfdev->mode = BF_INTR_MODE_MSIX; + printk(KERN_DEBUG "bf using %d MSIX irq from %ld\n", + num_irq, + bfdev->info.irq); + break; + } else { + if (num_irq) pci_disable_msix(pdev); + kfree(bfdev->info.msix_entries); + bfdev->info.msix_entries = NULL; + printk(KERN_ERR "bf error allocating MSIX vectors. Trying MSI...\n"); + /* and, fall back to MSI */ + } #endif /* LINUX_VERSION_CODE */ /* ** intentional no-break */ - case BF_INTR_MODE_MSI: + case BF_INTR_MODE_MSI: #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0) - num_irq = pci_enable_msi_block(pdev, BF_MSI_ENTRY_CNT); - /* we must get requested number of MSI vectors enabled */ - if (num_irq == 0) { - dev_dbg(&pdev->dev, "using MSI"); - bfdev->info.num_irq = BF_MSI_ENTRY_CNT; - bfdev->info.irq = pdev->irq; - bfdev->mode = BF_INTR_MODE_MSI; - printk(KERN_DEBUG "bf using %d MSI irq from %ld\n", bfdev->info.num_irq, + num_irq = pci_enable_msi_block(pdev, BF_MSI_ENTRY_CNT); + /* we must get requested number of MSI vectors enabled */ + if (num_irq == 0) { + bfdev->info.num_irq = BF_MSI_ENTRY_CNT; + bfdev->info.irq = pdev->irq; + bfdev->mode = BF_INTR_MODE_MSI; + printk(KERN_DEBUG "bf using %d MSI irq from %ld\n", bfdev->info.num_irq, bfdev->info.irq); - break; - } + break; + } #elif LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) - num_irq = pci_enable_msi_range(pdev, BF_MSI_ENTRY_CNT, BF_MSI_ENTRY_CNT); - if (num_irq > 0) { - dev_dbg(&pdev->dev, "using MSI"); - bfdev->info.num_irq = num_irq; - bfdev->info.irq = pdev->irq; - bfdev->mode = BF_INTR_MODE_MSI; - printk(KERN_DEBUG "bf using %d MSI irq from %ld\n", bfdev->info.num_irq, - bfdev->info.irq); - break; - } + num_irq = pci_enable_msi_range(pdev, BF_MSI_ENTRY_CNT, BF_MSI_ENTRY_CNT); + if (num_irq > 0) { + bfdev->info.num_irq = num_irq; + bfdev->info.irq = pdev->irq; + bfdev->mode = BF_INTR_MODE_MSI; + printk(KERN_DEBUG "bf using %d MSI irq from %ld\n", + bfdev->info.num_irq, + bfdev->info.irq); + break; + } #else - num_irq = pci_alloc_irq_vectors_affinity(pdev, BF_MSI_ENTRY_CNT, - BF_MSI_ENTRY_CNT, PCI_IRQ_MSI | PCI_IRQ_AFFINITY, NULL); - if (num_irq > 0) { - dev_dbg(&pdev->dev, "using MSI"); - bfdev->info.num_irq = num_irq; - bfdev->info.irq = pci_irq_vector(pdev, 0); - bfdev->mode = BF_INTR_MODE_MSI; - printk(KERN_DEBUG "bf using %d MSI irq from %ld\n", bfdev->info.num_irq, + num_irq = pci_alloc_irq_vectors_affinity(pdev, BF_MSI_ENTRY_CNT, + BF_MSI_ENTRY_CNT, PCI_IRQ_MSI | PCI_IRQ_AFFINITY, NULL); + if (num_irq > 0) { + bfdev->info.num_irq = num_irq; + bfdev->info.irq = pci_irq_vector(pdev, 0); + bfdev->mode = BF_INTR_MODE_MSI; + printk(KERN_DEBUG "bf using %d MSI irq from %ld\n", bfdev->info.num_irq, bfdev->info.irq); - break; - } + break; + } #endif /* LINUX_VERSION_CODE */ #endif /* CONFIG_PCI_MSI */ /* fall back to Legacy Interrupt, intentional no-break */ - case BF_INTR_MODE_LEGACY: - if (pci_intx_mask_supported(pdev)) { - dev_dbg(&pdev->dev, "using INTX"); - bfdev->info.irq_flags = IRQF_SHARED; - bfdev->info.irq = pdev->irq; - bfdev->mode = BF_INTR_MODE_LEGACY; - printk(KERN_DEBUG "bf using LEGACY irq %ld\n", bfdev->info.irq); - break; - } - dev_notice(&pdev->dev, "PCI INTx mask not supported\n"); + case BF_INTR_MODE_LEGACY: + if (pci_intx_mask_supported(pdev)) { + bfdev->info.irq_flags = IRQF_SHARED; + bfdev->info.irq = pdev->irq; + bfdev->mode = BF_INTR_MODE_LEGACY; + printk(KERN_DEBUG "bf using LEGACY irq %ld\n", bfdev->info.irq); + break; + } + printk(KERN_NOTICE " bf PCI INTx mask not supported\n"); /* fall back to no Interrupt, intentional no-break */ - case BF_INTR_MODE_NONE: - bfdev->info.irq = 0; - bfdev->info.num_irq = 0; - bfdev->mode = BF_INTR_MODE_NONE; - break; + case BF_INTR_MODE_NONE: + bfdev->info.irq = 0; + bfdev->info.num_irq = 0; + bfdev->mode = BF_INTR_MODE_NONE; + break; - default: - dev_err(&pdev->dev, "invalid IRQ mode %u", bf_intr_mode_default); - err = -EINVAL; - goto fail_clear_pci_master; + default: + printk(KERN_DEBUG "bf invalid IRQ mode %u", bf_intr_mode_default); + err = -EINVAL; + goto fail_clear_pci_master; } pci_set_drvdata(pdev, bfdev); sprintf(bfdev->name, "bf_%d", bfdev->info.minor); /* register bf driver */ err = bf_register_device(&pdev->dev, bfdev); - if (err != 0) + if (err != 0) { goto fail_release_irq; + } bf_global[bfdev->info.minor].async_queue = NULL; bf_global[bfdev->info.minor].bfdev = bfdev; - dev_info(&pdev->dev, "bf device %d registered with irq %ld\n", - bfdev->instance, bfdev->info.irq); + dev_info(&pdev->dev, + "bf device %d registered with irq %ld\n", + bfdev->instance, + bfdev->info.irq); printk(KERN_ALERT "bf probe ok\n"); +#ifdef BF_INCLUDE_KPKT + if (kpkt_mode) { + err = bf_kpkt_init(pdev, + bfdev->info.mem[0].internal_addr, + &bfdev->adapter_ptr, + bfdev->info.minor, + pci_use_highmem, + kpkt_hd_room, + kpkt_dr_int_en, + kpkt_rx_count); + if (err == 0) { + printk(KERN_ALERT "bf_kpkt kernel processing enabled\n"); + } else { + printk(KERN_ALERT "error starting bf_kpkt kernel processing\n"); + bfdev->adapter_ptr = NULL; + } + } +#endif return 0; fail_release_irq: @@ -1182,11 +1215,11 @@ bf_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) pci_disable_msix(bfdev->pdev); kfree(bfdev->info.msix_entries); bfdev->info.msix_entries = NULL; - } - else if (bfdev->mode == BF_INTR_MODE_MSI) + } else if (bfdev->mode == BF_INTR_MODE_MSI) { pci_disable_msi(bfdev->pdev); + } fail_clear_pci_master: - pci_clear_master(pdev); + pci_clear_master(pdev); fail_release_iomem: bf_pci_release_iomem(&bfdev->info); pci_release_regions(pdev); @@ -1199,22 +1232,24 @@ bf_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) return err; } - -static void -bf_pci_remove(struct pci_dev *pdev) -{ +static void bf_pci_remove(struct pci_dev *pdev) { struct bf_pci_dev *bfdev = pci_get_drvdata(pdev); struct bf_listener *cur_listener; +#ifdef BF_INCLUDE_KPKT + if (kpkt_mode) { + bf_kpkt_remove(bfdev->adapter_ptr); + } +#endif bf_disable_int_dma(bfdev); bf_unregister_device(bfdev); if (bfdev->mode == BF_INTR_MODE_MSIX) { pci_disable_msix(pdev); kfree(bfdev->info.msix_entries); bfdev->info.msix_entries = NULL; - } - else if (bfdev->mode == BF_INTR_MODE_MSI) + } else if (bfdev->mode == BF_INTR_MODE_MSI) { pci_disable_msi(pdev); + } pci_clear_master(pdev); bf_pci_release_iomem(&bfdev->info); pci_release_regions(pdev); @@ -1234,6 +1269,17 @@ bf_pci_remove(struct pci_dev *pdev) kfree(bfdev); } +/* AER support callbacks. Refer to: + * https://www.kernel.org/doc/Documentation/PCI/pcieaer-howto.txt + * and + * https://www.kernel.org/doc/Documentation/PCI/pci-error-recovery.txt + * + * from bf_kdrv point of view, AER uncorrected errors (fatal and non-fatal) + * should not cause pci link reset (upstream port AER callbacks must also + * support this requirements of bf_kdrv) + * Device, however, is not expected to function after uncorrected errors + * but, application has chance to perform diags without resetting pci link + */ /** * bf_pci_error_detected - called when PCI error is detected * @pdev: Pointer to PCI device @@ -1242,10 +1288,8 @@ bf_pci_remove(struct pci_dev *pdev) * called when root complex detects pci error associated with the device */ static pci_ers_result_t bf_pci_error_detected(struct pci_dev *pdev, - pci_channel_state_t state) -{ + pci_channel_state_t state) { struct bf_pci_dev *bfdev = pci_get_drvdata(pdev); - int minor; if (!bfdev) { return PCI_ERS_RESULT_NONE; @@ -1253,15 +1297,35 @@ static pci_ers_result_t bf_pci_error_detected(struct pci_dev *pdev, printk(KERN_ERR "pci_err_detected state %d\n", state); if (state == pci_channel_io_perm_failure || state == pci_channel_io_frozen) { bfdev->info.pci_error_state = 1; +#ifdef BF_INCLUDE_KPKT + if (kpkt_mode) { + bf_kpkt_set_pci_error(bfdev->adapter_ptr, 1); + } +#endif + /* we do not want pci link to go down. The user space application + * should collect the diag info, terminate the application and unload the + * kernel module + */ + return PCI_ERS_RESULT_CAN_RECOVER; /* to prevent pci link down */ + } else { + return PCI_ERS_RESULT_CAN_RECOVER; + } +} + +static pci_ers_result_t bf_pci_mmio_enabled(struct pci_dev *dev) { + struct bf_pci_dev *bfdev = pci_get_drvdata(dev); + + printk(KERN_ERR "BF pci_mmio_enabled invoked after pci error\n"); + pci_cleanup_aer_uncorrect_error_status(dev); + + if (bfdev) { /* send a signal to the user space program of the error */ - minor = bfdev->info.minor; + int minor = bfdev->info.minor; if (minor < BF_MAX_DEVICE_CNT && bf_global[minor].async_queue) { kill_fasync(&bf_global[minor].async_queue, SIGIO, POLL_ERR); } - return PCI_ERS_RESULT_DISCONNECT; - } else { - return PCI_ERS_RESULT_NONE; } + return PCI_ERS_RESULT_RECOVERED; } /** @@ -1270,13 +1334,13 @@ static pci_ers_result_t bf_pci_error_detected(struct pci_dev *pdev, * * Restart the card from scratch, as if from a cold-boot. */ -static pci_ers_result_t bf_pci_slot_reset(struct pci_dev *pdev) -{ +static pci_ers_result_t bf_pci_slot_reset(struct pci_dev *pdev) { /* nothing to do for now as we do not expect to get backto normal after - * a pcie link reset + * a pcie link reset. Not expected to be invoked. * TBD: fill in this function if tofino can recover after an error */ - return PCI_ERS_RESULT_DISCONNECT; + printk(KERN_ERR "BF pci_slot_reset invoked after pci error\n"); + return PCI_ERS_RESULT_RECOVERED; } /** @@ -1286,22 +1350,13 @@ static pci_ers_result_t bf_pci_slot_reset(struct pci_dev *pdev) * This callback is called when the error recovery driver tells us that * its OK to resume normal operation. */ -static void bf_pci_resume(struct pci_dev *pdev) -{ - /* this function should never be called for Tofinoi */ - struct bf_pci_dev *bfdev = pci_get_drvdata(pdev); - +static void bf_pci_resume(struct pci_dev *pdev) { printk(KERN_ERR "BF io_resume invoked after pci error\n"); - if (bfdev) { - bfdev->info.pci_error_state = 0; - } } -static int -bf_config_intr_mode(char *intr_str) -{ +static int bf_config_intr_mode(char *intr_str) { if (!intr_str) { - pr_info("Use MSIX interrupt by default\n"); + pr_info("Use MSI interrupt by default\n"); return 0; } @@ -1314,67 +1369,108 @@ bf_config_intr_mode(char *intr_str) } else if (!strcmp(intr_str, BF_INTR_MODE_LEGACY_NAME)) { bf_intr_mode_default = BF_INTR_MODE_LEGACY; pr_info("Use legacy interrupt\n"); - } else { + } else if (!strcmp(intr_str, BF_INTR_MODE_NONE_NAME)) { bf_intr_mode_default = BF_INTR_MODE_NONE; - pr_info(" No Interrupt \n"); + pr_info("BF interrupt disabled\n"); + } else { + pr_info("Error: bad intr_mode parameter - %s\n", intr_str); + return -EINVAL; } - return 0; } static const struct pci_device_id bf_pci_tbl[] = { - {PCI_VDEVICE(BF, TOFINO_DEV_ID_A0), 0}, - {PCI_VDEVICE(BF, TOFINO_DEV_ID_B0), 0}, - {PCI_VDEVICE(BF, TOFINO2_DEV_ID_A0), 0}, - /* required last entry */ - { .device = 0 } -}; + {PCI_VDEVICE(BF, TOFINO_DEV_ID_A0), 0}, + {PCI_VDEVICE(BF, TOFINO_DEV_ID_B0), 0}, + {PCI_VDEVICE(BF, TOFINO2_DEV_ID_A0), 0}, + {PCI_VDEVICE(BF, TOFINO2_DEV_ID_A00), 0}, + {PCI_VDEVICE(BF, TOFINO2_DEV_ID_B0), 0}, + /* required last entry */ + {.device = 0}}; /* PCI bus error handlers */ static struct pci_error_handlers bf_pci_err_handler = { - .error_detected = bf_pci_error_detected, - .slot_reset = bf_pci_slot_reset, - .resume = bf_pci_resume, + .error_detected = bf_pci_error_detected, + .mmio_enabled = bf_pci_mmio_enabled, + .slot_reset = bf_pci_slot_reset, + .resume = bf_pci_resume, }; -static struct pci_driver bf_pci_driver = { - .name = "bf", - .id_table = bf_pci_tbl, - .probe = bf_pci_probe, - .remove = bf_pci_remove, - .err_handler = &bf_pci_err_handler -}; +static struct pci_driver bf_pci_driver = {.name = "bf", + .id_table = bf_pci_tbl, + .probe = bf_pci_probe, + .remove = bf_pci_remove, + .err_handler = &bf_pci_err_handler}; -static int __init -bfdrv_init(void) -{ +static int __init bfdrv_init(void) { int ret; ret = bf_config_intr_mode(intr_mode); - if (ret < 0) + /* do not enable DR interrupt if not using MSI or not in kpkt mode */ + if ((bf_intr_mode_default != BF_INTR_MODE_MSI && + bf_intr_mode_default != BF_INTR_MODE_LEGACY) || kpkt_mode == 0) { + kpkt_dr_int_en = 0; + } + if (kpkt_mode) { + printk(KERN_NOTICE "kpkt_mode %d hd_room %d dr_int_en %d rx_count %d\n", + kpkt_mode, + kpkt_hd_room, + kpkt_dr_int_en, + kpkt_rx_count); + } + if (ret < 0) { return ret; - + } spin_lock_init(&bf_nonisr_lock); return pci_register_driver(&bf_pci_driver); } -static void __exit -bfdrv_exit(void) -{ +static void __exit bfdrv_exit(void) { pci_unregister_driver(&bf_pci_driver); + intr_mode = NULL; + kpkt_mode = 0; } module_init(bfdrv_init); module_exit(bfdrv_exit); +module_param(kpkt_mode, int, S_IRUGO); +MODULE_PARM_DESC(kpkt_mode, + "bf kernel mode pkt processing (default=off):\n" + " 1 Use kernel mode bf_pkt processing\n" + " 0 Do not use kernel mode bf_pkt processing\n" + "\n"); + +module_param(kpkt_hd_room, int, S_IRUGO); +MODULE_PARM_DESC(kpkt_hd_room, + "head room to reserve when receiving packets (default=32):\n" + "\n"); + +module_param(kpkt_rx_count, int, S_IRUGO); +MODULE_PARM_DESC(kpkt_rx_count, + "number of buffers per rx pkt ring (default=256):\n" + "\n"); +/* dr_int_en is applicable only if MSI interrupt mode is selected */ +module_param(kpkt_dr_int_en, int, S_IRUGO); +MODULE_PARM_DESC(kpkt_dr_int_en, + "bf pkt Interrupt enable (default=1):\n" + " 1 use interrupt\n" + " 0 Do not use interrupt\n" + "\n"); + module_param(intr_mode, charp, S_IRUGO); MODULE_PARM_DESC(intr_mode, -"bf interrupt mode (default=msix):\n" -" " BF_INTR_MODE_MSIX_NAME " Use MSIX interrupt\n" -" " BF_INTR_MODE_MSI_NAME " Use MSI interrupt\n" -" " BF_INTR_MODE_LEGACY_NAME " Use Legacy interrupt\n" -"\n"); + "bf interrupt mode (default=msix):\n" + " " BF_INTR_MODE_MSIX_NAME + " Use MSIX interrupt\n" + " " BF_INTR_MODE_MSI_NAME + " Use MSI interrupt\n" + " " BF_INTR_MODE_LEGACY_NAME + " Use Legacy interrupt\n" + " " BF_INTR_MODE_NONE_NAME + " Use no interrupt\n" + "\n"); MODULE_DEVICE_TABLE(pci, bf_pci_tbl); MODULE_DESCRIPTION("Barefoot Tofino PCI device"); diff --git a/platform/barefoot/bfn-modules/modules/bf_kdrv.h b/platform/barefoot/bfn-modules/modules/bf_kdrv.h new file mode 100644 index 000000000000..de5ca4bbc71c --- /dev/null +++ b/platform/barefoot/bfn-modules/modules/bf_kdrv.h @@ -0,0 +1,146 @@ +/******************************************************************************* + Barefoot Networks Switch ASIC Linux driver + Copyright(c) 2015 - 2019 Barefoot Networks, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + This program is distributed in the hope it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + + The full GNU General Public License is included in this distribution in + the file called "COPYING". + + Contact Information: + info@barefootnetworks.com + Barefoot Networks, 4750 Patrick Henry Drive, Santa Clara CA 95054 + +*******************************************************************************/ +#ifndef _BF_KDRV_H_ +#define _BF_KDRV_H_ + +#include +#include +#include + +#ifndef phys_addr_t +typedef uint64_t phys_addr_t; +#endif + +#define PCI_VENDOR_ID_BF 0x1d1c +#define TOFINO_DEV_ID_A0 0x01 +#define TOFINO_DEV_ID_B0 0x10 +#define TOFINO2_DEV_ID_A0 0x0100 +#define TOFINO2_DEV_ID_A00 0x0000 +#define TOFINO2_DEV_ID_B0 0x0110 + +#ifndef PCI_MSIX_ENTRY_SIZE +#define PCI_MSIX_ENTRY_SIZE 16 +#define PCI_MSIX_ENTRY_LOWER_ADDR 0 +#define PCI_MSIX_ENTRY_UPPER_ADDR 4 +#define PCI_MSIX_ENTRY_DATA 8 +#define PCI_MSIX_ENTRY_VECTOR_CTRL 12 +#define PCI_MSIX_ENTRY_CTRL_MASKBIT 1 +#endif + +#define BF_CLASS_NAME "bf" +#define BF_MAX_DEVICE_CNT 256 +#define BF_INTR_MODE_NONE_NAME "none" +#define BF_INTR_MODE_LEGACY_NAME "legacy" +#define BF_INTR_MODE_MSI_NAME "msi" +#define BF_INTR_MODE_MSIX_NAME "msix" +#define BF_MAX_BAR_MAPS 6 +#define BF_MSIX_ENTRY_CNT 32 /* 512 for tofino-1 */ +#define BF_MSI_ENTRY_CNT 2 +#define BF_MSI_INT_TBUS 1 + +#define BF_TBUS_MSIX_INDEX_INVALID (0) +#define BF_TBUS_MSIX_BASE_INDEX_TOF1 (32) + +/* Tofino generation type */ +typedef enum { + BF_TOFINO_NONE = 0, + BF_TOFINO_1, + BF_TOFINO_2, +} bf_tof_type; + +/* device memory */ +struct bf_dev_mem { + const char *name; + phys_addr_t addr; + resource_size_t size; + void __iomem *internal_addr; +}; + +struct bf_listener { + struct bf_pci_dev *bfdev; + s32 event_count[BF_MSIX_ENTRY_CNT]; + int minor; + struct bf_listener *next; +}; + +/* device information */ +struct bf_dev_info { + struct module *owner; + struct device *dev; + int minor; + atomic_t event[BF_MSIX_ENTRY_CNT]; + wait_queue_head_t wait; + const char *version; + struct bf_dev_mem mem[BF_MAX_BAR_MAPS]; + struct msix_entry *msix_entries; + long irq; /* first irq vector */ + int num_irq; /* number of irq vectors */ + unsigned long irq_flags; /* sharable ?? */ + uint16_t pci_dev_id; /* generation type of BF ASIC */ + bf_tof_type tof_type; /* Tofino generation type */ + /* msix index assigned to tbus MSIX for Tofino-2 only */ + int tbus_msix_ind[BF_TBUS_MSIX_INDICES_MAX]; + int tbus_msix_map_enable; + int pci_error_state; /* was there a pci bus error */ +}; + +/* cookie to be passed to IRQ handler, useful especially with MSIX */ +struct bf_int_vector { + struct bf_pci_dev *bf_dev; + int int_vec_offset; +}; + +/** + * A structure describing the private information for a BF pcie device. + */ +struct bf_pci_dev { + struct bf_dev_info info; + struct pci_dev *pdev; + enum bf_intr_mode mode; + u8 instance; + char name[16]; + struct bf_int_vector bf_int_vec[BF_MSIX_ENTRY_CNT]; + struct bf_listener * + listener_head; /* head of a singly linked list of listeners */ + void *adapter_ptr; /* pkt processing adapter */ +}; + +/* TBD: Need to build with CONFIG_PCI_MSI */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0) +#if defined(RHEL_RELEASE_CODE) +#else +extern int pci_enable_msi_block(struct pci_dev *dev, unsigned int nvec); +#endif /* defined(RHEL_RELEASE_CODE) */ +extern int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec); +#else +extern int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec); +extern int pci_enable_msix_range(struct pci_dev *dev, + struct msix_entry *entries, + int minvec, + int maxvec); +#endif + +#endif /* _BF_KDRV_H_ */ From eb55c22742ec4f2fe66e4a152576a208af58b0b2 Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Tue, 14 Apr 2020 20:27:27 +0300 Subject: [PATCH 162/178] [Mellanox] bug fix - adpt sfputil plugin to support ACS-MSN4700 (#4361) --- device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py index 07dbbe1cc21b..b5f2a335b09c 100644 --- a/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py +++ b/device/mellanox/x86_64-mlnx_msn2700-r0/plugins/sfputil.py @@ -41,7 +41,7 @@ # magic code defnition for port number, qsfp port position of each hwsku # port_position_tuple = (PORT_START, QSFP_PORT_START, PORT_END, PORT_IN_BLOCK, EEPROM_OFFSET) -hwsku_dict = {'ACS-MSN2700': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, "LS-SN2700":0, 'ACS-MSN2740': 0, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 3, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'ACS-MSN3800': 4, 'Mellanox-SN3800-D112C8': 4} +hwsku_dict = {'ACS-MSN2700': 0, 'Mellanox-SN2700': 0, 'Mellanox-SN2700-D48C8': 0, 'LS-SN2700': 0, 'ACS-MSN2740': 0, 'ACS-MSN2100': 1, 'ACS-MSN2410': 2, 'ACS-MSN2010': 3, 'ACS-MSN3700': 0, 'ACS-MSN3700C': 0, 'ACS-MSN3800': 4, 'Mellanox-SN3800-D112C8': 4, 'ACS-MSN4700': 0} port_position_tuple_list = [(0, 0, 31, 32, 1), (0, 0, 15, 16, 1), (0, 48, 55, 56, 1), (0, 18, 21, 22, 1), (0, 0, 63, 64, 1)] def log_info(msg, also_print_to_console=False): From c3e030b76941f9e3ec9eed1c3659e17283d02dc0 Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Tue, 14 Apr 2020 19:55:08 +0300 Subject: [PATCH 163/178] [mellanox]: Enable CPLD update progress bar (#4363) Signed-off-by: Nazarii Hnydyn --- .../sonic_platform/component.py | 37 ++++--------------- 1 file changed, 7 insertions(+), 30 deletions(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py index 468420eaf0aa..13e3953a03ad 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py @@ -14,7 +14,6 @@ import io import os import re - import sys except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -243,8 +242,7 @@ class ComponentCPLD(Component): CPLD_PART_NUMBER_DEFAULT = ZERO CPLD_VERSION_MINOR_DEFAULT = ZERO - CPLD_UPDATE_COMMAND = 'cpldupdate --dev {} {}' - CPLD_INSTALL_SUCCESS_FLAG = 'PASS!' + CPLD_UPDATE_COMMAND = 'cpldupdate --dev {} --print-progress {}' MST_DEVICE_PATTERN = '/dev/mst/mt[0-9]*_pci_cr0' @@ -303,7 +301,7 @@ def install_firmware(self, image_path): Details: The command "cpldupdate" is provided to install CPLD. There are two ways to do it: - 1. To burn CPLD via gpio, which is faster but only supported on new systems, like Anaconda, ... + 1. To burn CPLD via gpio, which is faster but only supported on new systems, like SN3700, ... 2. To install CPLD via firmware, which is slower but supported on older systems. This also requires the mst device designated. "cpldupdate --dev " has the logic of testing whether to update via gpio is supported, @@ -326,37 +324,16 @@ def install_firmware(self, image_path): return False cmdline = self.CPLD_UPDATE_COMMAND.format(mst_dev_list[0], image_path) - outputline = "" success_flag = False - try: - proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT) - while True: - out = proc.stdout.read(1) - - if out == '' and proc.poll() != None: - break - - if out != '': - sys.stdout.write(out) - sys.stdout.flush() - outputline += out - - if (out == '\n' or out == '\r') and len(outputline): - m = re.search(self.CPLD_INSTALL_SUCCESS_FLAG, outputline) - if m and m.group(0) == self.CPLD_INSTALL_SUCCESS_FLAG: - success_flag = True - if proc.returncode: - print("ERROR: Upgrade CPLD failed, return code {}".format(proc.returncode)) - success_flag = False - - except OSError as e: - raise RuntimeError("Failed to execute command {} due to {}".format(cmdline, repr(e))) + try: + subprocess.check_call(cmdline, stderr=subprocess.STDOUT, shell=True) + success_flag = True + except subprocess.CalledProcessError as e: + print("ERROR: Failed to upgrade CPLD: rc={}".format(e.returncode)) if success_flag: print("INFO: Refresh or power cycle is required to finish CPLD installation") - else: - print("ERROR: Failed to install CPLD") return success_flag From e4bd7ab18964bb3036f870c0feebeca7fa041ab0 Mon Sep 17 00:00:00 2001 From: Kebo Liu Date: Tue, 14 Apr 2020 20:20:06 +0300 Subject: [PATCH 164/178] [Mellanox] Extend mellanox platform API to report SFP error event (#4365) * extend mellanox platform API to report SFP error event * remove unnecessary loop code * install enum34 to pmon to support using Enum --- dockers/docker-platform-monitor/Dockerfile.j2 | 3 +- .../sonic_platform/chassis.py | 15 +-- .../sonic_platform/sfp_event.py | 94 ++++++++++++++++--- 3 files changed, 86 insertions(+), 26 deletions(-) diff --git a/dockers/docker-platform-monitor/Dockerfile.j2 b/dockers/docker-platform-monitor/Dockerfile.j2 index fd11f628559c..61374af7d544 100755 --- a/dockers/docker-platform-monitor/Dockerfile.j2 +++ b/dockers/docker-platform-monitor/Dockerfile.j2 @@ -18,7 +18,8 @@ RUN apt-get update && \ rrdtool \ python-smbus \ ethtool \ - dmidecode + dmidecode && \ + pip install enum34 {% if docker_platform_monitor_debs.strip() -%} # Copy locally-built Debian package dependencies diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index 5884b833b12b..5edb82bfe517 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -433,25 +433,12 @@ def get_change_event(self, timeout=0): timeout = MAX_SELECT_DELAY while True: status = self.sfp_event.check_sfp_status(port_dict, timeout) - if not port_dict == {}: + if bool(port_dict): break else: status = self.sfp_event.check_sfp_status(port_dict, timeout) if status: - # get_change_event has the meaning of retrieving all the notifications through a single call. - # Typically this is implemented via a select framework which requires the underlay file-reading - # interface able to retrieve all notifications without blocking once the fd has been selected. - # However, sdk doesn't provide any interface satisfied the requirement. as a result, - # check_sfp_status returns only one notification may indicate more notifications in its queue. - # In this sense, we have to iterate in a loop to get all the notifications in case that - # the first call returns at least one. - i = 0 - while i < self.MAX_SELECT_EVENT_RETURNED: - status = self.sfp_event.check_sfp_status(port_dict, 0) - if not status: - break - i = i + 1 return True, {'sfp':port_dict} else: return True, {'sfp':{}} diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp_event.py b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp_event.py index e92884fc3f33..0ed75c26c63a 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp_event.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp_event.py @@ -11,15 +11,69 @@ from python_sdk_api.sx_api import * from sonic_daemon_base.daemon_base import Logger -SDK_SFP_STATE_IN = 0x1 +# SFP status from PMAOS register +# 0x1 plug in +# 0x2 plug out +# 0x3 plug in with error +# 0x4 disabled, at this status SFP eeprom is not accessible, +# and presence status also will be not present, +# so treate it as plug out. +SDK_SFP_STATE_IN = 0x1 SDK_SFP_STATE_OUT = 0x2 +SDK_SFP_STATE_ERR = 0x3 +SDK_SFP_STATE_DIS = 0x4 + +# SFP status that will be handled by XCVRD STATUS_PLUGIN = '1' STATUS_PLUGOUT = '0' -STATUS_UNKNOWN = '2' +STATUS_ERR_I2C_STUCK = '2' +STATUS_ERR_BAD_EEPROM = '3' +STATUS_ERR_UNSUPPORTED_CABLE = '4' +STATUS_ERR_HIGH_TEMP = '5' +STATUS_ERR_BAD_CABLE = '6' + +# SFP status used in this file only, will not expose to XCVRD +# STATUS_ERROR will be mapped to different status according to the error code +STATUS_UNKNOWN = '-1' +STATUS_ERROR = '-2' + +# SFP error code, only valid when SFP at SDK_SFP_STATE_ERR status +# Only 0x2, 0x3, 0x5, 0x6 and 0x7 will block the eeprom access, +# so will only report above errors to XCVRD and other errors will be +# printed to syslog. + +''' +0x0: "Power_Budget_Exceeded", +0x1: "Long_Range_for_non_MLNX_cable_or_module", +0x2: "Bus_stuck", +0x3: "bad_or_unsupported_EEPROM", +0x4: "Enforce_part_number_list", +0x5: "unsupported_cable", +0x6: "High_Temperature", +0x7: "bad_cable", +0x8: "PMD_type_is_not_enabled", +0x9: "[internal]Laster_TEC_failure", +0xa: "[internal]High_current", +0xb: "[internal]High_voltage", +0xd: "[internal]High_power", +0xe: "[internal]Module_state_machine_fault", +0xc: "pcie_system_power_slot_Exceeded" +''' + +# SFP errors that will block eeprom accessing +sdk_sfp_err_type_dict = { + 0x2: STATUS_ERR_I2C_STUCK, + 0x3: STATUS_ERR_BAD_EEPROM, + 0x5: STATUS_ERR_UNSUPPORTED_CABLE, + 0x6: STATUS_ERR_HIGH_TEMP, + 0x7: STATUS_ERR_BAD_CABLE +} sfp_value_status_dict = { - SDK_SFP_STATE_IN: STATUS_PLUGIN, - SDK_SFP_STATE_OUT: STATUS_PLUGOUT, + SDK_SFP_STATE_IN: STATUS_PLUGIN, + SDK_SFP_STATE_OUT: STATUS_PLUGOUT, + SDK_SFP_STATE_ERR: STATUS_ERROR, + SDK_SFP_STATE_DIS: STATUS_PLUGOUT, } # system level event/error @@ -174,7 +228,7 @@ def check_sfp_status(self, port_change, timeout): for fd in read: if fd == self.rx_fd_p.fd: - success, port_list, module_state = self.on_pmpe(self.rx_fd_p) + success, port_list, module_state, error_type = self.on_pmpe(self.rx_fd_p) if not success: logger.log_error("failed to read from {}".format(fd)) break @@ -192,15 +246,23 @@ def check_sfp_status(self, port_change, timeout): found += 1 continue + # If get SFP status error(0x3) from SDK, then need to read the error_type to get the detailed error + if sfp_state == STATUS_ERROR: + if error_type in sdk_sfp_err_type_dict.keys(): + # In SFP at error status case, need to overwrite the sfp_state with the exact error code + sfp_state = sdk_sfp_err_type_dict[error_type] + else: + # For errors don't block the eeprom accessing, we don't report it to XCVRD + logger.log_info("SFP error on port but not blocking eeprom read, error_type {}".format(error_type)) + found +=1 + continue + for port in port_list: logger.log_info("SFP on port {} state {}".format(port, sfp_state)) port_change[port] = sfp_state found += 1 - if found == 0: - return False - else: - return True + return found != 0 def on_pmpe(self, fd_p): ''' on port module plug event handler ''' @@ -228,7 +290,17 @@ def on_pmpe(self, fd_p): port_list_size = pmpe_t.list_size logical_port_list = pmpe_t.log_port_list module_state = pmpe_t.module_state - + error_type = pmpe_t.error_type + module_id = pmpe_t.module_id + + if module_state == SDK_SFP_STATE_ERR: + logger.log_error("Receive PMPE error event on module {}: status {} error type {}".format(module_id, module_state, error_type)) + elif module_state == SDK_SFP_STATE_DIS: + logger.log_info("Receive PMPE disable event on module {}: status {}".format(module_id, module_state)) + elif module_state == SDK_SFP_STATE_IN or module_state == SDK_SFP_STATE_OUT: + logger.log_info("Receive PMPE plug in/out event on module {}: status {}".format(module_id, module_state)) + else: + logger.log_error("Receive PMPE unknown event on module {}: status {}".format(module_id, module_state)) for i in xrange(port_list_size): logical_port = sx_port_log_id_t_arr_getitem(logical_port_list, i) rc = sx_api_port_device_get(self.handle, 1 , 0, port_attributes_list, port_cnt_p) @@ -247,4 +319,4 @@ def on_pmpe(self, fd_p): delete_sx_port_attributes_t_arr(port_attributes_list) delete_uint32_t_p(port_cnt_p) - return status, label_port_list, module_state, + return status, label_port_list, module_state, error_type From 2f66b4c545b96c6c37485214f2790dba5157b81b Mon Sep 17 00:00:00 2001 From: SuvarnaMeenakshi <50386592+SuvarnaMeenakshi@users.noreply.github.com> Date: Tue, 7 Apr 2020 00:05:47 -0700 Subject: [PATCH 165/178] [sonic-netns-exec]: use "$@" to reflects all positional parameters as they were set initially (#4375) sonic-netns-exec fails to execute below command in swss.sh: sonic-netns-exec "$NET_NS" sonic-db-cli $1 EVAL " local tables = {$2} for i = 1, table.getn(tables) do local matches = redis.call('KEYS', tables[i]) for j,name in ipairs(matches) do redis.call('DEL', name) end end" 0 This command fails with error " redis.exceptions.ResponseError: value is not an integer or out of range" . Root cause: When sonic-netns-exec executes the above function, argument passed to sonic-db-cli is NOT executed as a single script. The argument is passed as separate keywords to sonic-db-cli, as below: ['EVAL', 'local', 'tables', '=', "{'PORT_TABLE*'}", 'for', 'i', '=', '1,', 'table.getn(tables)', 'do', 'local', 'matches', '=', "redis.call('KEYS',", 'tables[i])', 'for', 'j,name', 'in', 'ipairs(matches)', 'do', "redis.call('DEL',", 'name)', 'end', 'end', '0'] - How I did it To make sure that the parameters are passed as they were set initially, fix sonic-netns-exec to use double quoted "$@", where "$@" is "$1" "$2" "$3" ... "${N}" After fix, the argument passed to sonic-db-cli is as below: Argument passed to sonic-db-cli: ['EVAL', "\n local tables = {'PORT_TABLE*'}\n for i = 1, table.getn(tables) do\n local matches = redis.call('KEYS', tables[i])\n for j,name in ipairs(matches) do\n redis.call('DEL', name)\n end\n end", '0'] Signed-off-by: SuvarnaMeenakshi --- files/scripts/sonic-netns-exec | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/files/scripts/sonic-netns-exec b/files/scripts/sonic-netns-exec index 166a2c7e4a2f..a0dfc6f9ab07 100755 --- a/files/scripts/sonic-netns-exec +++ b/files/scripts/sonic-netns-exec @@ -5,8 +5,8 @@ # sonic-netns-exec NS="$1" shift -if [ "$NS" != "" ]; then - ip netns exec $NS $@ +if [ ! -z "$NS" ]; then + ip netns exec $NS "$@" else - $@ + "$@" fi From 23aed5ae6a3377cebb394a65f01359c110da401c Mon Sep 17 00:00:00 2001 From: Sumukha Tumkur Vani Date: Wed, 15 Apr 2020 02:08:45 -0700 Subject: [PATCH 166/178] [docker-restapi]: Fix authentication in restapi (#4383) - enabling http/https endpoint and mounting the certificates directory - updating the sonic-restapi submodule --- dockers/docker-sonic-restapi/Dockerfile.j2 | 3 ++ .../base_image_files/monit_restapi | 7 ++++ .../docker-sonic-restapi/critical_processes | 1 + dockers/docker-sonic-restapi/restapi.sh | 38 +++++++++++++++++++ dockers/docker-sonic-restapi/start.sh | 1 - dockers/docker-sonic-restapi/supervisord.conf | 30 +++++++++++++-- rules/docker-restapi.mk | 6 +++ src/sonic-restapi | 2 +- 8 files changed, 82 insertions(+), 6 deletions(-) create mode 100644 dockers/docker-sonic-restapi/base_image_files/monit_restapi create mode 100644 dockers/docker-sonic-restapi/critical_processes create mode 100755 dockers/docker-sonic-restapi/restapi.sh diff --git a/dockers/docker-sonic-restapi/Dockerfile.j2 b/dockers/docker-sonic-restapi/Dockerfile.j2 index de8080880fc7..32904531f1fc 100644 --- a/dockers/docker-sonic-restapi/Dockerfile.j2 +++ b/dockers/docker-sonic-restapi/Dockerfile.j2 @@ -20,6 +20,9 @@ RUN apt-get update ## Clean up RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y +COPY ["start.sh", "restapi.sh", "/usr/bin/"] COPY ["supervisord.conf", "/etc/supervisor/conf.d/"] +COPY ["files/supervisor-proc-exit-listener", "/usr/bin"] +COPY ["critical_processes", "/etc/supervisor"] ENTRYPOINT ["/usr/bin/supervisord"] diff --git a/dockers/docker-sonic-restapi/base_image_files/monit_restapi b/dockers/docker-sonic-restapi/base_image_files/monit_restapi new file mode 100644 index 000000000000..2e90baf30d57 --- /dev/null +++ b/dockers/docker-sonic-restapi/base_image_files/monit_restapi @@ -0,0 +1,7 @@ +############################################################################### +## Monit configuration for restapi container +## process list: +## restapi +############################################################################### +check process restapi matching "/usr/sbin/go-server-server" + if does not exist for 5 times within 5 cycles then alert diff --git a/dockers/docker-sonic-restapi/critical_processes b/dockers/docker-sonic-restapi/critical_processes new file mode 100644 index 000000000000..3106eaa9410a --- /dev/null +++ b/dockers/docker-sonic-restapi/critical_processes @@ -0,0 +1 @@ +restapi diff --git a/dockers/docker-sonic-restapi/restapi.sh b/dockers/docker-sonic-restapi/restapi.sh new file mode 100755 index 000000000000..61778e3245d6 --- /dev/null +++ b/dockers/docker-sonic-restapi/restapi.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash + +RESTAPI_ARGS="" +while true +do + client_auth=`sonic-cfggen -d -v "RESTAPI['config']['client_auth']"` + if [[ $client_auth == 'true' ]]; then + certs=`sonic-cfggen -d -v "RESTAPI['certs']"` + allow_insecure=`sonic-cfggen -d -v "RESTAPI['config']['allow_insecure']"` + if [[ $allow_insecure == 'true' ]]; then + RESTAPI_ARGS=" -enablehttp=true" + else + RESTAPI_ARGS=" -enablehttp=false" + fi + if [[ -n "$certs" ]]; then + SERVER_CRT=`sonic-cfggen -d -v "RESTAPI['certs']['server_crt']"` + SERVER_KEY=`sonic-cfggen -d -v "RESTAPI['certs']['server_key']"` + CLIENT_CA_CRT=`sonic-cfggen -d -v "RESTAPI['certs']['client_ca_crt']"` + CLIENT_CRT_CNAME=`sonic-cfggen -d -v "RESTAPI['certs']['client_crt_cname']"` + if [[ -f $SERVER_CRT && -f $SERVER_KEY && -f $CLIENT_CA_CRT ]]; then + RESTAPI_ARGS+=" -enablehttps=true -servercert=$SERVER_CRT -serverkey=$SERVER_KEY -clientcert=$CLIENT_CA_CRT -clientcertcommonname=$CLIENT_CRT_CNAME" + break + fi + fi + fi + logger "Waiting for certificates..." + sleep 60 +done + +LOG_LEVEL=`sonic-cfggen -d -v "RESTAPI['config']['log_level']"` +if [ ! -z $LOG_LEVEL ]; then + RESTAPI_ARGS+=" -loglevel=$LOG_LEVEL" +else + RESTAPI_ARGS+=" -loglevel=trace" +fi + +logger "RESTAPI_ARGS: $RESTAPI_ARGS" +exec /usr/sbin/go-server-server ${RESTAPI_ARGS} diff --git a/dockers/docker-sonic-restapi/start.sh b/dockers/docker-sonic-restapi/start.sh index 015d246d1200..bff56a8864c1 100755 --- a/dockers/docker-sonic-restapi/start.sh +++ b/dockers/docker-sonic-restapi/start.sh @@ -6,5 +6,4 @@ echo "# Config files managed by sonic-config-engine" > /var/sonic/config_status rm -f /var/run/rsyslogd.pid supervisorctl start rsyslogd - supervisorctl start restapi diff --git a/dockers/docker-sonic-restapi/supervisord.conf b/dockers/docker-sonic-restapi/supervisord.conf index 284c8aef423b..58afc6dcd7de 100644 --- a/dockers/docker-sonic-restapi/supervisord.conf +++ b/dockers/docker-sonic-restapi/supervisord.conf @@ -3,10 +3,32 @@ logfile_maxbytes=1MB logfile_backups=2 nodaemon=true -[program:restapi] -command=/usr/sbin/go-server-server -loglevel trace +[eventlistener:supervisor-proc-exit-listener] +command=/usr/bin/supervisor-proc-exit-listener --container-name restapi +events=PROCESS_STATE_EXITED +autostart=true +autorestart=false + +[program:start.sh] +command=/usr/bin/start.sh priority=1 autostart=true autorestart=false -stdout_logfile=/tmp/rest-api.out.log -stderr_logfile=/tmp/rest-api.err.log +stdout_logfile=syslog +stderr_logfile=syslog + +[program:restapi] +command=/usr/bin/restapi.sh +priority=1 +autostart=false +autorestart=true +stdout_logfile=syslog +stderr_logfile=syslog + +[program:rsyslogd] +command=/usr/sbin/rsyslogd -n +priority=2 +autostart=false +autorestart=true +stdout_logfile=syslog +stderr_logfile=syslog diff --git a/rules/docker-restapi.mk b/rules/docker-restapi.mk index 2141dea64d17..09bbd03d8fd8 100644 --- a/rules/docker-restapi.mk +++ b/rules/docker-restapi.mk @@ -18,5 +18,11 @@ endif $(DOCKER_RESTAPI)_CONTAINER_NAME = restapi $(DOCKER_RESTAPI)_RUN_OPT += --cap-add NET_ADMIN --privileged -t +$(DOCKER_RESTAPI)_RUN_OPT += --network="host" $(DOCKER_RESTAPI)_RUN_OPT += -v /var/run/redis/redis.sock:/var/run/redis/redis.sock +$(DOCKER_RESTAPI)_RUN_OPT += -v /etc/sonic/certificates:/etc/sonic/certificates:ro +$(DOCKER_RESTAPI)_RUN_OPT += -p=8081:8081/tcp $(DOCKER_RESTAPI)_RUN_OPT += -p=8090:8090/tcp + +$(DOCKER_RESTAPI)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT) +$(DOCKER_RESTAPI)_BASE_IMAGE_FILES += monit_restapi:/etc/monit/conf.d diff --git a/src/sonic-restapi b/src/sonic-restapi index 163ee272ae99..c219e3da28fb 160000 --- a/src/sonic-restapi +++ b/src/sonic-restapi @@ -1 +1 @@ -Subproject commit 163ee272ae992f5885990dcca6552cd86b74391a +Subproject commit c219e3da28fb20b63b065ceb1828125593d73f14 From e8bfde39f8300b9c7ae19656e724bfc690ac9bf1 Mon Sep 17 00:00:00 2001 From: rlhui Date: Thu, 16 Apr 2020 18:19:02 -0700 Subject: [PATCH 167/178] Update SAI to v1.5.2 --- src/sonic-sairedis | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-sairedis b/src/sonic-sairedis index 792800607c0a..0305b7fb531b 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit 792800607c0a987097d430d9f7fa9dce34361cfd +Subproject commit 0305b7fb531b60fafc42c16aecfed9a6701be870 From 9b017a83b5125b759faebf292f3615b7c3ed98f3 Mon Sep 17 00:00:00 2001 From: Renuka Manavalan <47282725+renukamanavalan@users.noreply.github.com> Date: Thu, 16 Apr 2020 21:54:45 -0700 Subject: [PATCH 168/178] [baseimage]: Install Kubernetes packages if enabled in image (#4374) (#4432) Install kubeadm, which transparently installs kubelet & kubectl As well download required Kubernetes images required to run as kubernetes node. The kubelet service is intentionally kept in disabled state, as it would otherwise continuously restart wasting resources, until join to master. --- Makefile.work | 5 +++++ build_debian.sh | 16 ++++++++++++++++ .../build_templates/sonic_debian_extension.j2 | 19 +++++++++++++++++++ files/image_config/kubernetes/kubernetes.list | 4 ++++ rules/config | 15 +++++++++++++++ slave.mk | 2 ++ 6 files changed, 61 insertions(+) create mode 100644 files/image_config/kubernetes/kubernetes.list diff --git a/Makefile.work b/Makefile.work index a1ccf8715567..e4e31a134555 100644 --- a/Makefile.work +++ b/Makefile.work @@ -9,6 +9,7 @@ # through http. # * ENABLE_ZTP: Enables zero touch provisioning. # * SHUTDOWN_BGP_ON_START: Sets admin-down state for all bgp peerings after restart. +# * INSTALL_KUBERNETES: Allows including Kubernetes # * ENABLE_PFCWD_ON_START: Enable PFC Watchdog (PFCWD) on server-facing ports # * by default for TOR switch. # * ENABLE_SYNCD_RPC: Enables rpc-based syncd builds. @@ -165,6 +166,10 @@ SONIC_BUILD_INSTRUCTION := make \ ENABLE_DHCP_GRAPH_SERVICE=$(ENABLE_DHCP_GRAPH_SERVICE) \ ENABLE_ZTP=$(ENABLE_ZTP) \ SHUTDOWN_BGP_ON_START=$(SHUTDOWN_BGP_ON_START) \ + INSTALL_KUBERNETES=$(INSTALL_KUBERNETES) \ + KUBERNETES_VERSION=$(KUBERNETES_VERSION) \ + K8s_GCR_IO_PAUSE_VERSION=$(K8s_GCR_IO_PAUSE_VERSION) \ + K8s_CNI_CALICO_VERSION=$(K8s_CNI_CALICO_VERSION) \ SONIC_ENABLE_PFCWD_ON_START=$(ENABLE_PFCWD_ON_START) \ SONIC_ENABLE_SYNCD_RPC=$(ENABLE_SYNCD_RPC) \ SONIC_INSTALL_DEBUG_TOOLS=$(INSTALL_DEBUG_TOOLS) \ diff --git a/build_debian.sh b/build_debian.sh index 51154cc073bc..fac25f18de6b 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -203,6 +203,22 @@ sudo LANG=C chroot $FILESYSTEM_ROOT apt-get update sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install docker-ce=${DOCKER_VERSION} sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y remove software-properties-common gnupg2 +if [ "$INSTALL_KUBERNETES" == "y" ] +then + ## Install Kubernetes + echo '[INFO] Install kubernetes' + sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT curl -fsSL \ + https://packages.cloud.google.com/apt/doc/apt-key.gpg | \ + sudo LANG=C chroot $FILESYSTEM_ROOT apt-key add - + ## Check out the sources list update matches current Debian version + sudo cp files/image_config/kubernetes/kubernetes.list $FILESYSTEM_ROOT/etc/apt/sources.list.d/ + sudo LANG=C chroot $FILESYSTEM_ROOT apt-get update + sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install kubeadm=${KUBERNETES_VERSION}-00 + # kubeadm package auto install kubelet & kubectl +else + echo '[INFO] Skipping Install kubernetes' +fi + ## Add docker config drop-in to specify dockerd command line sudo mkdir -p $FILESYSTEM_ROOT/etc/systemd/system/docker.service.d/ ## Note: $_ means last argument of last command diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 4b5234bc96a1..7a98d30b291b 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -245,6 +245,13 @@ sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install azure-s sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install watchdog sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install futures +{% if install_kubernetes == "y" %} +# Copy kubelet service files +# Keep it disabled until join, else it continuously restart and as well spew too many +# non-required log lines wasting syslog resources. +sudo LANG=C chroot $FILESYSTEM_ROOT systemctl disable kubelet.service +{% endif %} + # Copy the buffer configuration template sudo cp $BUILD_TEMPLATES/buffers_config.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ @@ -399,6 +406,18 @@ sudo LANG=C chroot $FILESYSTEM_ROOT docker $SONIC_NATIVE_DOCKERD_FOR_DOCKERFS ta sudo LANG=C chroot $FILESYSTEM_ROOT docker $SONIC_NATIVE_DOCKERD_FOR_DOCKERFS tag {{imagename}}:latest {{imagebasename}}:latest {% endif %} {% endfor %} + +{% if install_kubernetes == "y" %} +## Pull in kubernetes docker images +echo "pulling universal k8s images ..." +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT docker pull k8s.gcr.io/pause:${K8s_GCR_IO_PAUSE_VERSION} +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT docker pull k8s.gcr.io/kube-proxy:v${KUBERNETES_VERSION} +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT docker pull calico/node:v${K8s_CNI_CALICO_VERSION} +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT docker pull calico/pod2daemon-flexvol:v${K8s_CNI_CALICO_VERSION} +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT docker pull calico/cni:v${K8s_CNI_CALICO_VERSION} +echo "docker images pull complete" +{% endif %} + if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then sudo umount $FILESYSTEM_ROOT/dockerfs sudo rm -fr $FILESYSTEM_ROOT/dockerfs diff --git a/files/image_config/kubernetes/kubernetes.list b/files/image_config/kubernetes/kubernetes.list new file mode 100644 index 000000000000..5c888b830623 --- /dev/null +++ b/files/image_config/kubernetes/kubernetes.list @@ -0,0 +1,4 @@ +# The following is as recommended by https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/ +# Whenever an OS update from Debian stretch is done, make sure to find the matching k8s sources list +# +deb https://apt.kubernetes.io/ kubernetes-xenial main diff --git a/rules/config b/rules/config index c168fa5a964e..b3aa7bce3a89 100644 --- a/rules/config +++ b/rules/config @@ -110,3 +110,18 @@ ENABLE_RESTAPI = n # ENABLE_NAT - build docker-sonic-nat for nat support ENABLE_NAT = y + +# INSTALL_KUBERNETES - if set to y kubernetes packages are installed to be able to +# run as worker node in kubernetes cluster. +INSTALL_KUBERNETES = n + +# KUBERNETES_VERSION - Set to the required version. +# K8s_GCR_IO_PAUSE_VERSION - Version of k8s universal pause container image +# K8s_CNI_CALICO_VERSION - Calico used as CNI; Appropriate version for this Kubernetes version +# These are Used *only* when INSTALL_KUBERNETES=y +# NOTE: As a worker node it has to run version compatible to kubernetes master. +# +KUBERNETES_VERSION = 1.18.0 +K8s_GCR_IO_PAUSE_VERSION = 3.2 +K8s_CNI_CALICO_VERSION = 3.12.0 + diff --git a/slave.mk b/slave.mk index 21c1176feef1..0c4f2c70b392 100644 --- a/slave.mk +++ b/slave.mk @@ -187,6 +187,7 @@ $(info "USERNAME" : "$(USERNAME)") $(info "PASSWORD" : "$(PASSWORD)") $(info "ENABLE_DHCP_GRAPH_SERVICE" : "$(ENABLE_DHCP_GRAPH_SERVICE)") $(info "SHUTDOWN_BGP_ON_START" : "$(SHUTDOWN_BGP_ON_START)") +$(info "INSTALL_KUBERNETES" : "$(INSTALL_KUBERNETES)") $(info "ENABLE_PFCWD_ON_START" : "$(ENABLE_PFCWD_ON_START)") $(info "INSTALL_DEBUG_TOOLS" : "$(INSTALL_DEBUG_TOOLS)") $(info "ROUTING_STACK" : "$(SONIC_ROUTING_STACK)") @@ -658,6 +659,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export enable_ztp="$(ENABLE_ZTP)" export enable_nat="$(ENABLE_NAT)" export shutdown_bgp_on_start="$(SHUTDOWN_BGP_ON_START)" + export install_kubernetes="$(INSTALL_KUBERNETES)" export enable_pfcwd_on_start="$(ENABLE_PFCWD_ON_START)" export installer_debs="$(addprefix $(STRETCH_DEBS_PATH)/,$($*_INSTALLS))" export lazy_installer_debs="$(foreach deb, $($*_LAZY_INSTALLS),$(foreach device, $($(deb)_PLATFORM),$(addprefix $(device)@, $(STRETCH_DEBS_PATH)/$(deb))))" From c7c78f03bc4edf5f1ffc35b7d3390ca7a460edff Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Thu, 13 Feb 2020 18:45:37 -0800 Subject: [PATCH 169/178] Update frr to latest 7.2.1 (#4145) --- rules/frr.mk | 2 +- src/sonic-frr/frr | 2 +- ...nexthops-compare-vrf-only-if-ip-type.patch | 73 ------------------- src/sonic-frr/patch/series | 1 - 4 files changed, 2 insertions(+), 76 deletions(-) delete mode 100644 src/sonic-frr/patch/0005-nexthops-compare-vrf-only-if-ip-type.patch diff --git a/rules/frr.mk b/rules/frr.mk index e5c9c230a766..6dc25b30dfff 100644 --- a/rules/frr.mk +++ b/rules/frr.mk @@ -3,7 +3,7 @@ FRR_VERSION = 7.2.1 FRR_SUBVERSION = 0 FRR_BRANCH = frr/7.2 -FRR_TAG = frr-7.2.1-s1 +FRR_TAG = frr-7.2.1-s2 export FRR_VERSION FRR_SUBVERSION FRR_BRANCH diff --git a/src/sonic-frr/frr b/src/sonic-frr/frr index 90446e3c3310..e1b0c939960c 160000 --- a/src/sonic-frr/frr +++ b/src/sonic-frr/frr @@ -1 +1 @@ -Subproject commit 90446e3c3310001a7b84017fa4b237ea7914f45e +Subproject commit e1b0c939960c49eba05e972a68d50ca32dd09303 diff --git a/src/sonic-frr/patch/0005-nexthops-compare-vrf-only-if-ip-type.patch b/src/sonic-frr/patch/0005-nexthops-compare-vrf-only-if-ip-type.patch deleted file mode 100644 index 343f1b3262d9..000000000000 --- a/src/sonic-frr/patch/0005-nexthops-compare-vrf-only-if-ip-type.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 2f0b5aef66316b47d2cc8ac18453600621a6a317 Mon Sep 17 00:00:00 2001 -From: Tyler Li -Date: Thu, 14 Nov 2019 23:46:52 -0800 -Subject: [PATCH] nexthops compare vrf only if ip type - ---- - lib/nexthop.c | 12 ++++++------ - lib/zclient.c | 12 ++++++------ - 2 files changed, 12 insertions(+), 12 deletions(-) - -diff --git a/lib/nexthop.c b/lib/nexthop.c -index cf5bed3d6..7d9f646c9 100644 ---- a/lib/nexthop.c -+++ b/lib/nexthop.c -@@ -105,12 +105,6 @@ static int _nexthop_cmp_no_labels(const struct nexthop *next1, - { - int ret = 0; - -- if (next1->vrf_id < next2->vrf_id) -- return -1; -- -- if (next1->vrf_id > next2->vrf_id) -- return 1; -- - if (next1->type < next2->type) - return -1; - -@@ -120,6 +114,12 @@ static int _nexthop_cmp_no_labels(const struct nexthop *next1, - switch (next1->type) { - case NEXTHOP_TYPE_IPV4: - case NEXTHOP_TYPE_IPV6: -+ if (next1->vrf_id < next2->vrf_id) -+ return -1; -+ -+ if (next1->vrf_id > next2->vrf_id) -+ return 1; -+ - ret = _nexthop_gateway_cmp(next1, next2); - if (ret != 0) - return ret; -diff --git a/lib/zclient.c b/lib/zclient.c -index c739af043..0d37c46d1 100644 ---- a/lib/zclient.c -+++ b/lib/zclient.c -@@ -783,12 +783,6 @@ static int zapi_nexthop_cmp_no_labels(const struct zapi_nexthop *next1, - { - int ret = 0; - -- if (next1->vrf_id < next2->vrf_id) -- return -1; -- -- if (next1->vrf_id > next2->vrf_id) -- return 1; -- - if (next1->type < next2->type) - return -1; - -@@ -798,6 +792,12 @@ static int zapi_nexthop_cmp_no_labels(const struct zapi_nexthop *next1, - switch (next1->type) { - case NEXTHOP_TYPE_IPV4: - case NEXTHOP_TYPE_IPV6: -+ if (next1->vrf_id < next2->vrf_id) -+ return -1; -+ -+ if (next1->vrf_id > next2->vrf_id) -+ return 1; -+ - ret = nexthop_g_addr_cmp(next1->type, &next1->gate, - &next2->gate); - if (ret != 0) --- -2.11.0 - diff --git a/src/sonic-frr/patch/series b/src/sonic-frr/patch/series index 13619c87ff65..233021ace50b 100644 --- a/src/sonic-frr/patch/series +++ b/src/sonic-frr/patch/series @@ -2,5 +2,4 @@ 0002-Reduce-severity-of-Vty-connected-from-message.patch 0003-Use-vrf_id-for-vrf-not-tabled_id.patch 0004-Allow-BGP-attr-NEXT_HOP-to-be-0.0.0.0-due-to-allevia.patch -0005-nexthops-compare-vrf-only-if-ip-type.patch 0006-changes-for-making-snmp-socket-non-blocking.patch From 5839a01abd9c7dc35223c55e345589941ce57649 Mon Sep 17 00:00:00 2001 From: abdosi <58047199+abdosi@users.noreply.github.com> Date: Fri, 17 Apr 2020 10:46:56 -0700 Subject: [PATCH 170/178] [sonic-buildimage] libsaibcm Debian package update (#4439) from 3.7.3.3-3 to 3.7.3.3-4 Fixes for PFC WD Signed-off-by: Abhishek Dosi --- platform/broadcom/sai.mk | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index 54f44271ad56..e6e40039caf0 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,9 +1,8 @@ -BRCM_SAI = libsaibcm_3.7.3.3-2_amd64.deb -$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm_3.7.3.3-2_amd64.deb?sv=2015-04-05&sr=b&sig=701AT0Rwcn%2FKT33UPE1TTQRoJ9tQG0iDfOSXXVCtnyY%3D&se=2033-10-29T22%3A32%3A29Z&sp=r" - -BRCM_SAI_DEV = libsaibcm-dev_3.7.3.3-2_amd64.deb +BRCM_SAI = libsaibcm_3.7.3.3-4_amd64.deb +$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm_3.7.3.3-4_amd64.deb?sv=2015-04-05&sr=b&sig=9z7vLhweD%2B%2FZylkr9XsDAJ3DdE5NJlcPTslFYyBuAXU%3D&se=2033-12-25T14%3A52%3A25Z&sp=r" +BRCM_SAI_DEV = libsaibcm-dev_3.7.3.3-4_amd64.deb $(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV))) -$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm-dev_3.7.3.3-2_amd64.deb?sv=2015-04-05&sr=b&sig=vXdUpaP0o71SatqEoqqDH2kai%2FLuFUWZWZAy7HKfeiQ%3D&se=2033-10-29T22%3A31%3A07Z&sp=r" +$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm-dev_3.7.3.3-4_amd64.deb?sv=2015-04-05&sr=b&sig=SAOoGh2zdljiPuKeDoa%2B1lSJzZ8uXh2Irl2RZX1uAiA%3D&se=2033-12-25T14%3A53%3A44Z&sp=r" SONIC_ONLINE_DEBS += $(BRCM_SAI) $(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI) From 4c900dcd4c11650833fc6cd7ae6a39ff181e3656 Mon Sep 17 00:00:00 2001 From: lguohan Date: Sat, 18 Apr 2020 21:14:05 -0700 Subject: [PATCH 171/178] [grub]: use UUID for root partition (#4443) Signed-off-by: Guohan Lu --- installer/x86_64/install.sh | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/installer/x86_64/install.sh b/installer/x86_64/install.sh index d0aa7818df9b..6a347c78db73 100755 --- a/installer/x86_64/install.sh +++ b/installer/x86_64/install.sh @@ -583,19 +583,22 @@ EOF $onie_root_dir/tools/bin/onie-boot-mode -q -o install fi -# Add a menu entry for the DEMO OS +# Add a menu entry for the SONiC OS # Note: assume that apparmor is supported in the kernel demo_grub_entry="$demo_volume_revision_label" if [ "$install_env" = "sonic" ]; then old_sonic_menuentry=$(cat /host/grub/grub.cfg | sed "/$running_sonic_revision/,/}/!d") - demo_dev=$(echo $old_sonic_menuentry | sed -e "s/.*root\=\(.*\)rw.*/\1/") + grub_cfg_root=$(echo $old_sonic_menuentry | sed -e "s/.*root\=\(.*\)rw.*/\1/") onie_menuentry=$(cat /host/grub/grub.cfg | sed "/menuentry ONIE/,/}/!d") -fi - -if [ "$install_env" = "build" ]; then +elif [ "$install_env" = "build" ]; then grub_cfg_root=%%SONIC_ROOT%% -else - grub_cfg_root=$demo_dev +else # install_env = "onie" + uuid=$(blkid "$demo_dev" | sed -ne 's/.* UUID=\"\([^"]*\)\".*/\1/p') + if [ -z "$uuid" ]; then + grub_cfg_root=$demo_dev + else + grub_cfg_root=UUID=$uuid + fi fi cat <> $grub_cfg From be5a015941935c26d43ba5dc0ef3cedbd181181d Mon Sep 17 00:00:00 2001 From: Renuka Manavalan <47282725+renukamanavalan@users.noreply.github.com> Date: Sun, 19 Apr 2020 11:34:30 -0700 Subject: [PATCH 172/178] Kubeadm v1.18.0 requires Calico images of version v3.12.1 (#4445) --- rules/config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules/config b/rules/config index b3aa7bce3a89..0c2f07cd2648 100644 --- a/rules/config +++ b/rules/config @@ -123,5 +123,5 @@ INSTALL_KUBERNETES = n # KUBERNETES_VERSION = 1.18.0 K8s_GCR_IO_PAUSE_VERSION = 3.2 -K8s_CNI_CALICO_VERSION = 3.12.0 +K8s_CNI_CALICO_VERSION = 3.12.1 From 4324f307efe63bce1b88b2dd77ab451edaeab16f Mon Sep 17 00:00:00 2001 From: Abhishek Dosi Date: Sun, 19 Apr 2020 16:38:10 -0700 Subject: [PATCH 173/178] [Submodule update] swss with following PR's: Do not set PG to Buffer porfile mapping again if already exist. (#1261) [sub intf] Use m_lag_id to be the parent port object id when parent port is LAG (#1235) --- src/sonic-swss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss b/src/sonic-swss index 3f8c2fe8267d..e9cf94aaf159 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 3f8c2fe8267d2051e098c2a71f977b70d84e84b6 +Subproject commit e9cf94aaf159c6ee30d6da7fa53fbbaa640694a8 From 8f8ea0489109525bf025091c7ae8b4c5b153ad5e Mon Sep 17 00:00:00 2001 From: Abhishek Dosi Date: Sun, 19 Apr 2020 16:42:26 -0700 Subject: [PATCH 174/178] [Submodule update] sonic-utilities with PR's: [201911] Explicitly specify command names with underscores (continued) (#868) [fwutil]: Update Command-Reference.md. (#876) --- src/sonic-utilities | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-utilities b/src/sonic-utilities index 8f08a1550afb..250a49bf47e2 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit 8f08a1550afbfab1706bd3ec347795b36e367ed2 +Subproject commit 250a49bf47e24b2b5aa5f84478cbe8550f817589 From 9c4336065228431c445382e7f713674bd4980922 Mon Sep 17 00:00:00 2001 From: Abhishek Dosi Date: Sun, 19 Apr 2020 16:48:00 -0700 Subject: [PATCH 175/178] [submodule update] sonic-platform-daemons [xcvrd] Extend xcvrd with SFP error event handling (#52) [thermal fix] 1. Catch exception for each update iteration; 2. add unit test (#51) Add thermal control daemon to monitor FAN and thermal status and run thermal policy (#49 --- 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 2e8bd64535f3..364ae4254ba4 160000 --- a/src/sonic-platform-daemons +++ b/src/sonic-platform-daemons @@ -1 +1 @@ -Subproject commit 2e8bd64535f3991d67ad225701cb5ad92b6d6133 +Subproject commit 364ae4254ba4d770fffa1286e2219841571c78b5 From ca926f2e750c6fe7d69a529e4885b9db2c044bdb Mon Sep 17 00:00:00 2001 From: Abhishek Dosi Date: Sun, 19 Apr 2020 16:52:19 -0700 Subject: [PATCH 176/178] [Submodule update] sonic-platform-common with PR's [Chassis base] Add sfp error event definition #80 SFP(sff8472 attributes) transciever eeprom attribute support #74 --- 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 6ddd012d9ab3..3fe07066892a 160000 --- a/src/sonic-platform-common +++ b/src/sonic-platform-common @@ -1 +1 @@ -Subproject commit 6ddd012d9ab362254bd6a54372ee0ab679a7130e +Subproject commit 3fe07066892aba5ae3e8f5f0ffd5163ffc578b31 From 898f8789a7d594853cd07a86d0029342d860f4cb Mon Sep 17 00:00:00 2001 From: Abhishek Dosi Date: Sun, 19 Apr 2020 16:57:49 -0700 Subject: [PATCH 177/178] [submodule update] sonic-swss-common with PR's [DBConnector] Add methods to set/get Redis client name (#335) --- src/sonic-swss-common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-swss-common b/src/sonic-swss-common index 7e4e2161d41a..e81e661cea0d 160000 --- a/src/sonic-swss-common +++ b/src/sonic-swss-common @@ -1 +1 @@ -Subproject commit 7e4e2161d41a845a8a57cd3c187acf497d3ce329 +Subproject commit e81e661cea0dbf441f9576013b9e9485de0e4c45 From 773e83b243e42d270aec783b367aa8addb48b1d1 Mon Sep 17 00:00:00 2001 From: Srideep Date: Wed, 22 Apr 2020 23:52:02 -0600 Subject: [PATCH 178/178] [DellEMC] s5232f console and sfputil fix (#4453) * [DellEMC] s5232f console and sfputil fix Remove hardcoding 115K baudrate for console Enhance sfputil api as per spec --- .../installer.conf | 1 - .../plugins/sfputil.py | 345 +++++++++++++++++- 2 files changed, 341 insertions(+), 5 deletions(-) diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/installer.conf b/device/dell/x86_64-dellemc_s5232f_c3538-r0/installer.conf index 925a32fc0c3a..924e0fb81963 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/installer.conf +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/installer.conf @@ -1,3 +1,2 @@ CONSOLE_PORT=0x3f8 CONSOLE_DEV=0 -CONSOLE_SPEED=115200 diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/sfputil.py b/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/sfputil.py index b424cffc3f7c..62dc5cb9c34b 100644 --- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/sfputil.py +++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/plugins/sfputil.py @@ -8,13 +8,41 @@ import sys import getopt import time + import io from sonic_sfp.sfputilbase import SfpUtilBase from os import * from mmap import * - + from sonic_sfp.sff8436 import sff8436InterfaceId + from sonic_sfp.sff8436 import sff8436Dom + from sonic_sfp.sff8472 import sff8472Dom except ImportError as e: raise ImportError("%s - required module not found" % str(e)) +QSFP_DOM_REV_OFFSET = 1 +QSFP_DOM_REV_WIDTH = 1 +QSFP_TEMPE_OFFSET = 22 +QSFP_TEMPE_WIDTH = 2 +QSFP_VOLT_OFFSET = 26 +QSFP_VOLT_WIDTH = 2 +QSFP_CHANNL_MON_OFFSET = 34 +QSFP_CHANNL_MON_WIDTH = 16 +QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH = 24 +QSFP_MODULE_THRESHOLD_OFFSET = 128 +QSFP_MODULE_THRESHOLD_WIDTH = 24 +QSFP_CHANNL_THRESHOLD_OFFSET = 176 +QSFP_CHANNL_THRESHOLD_WIDTH = 16 +QSFP_CHANNL_MON_MASK_OFFSET = 242 +QSFP_CHANNL_MON_MASK_WIDTH = 4 + +SFP_TEMPE_OFFSET = 96 +SFP_TEMPE_WIDTH = 2 +SFP_VOLT_OFFSET = 98 +SFP_VOLT_WIDTH = 2 +SFP_MODULE_THRESHOLD_OFFSET = 0 +SFP_MODULE_THRESHOLD_WIDTH = 56 + +XCVR_DOM_CAPABILITY_OFFSET = 92 +XCVR_DOM_CAPABILITY_WIDTH = 1 class SfpUtil(SfpUtilBase): """Platform-specific SfpUtil class""" @@ -213,8 +241,11 @@ def reset(self, port_num): return True - def get_transceiver_change_event(self): + def get_transceiver_change_event(self, timeout=0): port_dict = {} + sleep_time_ms = 500 # Poll interval, in milliseconds + sleep_time = sleep_time_ms / 1000.0 + elapsed_time_ms = 0 while True: for port_num in range(self.port_start, (self.port_end + 1)): presence = self.get_presence(port_num) @@ -227,6 +258,312 @@ def get_transceiver_change_event(self): port_dict[port_num] = '0' if(len(port_dict) > 0): - return True, port_dict + break + + if len(port_dict) > 0: + break + if timeout != 0: + elapsed_time_ms += sleep_time_ms + if elapsed_time_ms > timeout: + break + time.sleep(sleep_time) + + return True, port_dict + + + def get_transceiver_dom_info_dict(self, port_num): + transceiver_dom_info_dict = {} + + dom_info_dict_keys = ['temperature', 'voltage', 'rx1power', + 'rx2power', 'rx3power', 'rx4power', + 'tx1bias', 'tx2bias', 'tx3bias', + 'tx4bias', 'tx1power', 'tx2power', + 'tx3power', 'tx4power', + ] + transceiver_dom_info_dict = dict.fromkeys(dom_info_dict_keys, 'N/A') + + if port_num in self.qsfp_ports: + offset = 0 + offset_xcvr = 128 + file_path = self._get_port_eeprom_path(port_num, self.IDENTITY_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + return None + + try: + sysfsfile_eeprom = io.open(file_path, mode="rb", buffering=0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return transceiver_dom_info_dict + + sfpi_obj = sff8436InterfaceId() + if sfpi_obj is None: + return transceiver_dom_info_dict + + # QSFP capability byte parse, through this byte can know whether it support tx_power or not. + # TODO: in the future when decided to migrate to support SFF-8636 instead of SFF-8436, + # need to add more code for determining the capability and version compliance + # in SFF-8636 dom capability definitions evolving with the versions. + qsfp_dom_capability_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset_xcvr + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH) + if qsfp_dom_capability_raw is not None: + qspf_dom_capability_data = sfpi_obj.parse_qsfp_dom_capability(qsfp_dom_capability_raw, 0) + else: + return transceiver_dom_info_dict + + dom_temperature_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_TEMPE_OFFSET), QSFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + else: + return transceiver_dom_info_dict + + dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_VOLT_OFFSET), QSFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + else: + return transceiver_dom_info_dict + + qsfp_dom_rev_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_DOM_REV_OFFSET), QSFP_DOM_REV_WIDTH) + if qsfp_dom_rev_raw is not None: + qsfp_dom_rev_data = sfpd_obj.parse_sfp_dom_rev(qsfp_dom_rev_raw, 0) + else: + return transceiver_dom_info_dict + + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + + # The tx_power monitoring is only available on QSFP which compliant with SFF-8636 + # and claimed that it support tx_power with one indicator bit. + dom_channel_monitor_data = {} + qsfp_dom_rev = qsfp_dom_rev_data['data']['dom_rev']['value'] + qsfp_tx_power_support = qspf_dom_capability_data['data']['Tx_power_support']['value'] + if (qsfp_dom_rev[0:8] != 'SFF-8636' or (qsfp_dom_rev[0:8] == 'SFF-8636' and qsfp_tx_power_support != 'on')): + dom_channel_monitor_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + else: + return transceiver_dom_info_dict + + transceiver_dom_info_dict['tx1power'] = 'N/A' + transceiver_dom_info_dict['tx2power'] = 'N/A' + transceiver_dom_info_dict['tx3power'] = 'N/A' + transceiver_dom_info_dict['tx4power'] = 'N/A' + else: + dom_channel_monitor_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power(dom_channel_monitor_raw, 0) + else: + return None + + transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TX1Power']['value'] + transceiver_dom_info_dict['tx2power'] = dom_channel_monitor_data['data']['TX2Power']['value'] + transceiver_dom_info_dict['tx3power'] = dom_channel_monitor_data['data']['TX3Power']['value'] + transceiver_dom_info_dict['tx4power'] = dom_channel_monitor_data['data']['TX4Power']['value'] + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RX1Power']['value'] + transceiver_dom_info_dict['rx2power'] = dom_channel_monitor_data['data']['RX2Power']['value'] + transceiver_dom_info_dict['rx3power'] = dom_channel_monitor_data['data']['RX3Power']['value'] + transceiver_dom_info_dict['rx4power'] = dom_channel_monitor_data['data']['RX4Power']['value'] + transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TX1Bias']['value'] + transceiver_dom_info_dict['tx2bias'] = dom_channel_monitor_data['data']['TX2Bias']['value'] + transceiver_dom_info_dict['tx3bias'] = dom_channel_monitor_data['data']['TX3Bias']['value'] + transceiver_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value'] - time.sleep(0.5) + else: + offset = 256 + file_path = self._get_port_eeprom_path(port_num, self.DOM_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + return None + + try: + sysfsfile_eeprom = io.open(file_path,"rb",0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8472Dom(None,1) + if sfpd_obj is None: + return transceiver_dom_info_dict + + dom_temperature_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_TEMPE_OFFSET), + SFP_TEMPE_WIDTH) + if dom_temperature_raw is not None: + dom_temperature_data = sfpd_obj.parse_temperature(dom_temperature_raw, 0) + else: + return transceiver_dom_info_dict + + dom_voltage_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_VOLT_OFFSET), + SFP_VOLT_WIDTH) + if dom_voltage_raw is not None: + dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0) + else: + return transceiver_dom_info_dict + + dom_channel_monitor_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, (offset + SFP_MODULE_THRESHOLD_OFFSET), + SFP_MODULE_THRESHOLD_WIDTH) + if dom_channel_monitor_raw is not None: + dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(dom_channel_monitor_raw, 0) + else: + return transceiver_dom_info_dict + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value'] + transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value'] + transceiver_dom_info_dict['rx1power'] = dom_channel_monitor_data['data']['RXPower']['value'] + transceiver_dom_info_dict['rx2power'] = 'N/A' + transceiver_dom_info_dict['rx3power'] = 'N/A' + transceiver_dom_info_dict['rx4power'] = 'N/A' + transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TXBias']['value'] + transceiver_dom_info_dict['tx2bias'] = 'N/A' + transceiver_dom_info_dict['tx3bias'] = 'N/A' + transceiver_dom_info_dict['tx4bias'] = 'N/A' + transceiver_dom_info_dict['tx1power'] = dom_channel_monitor_data['data']['TXPower']['value'] + transceiver_dom_info_dict['tx2power'] = 'N/A' + transceiver_dom_info_dict['tx3power'] = 'N/A' + transceiver_dom_info_dict['tx4power'] = 'N/A' + + return transceiver_dom_info_dict + + def get_transceiver_dom_threshold_info_dict(self, port_num): + transceiver_dom_threshold_info_dict = {} + dom_info_dict_keys = ['temphighalarm', 'temphighwarning', + 'templowalarm', 'templowwarning', + 'vcchighalarm', 'vcchighwarning', + 'vcclowalarm', 'vcclowwarning', + 'rxpowerhighalarm', 'rxpowerhighwarning', + 'rxpowerlowalarm', 'rxpowerlowwarning', + 'txpowerhighalarm', 'txpowerhighwarning', + 'txpowerlowalarm', 'txpowerlowwarning', + 'txbiashighalarm', 'txbiashighwarning', + 'txbiaslowalarm', 'txbiaslowwarning' + ] + transceiver_dom_threshold_info_dict = dict.fromkeys(dom_info_dict_keys, 'N/A') + + if port_num in self.qsfp_ports: + file_path = self._get_port_eeprom_path(port_num, self.IDENTITY_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + return None + + try: + sysfsfile_eeprom = io.open(file_path, mode="rb", buffering=0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8436Dom() + if sfpd_obj is None: + return transceiver_dom_threshold_info_dict + + # Dom Threshold data starts from offset 384 + # Revert offset back to 0 once data is retrieved + offset = 384 + dom_module_threshold_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, + (offset + QSFP_MODULE_THRESHOLD_OFFSET), + QSFP_MODULE_THRESHOLD_WIDTH) + if dom_module_threshold_raw is not None: + dom_module_threshold_data = sfpd_obj.parse_module_threshold_values(dom_module_threshold_raw, 0) + else: + return transceiver_dom_threshold_info_dict + + dom_channel_threshold_raw = self._read_eeprom_specific_bytes( + sysfsfile_eeprom, + (offset + QSFP_CHANNL_THRESHOLD_OFFSET), + QSFP_CHANNL_THRESHOLD_WIDTH) + if dom_channel_threshold_raw is not None: + dom_channel_threshold_data = sfpd_obj.parse_channel_threshold_values(dom_channel_threshold_raw, 0) + else: + return transceiver_dom_threshold_info_dict + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + # Threshold Data + transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VccHighAlarm']['value'] + transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VccHighWarning']['value'] + transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VccLowAlarm']['value'] + transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VccLowWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_channel_threshold_data['data']['RxPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_channel_threshold_data['data']['RxPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_channel_threshold_data['data']['RxPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_channel_threshold_data['data']['RxPowerLowWarning']['value'] + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_channel_threshold_data['data']['TxBiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_channel_threshold_data['data']['TxBiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_channel_threshold_data['data']['TxBiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_channel_threshold_data['data']['TxBiasLowWarning']['value'] + + else: + offset = 256 + file_path = self._get_port_eeprom_path(port_num, self.DOM_EEPROM_ADDR) + if not self._sfp_eeprom_present(file_path, 0): + return None + + try: + sysfsfile_eeprom = io.open(file_path,"rb",0) + except IOError: + print("Error: reading sysfs file %s" % file_path) + return None + + sfpd_obj = sff8472Dom(None,1) + if sfpd_obj is None: + return transceiver_dom_threshold_info_dict + + dom_module_threshold_raw = self._read_eeprom_specific_bytes(sysfsfile_eeprom, + (offset + SFP_MODULE_THRESHOLD_OFFSET), SFP_MODULE_THRESHOLD_WIDTH) + + if dom_module_threshold_raw is not None: + dom_module_threshold_data = sfpd_obj.parse_alarm_warning_threshold(dom_module_threshold_raw, 0) + else: + return transceiver_dom_threshold_info_dict + + try: + sysfsfile_eeprom.close() + except IOError: + print("Error: closing sysfs file %s" % file_path) + return None + + #Threshold Data + transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] + transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] + transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] + transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] + transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VoltageHighAlarm']['value'] + transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VoltageLowAlarm']['value'] + transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VoltageHighWarning']['value'] + transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VoltageLowWarning']['value'] + transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_module_threshold_data['data']['BiasHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_module_threshold_data['data']['BiasLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_module_threshold_data['data']['BiasHighWarning']['value'] + transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_module_threshold_data['data']['BiasLowWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_module_threshold_data['data']['TXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_module_threshold_data['data']['TXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_module_threshold_data['data']['TXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_module_threshold_data['data']['TXPowerLowWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_module_threshold_data['data']['RXPowerHighAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_module_threshold_data['data']['RXPowerLowAlarm']['value'] + transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_module_threshold_data['data']['RXPowerHighWarning']['value'] + transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RXPowerLowWarning']['value'] + + return transceiver_dom_threshold_info_dict